学习笔记之SpringMVC中的异常处理篇
DispatcherServlet 默认装配的 HandlerExceptionResolver :
当没有使用 <mvc:annotation-driven/> 配置时默认有三个异常解析器:
1.AnnotatonMethodHandlerExceptionResolver(在Spring3.2以后该方法以及被舍弃过时了)
2.ResponseStatusExceptionResolver
3.DefaultHandlerExceptionResolver
使用 <mvc:annotation-driven/> 配置时有三个异常解析器:
1.ExceptionHandlerExceptionResolver
2.ResponseStatusExceptionResolver
3.DefaultHandlerExceptionResolver
其中除了第一个以外,其余两个是一样的。由于一般在项目都会配置 <mvc:annotation-driven/> ,所以这里这说配置了该注解的情况。
各异常解析器的作用
1.ExceptionHandlerExceptionResolver主要处理 Handler 中用@ExceptionHandler 注解定义的方法。
(1). 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象
(2). @ExceptionHandler 方法的入参中不能传入Map, 若希望把异常信息传到页面上, 需要使用ModelAndView作为返回值
- 因为这里在处理(解析)异常(执行doResolverException()方法)的时候,
发生异常时,异常解析器会返回一个ModelAndView对象(return getModelAndView(viewName, ex, request)),通过mv.addObject(this.exceptionAttribute, ex)把异常ex放入ModelAndView对象中去进行返回 ,因此可以用来传递异常信息到前端页面中 ,这里的exceptionAttribute默认为类名第一个字母小写(即exception),也可以在SpringMVC的配置文件中进行配置,如<propertyname=“exceptionAttribute” value=“ex”></property>,此时在页面中显示异常信息则用ex为名字。
(3). @ExceptionHandler 标记的方法有优先级的问题.
- 处理异常会按一定的优先级进行找不同的处理方法,顺序是按继承关系最浅的方式寻找。例如当出现ArithmeticException(算数异常)时,如果同时有两个方法标记了@ExceptionHandler注解,比如分别是@ExceptionHandler({ArithmeticException.class})和@ExceptionHandler({RuntimeException.class})时,会优先选择标记了@ExceptionHandler({ArithmeticException.class})的方法来处理异常,如果没有这个方法才会优先使用@ExceptionHandler({RuntimeException.class})标记的方法。
(4). @ControllerAdvice: 如果在当前Handler中找不到 @ExceptionHandler 标记的方法来处理异常, 则将去 @ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常
2.ResponseStatusExceptionResolver
在异常及异常父类中找到 @ResponseStatus 注解,然后使用这个注解的属性进行处理。
- @ResponseStatus 标记异常方法这里目标方法被正确的执行了,但是在页面上显示的却是 @ResponseStatus 注解标识的reason以及响应码(404等), 而在异常类(这里的UserNameNotMatchPasswordException)上标记的 @ResponseStatus 则只有 在出现异常的情况下才会显示异常类所定制的reason以及响应码(404等)。这里是通过该注解对异常信息进行了定制,即不管目标方法执行成功与否,都会报404错误。
- 也可以通过来标记一个类,来定制一个属于自己的异常类。
3.DefaultHandlerExceptionResolver
- DefaultHandlerExceptionResolver 异常解析器对Spring的一些特殊的异常进行处理, 比如NoSuchRequestHandlingMethodException(没有这种请求处理方式) 。或者HttpRequestMethodNotSupportedException(请求方式不支持)等等;这里用 DefaultHandlerExceptionResolver 来处理HttpRequestmethodNotSupportedException异常,方法:用超链接发送一个GET请求,而目标方法只能接受POST请求
执行结果:
4.此外,还有一个SimpleMappingExceptionResolver:
- SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常,通过数组下标越界来产生异常,然后通过SimpleMappingExceptionResolver的,异常解析器来使得发生异常时能够映射到错误页面。
由于这里会产生数组越界的异常,因此配置如下:
通过这个配置,可以在发生错误时,能够直接映射到error这个页面中去。还能够在error这个页面对错误进行显示,默认为异常的第一个字母小写即${requestScope.exception},也可以通过<property name=“exceptionAttribute” value=“ex”></property>来修改异常信息的名字。
参考:尚硅谷_佟刚老师的SpringMVC视频
链接:https://www.bilibili.com/video/BV1mW411M7YA