前言
在日常开发中,自己写的代码中总是有各种各样的异常,不管是受查异常还是非受查异常。对于异常我们可以在每个方法里面去去捕获异常,然后跳转到对应的异常页面中,但是这样的话就会导致代码侵入比较严重,耦合性差,同时在每个方法里面都进行异常捕获处理,这样效率也比较低。
那么有没有一种好的方式来解决这个问题呢,其实spring已经帮我们处理好这个问题了,具体的处理流程请看下图。
从上图中可以看出来,Controller,Service,Dao中的异常是都是被springmvc的前端控制器DispatchServlet来统一进行处理,这样就不用在每个模块都进行异常处理了。
那么springmvc又是通过什么方式来对异常进行统一处理的呢??
通过SimpleMappingExceptionResolver进行处理
SimpleMappingExceptionResolver是springmvc自带的一个统一处理异常的类,可以从源码中可以看出SimpleMappingExceptionResolver是实现了springmvc的异常统一处理接口HandlerExceptionResolver
继承自AbstractHandlerExceptionResolver
然后又实现了HandlerExceptionResolver
如果我们要通过上述方法来实现异常的统一处理,需要在springmvc的配置文件中配置个bean,具体代码如下
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Throwable">/error/error</prop>
//这里可以匹配自己定义的自定义异常
<prop key="com.aiqinhai.common.MyselfException">/error/myError</prop>
</props>
</property>
</bean>
异常测试类
/**
*
* @author 爱琴孩
*测试异常处理
*/
@Controller
@RequestMapping("/testController")
public class TestController {
@RequestMapping("/test")
public String test() throws MyselfException{
System.out.println("进入到这个方法里面!");
try {
int i=3/0;
} catch (Exception e) {
// TODO: handle exception
throw new MyselfException("被除数不能为0");
}
return "upload";
}
}
测试结果如下
通过增强@ControllerAdvice来进行异常处理
自己定义一个增加Controller,具体代码如下
/**
*
* @author 爱琴孩
*定义增强Controller来统一处理异常
*/
@ControllerAdvice
public class ExceptionResolveController {
@ExceptionHandler(value=MyselfException.class)
public String resovleException(){
System.out.println("所有的异常都是在这里进行处理");
return "error/404";
}
}
上面的@ControllerAdvice是运行时类注解,被注解的类可以被容器扫描到
当然还有要在springmvc的配置文件中配置,能扫描@ControllerAdvice
<context:component-scan base-package="com.aiqinhai" use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
其实上面的还是要靠增强Controller中的@ExceptionHandler注解,这个注解才是解决异常的关键,当然,我们可以不用@ControllerAdvice,在一个基础类中定义一个方法,然后加上@ExceptionHandler注解,后面我们新增的业务Controller只需要继承这个基础类就可以了。
在web.xml中配置异常页面
在web.xml中加入下面这些代码就ok了,他就会根据异常的状态吗或者异常的类型来映射对应的异常页面
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/views/error/error.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/error/error.jsp</location>
</error-page>
总结
上面的几种方式,各有优势,能够获取简单的异常信息,但是对于异常信息之外的消息获取就不是很方便了,对于SimpleMappingExceptionResolver,是springmvc中自带的异常处理类,当然我们也可以自己实现HandlerExceptionResolver接口,来自定义自己的全局异常处理器。