在开发中,会产生很多异常。我们通常采取如下方式统一处理异常
Spring MVC异常处理 - 图1
开发中会有很多控制器,如果每一个控制器层都处理异常就比较麻烦,我们可以统一处理异常。
我们先看默认不处理异常会发生什么?

  1. @RequestMapping("test1")
  2. public void test1(){
  3. throw new RuntimeException("这里遇到了问题哈哈哈");
  4. }

image.png
这种提示是很不友善的、页面也很丑。我们通常是自己写异常处理页面,当发生异常后转发到自定义的异常页面。
SpringMVC提供了很多处理异常的方式。

使用SimpleMappingExceptionResolver

�使用springMVC自带的异常处理类,只需在把SimpleMappingExceptionResolver放在IOC容器中即可

  1. <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  2. <property name="exceptionMappings">
  3. <props>
  4. <!-- key为异常类型,值为要跳转到的页面-->
  5. <prop key="java.lang.RuntimeException">/WEB-INF/error/runtimeException.jsp</prop>
  6. <prop key="java.io.IOException">/WEB-INF/xxx.jsp</prop>
  7. </props>
  8. </property>
  9. <!-- 异常对象的属性名称,可以在JSP中通过ex获取异常信息-->
  10. <property name="exceptionAttribute" value="ex"/>
  11. <!-- 其他异常统一跳转的页面-->
  12. <property name="defaultErrorView" value="/WEB-INF/error/defaultError.jsp" />
  13. </bean>

自定义异常处理类,实现HandlerExceptionResolver接口

  1. @Component
  2. public class MyExceptionResolver implements HandlerExceptionResolver {
  3. @Override
  4. public ModelAndView resolveException(HttpServletRequest httpServletRequest,
  5. HttpServletResponse httpServletResponse,
  6. Object o,
  7. Exception e) {
  8. // 可以哪到异常的具体信息,比如哪个控制器的哪个方法抛出的异常
  9. // HandlerMethod handlerMethod = (HandlerMethod) o;
  10. // handlerMethod.getMethod();
  11. ModelAndView modelAndView = new ModelAndView("/WEB-INF/error/defaultError.jsp");
  12. modelAndView.addObject("ex",e);
  13. modelAndView.addObject("name","lifufa");
  14. return modelAndView;
  15. }
  16. }

这种方式比较灵活,可以根据异常的具体类型进行处理,也可以存放很多参数带到异常页面。

使用注解@ExceptionHandler

这种方式比较有局限性,只能处理一个Controller里面的异常,不常用。
所在的控制器里面的所有的异常统一处理

  1. @ExceptionHandler
  2. public ModelAndView error(Exception e){
  3. ModelAndView modelAndView = new ModelAndView("/WEB-INF/error/defaultError.jsp");
  4. modelAndView.addObject("ex",e);
  5. modelAndView.addObject("name","lifufa");
  6. return modelAndView;
  7. }

也可以指定处理的异常类型

  1. @ExceptionHandler({RuntimeException.class, IOException.class})
  2. public ModelAndView error1(Exception e){
  3. ModelAndView modelAndView = new ModelAndView("/WEB-INF/error/defaultError.jsp");
  4. modelAndView.addObject("ex",e);
  5. modelAndView.addObject("name","lff");
  6. return modelAndView;
  7. }

使用@ControllerAdvice 和 @ExceptionHandler配合使用的方式

  1. //@ControllerAdvice(basePackages = "com.lff") //表示这个包下面的所有异常都可以处理
  2. //@ControllerAdvice(annotations = Controller.class) //表示只要带有Controller注解抛出的异常都处理
  3. @ControllerAdvice
  4. public class MyExceptionResolverAnn {
  5. @ExceptionHandler
  6. public ModelAndView error(Exception e){
  7. ModelAndView modelAndView = new ModelAndView("/WEB-INF/error/defaultError.jsp");
  8. modelAndView.addObject("ex",e);
  9. modelAndView.addObject("name","lifufa");
  10. return modelAndView;
  11. }
  12. // @ExceptionHandler({RuntimeException.class, IOException.class})
  13. // public ModelAndView error1(Exception e){
  14. // ModelAndView modelAndView = new ModelAndView("/WEB-INF/error/defaultError.jsp");
  15. // modelAndView.addObject("ex",e);
  16. // modelAndView.addObject("name","lff");
  17. // return modelAndView;
  18. // }
  19. }

这种方式也比较灵活常用。