首页 > 代码库 > 【Spring】SpringMVC之异常处理
【Spring】SpringMVC之异常处理
java中的异常分为两类,一种是运行时异常,一种是非运行时异常。在JavaSE中,运行时异常都是通过try{}catch{}捕获的,这种只能捕获显示的异常,通常项目上抛出的异常都是不可预见。那么我们能够有什么方法能够解决这种问题吗?当然有,SpringMVC中的异常处理机制就很好的做到了这一点。
SpringMVC中的异常处理一共有3种方式
- (1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
- (2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
- (3)使用@ExceptionHandler注解实现异常处理。
(1)使用Spring MVC提供的SimpleMappingExceptionResolver
直接将SimpleMappingExceptionResolver
类配置到SpringMVC配置文件中
<!-- 只是对全局的Controller有效果 所有的被RequestMapping注解所添加的方法中的异常才有效果 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- key: 异常的类全称 value: ModelAndView中的viewName 表示当key指定的异常产生时 , 则请求转发至 value指向的视图 --> <prop key="java.lang.Exception">errorPage</prop> </props> </property> </bean>
从配置文件上可以看出,如果发生了异常就跳转到名为errorPage的视图上。
完整的applicationContext.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="cn"></context:component-scan> <!-- 开启mvc注解扫描 --> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 只是对全局的Controller有效果 所有的被RequestMapping注解所添加的方法中的异常才有效果 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- key: 异常的类全称 value: ModelAndView中的viewName 表示当key指定的异常产生时 , 则请求转发至 value指向的视图 --> <prop key="java.lang.Exception">errorPage</prop> </props> </property> </bean> </beans>
使用这种方式的异常处理就是简单,但是问题显而易见,就是发生了异常自动就跳转到错误页面,那么这不利于后台对错误日志的收集。
(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器
使用方式如下:
@Componentpublic class MyException implements HandlerExceptionResolver { @Override public ModelAndView resolveException(参数...) { //操作... }}
在自定义异常处理器中,我们就可以很方便对异常信息进行各种操作操作,下面是一个能收集错误信息的自定义异常处理器:
SpringMVC的配置文件中需要负责打开扫描:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"> <!-- 开启注解扫描 --> <context:component-scan base-package="cn"></context:component-scan> <!-- 开启mvc注解扫描 --> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
自定义的异常类:
package cn.shop.exception;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.ModelAndView;import cn.shop.util.ExceptionUtil;/** * 用来在全局 处理Controller异常 */@Componentpublic class SpringMVCException implements HandlerExceptionResolver { /** * 如果这个类的对象, 存在于容器中, 则当前的项目中, 所有的Controller 出现的异常, 都会到这个方法中 * * 参数1. 请求对象 * 参数2. 响应对象 * 参数3. 出现异常时的 Method对象 * 参数4. 出现异常时的异常信息 * * 返回值, 会被ViewResolver解析 */ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object method,Exception e) { System.out.println("出现异常的方法:"+method.toString()); //request.getQueryString(): 获取get请求时的参数列表 String paras = request.getQueryString(); System.out.println("出现了异常, 出现异常时的请求参数:"+paras); System.out.println("--------------------------------------"); System.out.println("---------- 异常信息如下 ---------"); System.out.println("--------------------------------------"); e.printStackTrace(); //存储到异常日志 ExceptionUtil.toException(e); //跳转 return new ModelAndView( "error"); }}
存储异常的工具类:
package cn.shop.util;import java.io.File;import java.io.FileOutputStream;import java.io.PrintWriter;import java.text.SimpleDateFormat;import java.util.Date;/** * 用来收集异常日志 * * JavaEE web阶段 * * 当产生异常时, 应把异常收集起来 , * * 存储到 * 本地文件 * 网络存储 * 短信发送 * 邮件 */public class ExceptionUtil { /** * * 存储: * 在存储的目录下 ,按照每天的日期创建单独文件夹 * * 每天的文件夹中, 异常日志存储的文件, 一个异常一个文件, 文件名称按照时-分-秒-毫秒的格式存储 * * * @param e 要存储的异常信息 * @param exceptionPath 要存储的位置: 是一个文件夹, 文件夹可以不存在 * @throws Exception */ public static void toException(Exception e,File exceptionPath) throws Exception{ if(!exceptionPath.exists()){ //创建文件夹 exceptionPath.mkdirs(); } Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String day = sdf.format(date); //创建每天的异常文件夹 File dayDir = new File(exceptionPath, day); if(!dayDir.exists()) dayDir.mkdirs(); //创建本次异常存储的文件 SimpleDateFormat sdf2 = new SimpleDateFormat("HH-mm-ss-sss"); String fileName = sdf2.format(date); File file = new File(dayDir, fileName+".txt"); //创建一个字符打印流 , 指向创建的这个文件 PrintWriter pw = new PrintWriter(new FileOutputStream(file)); //将异常信息输出至这个文件 e.printStackTrace(pw); pw.close(); } /** * * @param e 要存储的异常信息 , 存储的位置 ,在F://log文件夹中 */ public static void toException(Exception e){ try { toException(e,new File("F://log")); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }
(3)@ExceptionHandler注解实现异常处理
package cn.xdl.controller;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class UserController { @RequestMapping("/login.do") public String UserrLogin(String name,String password){ //从数据库进行数据对比... //将结果值返回 return "loginResult"; } /** * 当前这个Controller类 ,被RequestMapping所注解的方法 如果出现了异常 ,则自动寻找当前类中是否存在被@ExceptionHandler注解的方法 , 如果存在, 则执行 * * 这个方法的写法, 与使用直接方式的Controller基本一致 * 它的参数列表中, 可以根据需求选择如下参数: * HttpSession / HttpServletRequest /HttpServletResponse / Exception */ @ExceptionHandler public String hahaha(Exception e,HttpServletRequest request){ System.out.println("请求时的参数:"+request.getQueryString()); System.out.println("---------------------------------"); System.out.println("----------- 请看异常信息 -----------"); System.out.println("---------------------------------"); e.printStackTrace(); return "error"; }}
上面这三种方式,各不影响,如果使用了多种方式的话,那么以离异常近的处理机制为准(就近原则)。
参考文章:
Java中自定义异常
【Spring】SpringMVC之异常处理
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。