在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一, 也实现了异常信息的统一处理和维护 。
springmvc的异常处理思路
系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
Spring/SpringMVC常见的统一异常处方式:
1) 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver,处理器实现HandlerExceptionResolver 接口,全局异常处理器需要实现该接口
SimpleMappingExceptionResolver,就是通过简单的映射关系来决定由哪个视图,来处理当前的错误信息。SimpleMappingExceptionResolver提供通过异常类型exceptionMappings,来进行异常与视图之间的映射关系,提供在发生异常时,通过statusCodes来映射异常返回的视图名称和对应的HttpServletResponse的返回码。而且可以通过defaultErrorView和defaultErrorCode来指定默认值,defaultErrorView表示当没有在exceptionMappings里面找到对应的异常类型时,就返回defaultErrorView定义的视图,defaultErrorCode表示在发生异常时,当没有在视图与返回码的映射关系statusCodes里面找到对应的映射时,默认返回的返回码。
在使用SimpleMappingExceptionResolver时,当发生异常的时候,SimpleMappingExceptionResolver将会把当前的异常对象放到自身属性exceptionAttribute中,当没有指定exceptionAttribute时,exceptionAttribute就是用默认值exception
首先得在webApplicationContext.xml文件中配置该处理器:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--默认的异常处理页面-->
<property name="defaultErrorView" value="user/error"/> //错误页面的路径:如果配置modelView.addView("/WEB-INF/views"),就是相对路径
<!--异常处理页面用来获取异常信息的变量名,默认为exception-->
<property name="exceptionAttribute" value="ex"/>
<!--需要特殊处理的异常信息-->
<property name="exceptionMappings">
<props>
<prop key="com.smart.exception.CustomException">user/custom_error</prop>
</props>
</property> <property name="statusCodes"> <props> <prop key="number">500</prop> <prop key="null">503</prop> </props> </property>
</bean>
最重要的是要配置特殊处理的异常,自定义一个CustomException
package com.smart.exception;
/**
* 自定义异常
* **/
public class CustomException extends Exception{
private String message;
public CustomException(String message){
super(message);
this.message=message;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2) 实现Spring的异常处理接口HandlerExceptionResolver 自定义全局异常处理器
全局异常处理器处理思路
- 解析出异常类型
- 如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示
- 如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型
springmvc提供一个HandlerExceptionResolver接口,自定义全局异常处理器必须要实现这个接口
public class CustomExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView modelAndView = new ModelAndView();
if(ex instanceof CustomException){
CustomException exception=(CustomException)ex;
modelAndView.addObject("message",exception.getMessage());
modelAndView.setViewName("user/custom_error");
return modelAndView;
}else{
modelAndView.addObject("message",ex.getMessage());
modelAndView.setViewName("user/error");
return modelAndView;
}
}
}
在springmvc.xml中配置这个自定义的异常处理器:
<!-- 自定义的全局异常处理器
只要实现HandlerExceptionResolver接口就是全局异常处理器-->
<bean class="com.smart.CustomExceptionResolver"></bean>
3) 使用@ExceptionHandler注解实现异常处理
处理局部异常(Controller内)
@ExceptionHandler
public ModelAndView exceptionHandler(Exception ex){
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
System.out.println("in testExceptionHandler");
return mv;
}
@RequestMapping("/error")
public String error(){
int i = 5/0;
return "hello";
}
4) 定义一个类并配上注解@ControllerAdvice。然后再该类中定义处理异常的方法并使用注解@ExceptionHandler
处理全局异常(所有Controller)
//全局异常处理,捕获所有Controller中抛出的异常 @ControllerAdvice
public class testControllerAdvice { //自定义异常
@ExceptionHandler(CustomException.class)
public ModelAndView exceptionHandler(Exception ex){
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
System.out.println("in testControllerAdvice");
return mv;
}
@ExceptionHandler(Exception.class) @ResponseBody public Object exceptionHandler(Exception e){ ,,,, }
}
参考:
https://blog.csdn.net/eson_15/article/details/51731567
|