前言:为什么要统一异常处理?经常在项目中需要统一处理异常,将异常封装转给前端。也有时需要在项目中统一处理异常后,记录异常日志,做一下统一处理。
Springmvc 异常统一处理的方式有三种。
一、使用 @ExceptionHandler 注解
这种方式比较独立,如果 ctrl 层的异常处理只有自己这个 ctrl 层会这样处理,就可以采用这种方式,因为这个注解的方法必须和 ctrl 层需要处理异常的方法在同一个 controller 里。
@Controller
@RequestMapping("/demoCtrl")
public class DemoCtrl {
@RequestMapping("/testException")
public String testException() {
throw new RuntimeException();
}
@ExceptionHandler(RuntimeException.class)
public void dealException(){
System.out.println("hei, throw new Exception");
}
}
二、使用 @ControllerAdvice+ @ ExceptionHandler 注解(全局)
有了 @ControllerAdvice 就不需要限制在同一个 controller 中了。这种方式适合通用的 ctrl 层异常处理,可以实现全局的 ctrl 层异常捕获处理。
经测试,如果方法一和方法二的处理异常同时存在且异常类型一直,则会进入方法一的异常。
新建一个统一处理异常的类即可。请确保此WebExceptionHandle 类能被扫描到并装载进 Spring 容器中。
@ControllerAdvice
public class WebExceptionHandle {
@ExceptionHandler(RuntimeException.class)
public void dealException(){
System.out.println("hei, throw new Exception");
}
}
三、实现 HandlerExceptionResolver 接口(全局)
HandlerExceptionResolver接口中定义了一个resolveException方法,用于处理Controller中的异常。Exception ex参数即Controller抛出的异常。返回值类型是ModelAndView,可以通过这个返回值来设置异常时显示的页面。
写一个统一处理异常的类,实现 HandlerExceptionResolver 接口即可。
最后,当然需要将自己的HandlerExceptionResolver实现类配置到Spring配置文件中,或者加上@Component注解。
@Component
public class ExtHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
// 视图显示专门的错误页
ModelAndView modelAndView = new ModelAndView("yule/demo/demoScroll");
return modelAndView;
}
}
相关问题
HandlerExceptionResolver和web.xml中配置的error-page会有冲突吗?
web.xml中配置error-page同样是配置出现错误时显示的页面:
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
如果resolveException返回了ModelAndView,会优先根据返回值中的页面来显示。不过,resolveException可以返回null,此时则展示web.xml中的error-page的500状态码配置的页面。
当web.xml中有相应的error-page配置,则可以在实现resolveException方法时返回null。
API文档中对返回值的解释:
return a corresponding ModelAndView to forward to, or null for default processing.