springmvc的特性 (spring mvc解析参数)

spring-webmvc版本5.2.5,springboot版本2.2.6

一.HandlerExceptionResolver是什么?

处理异常的工具类,简单来说,传过来一个异常,有能力处理,直接返回处理后的结果;不能处理,返回null

二.HandlerExceptionResolver怎么来的?

1.DispatcherServlet调用init()初始化方法时,从spring ioc容器中取出所有HandlerExceptionResolver类型的对象,并排序

2.ioc怎么有HandlerExceptionResolver?

来源一:@EnableAutoConfiguration-->>autoconfigure项目,默认自动装配文件META-INF\spring.factories-->>ErrorMvcAutoConfiguration,自动装配类往spring ioc容器中注册DefaultErrorAttributes errorAttributes对象,为了能排在最前面,优先级设置成了最高;errorAttributes的目的很简单,就是将异常信息request.setAttribute("DefaultErrorAttributes.ERROR", ex);只放进request参数中,不处理(异常存在request中,方便后面取值),然后返回null

来源二:@EnableAutoConfiguration-->>autoconfigure项目,默认自动装配文件META-INF\spring.factories-->>WebMvcAutoConfiguration-->>EnableWebMvcConfiguration类,实例HandlerExceptionResolverComposite对象;异常处理器类型的一个组合类,里面默认设置了三个异常处理解析器(ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver),既然是组合,为什么不把errorAttributes也组合进去呢?

ExceptionHandlerExceptionResolver的作用:解析单独有@ExceptionHandler注解的方法;解析有@ControllerAdvice注解的类,并找到带有@ExceptionHandler注解的方法;简单来说,就是把关心的方法和异常类型关联起来,存入map中,如果有异常出现,根据异常类型,找到对应的method,反射执行method对象

springmvc拦截异常,springmvc优缺点

ExceptionHandlerExceptionResolver结构

ResponseStatusExceptionResolver的作用:自定义一个异常子类,类上面加有@ResponseStatus注解,如

@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户名和密码不匹配")

public class UserNameNoMatchPassword extends RuntimeException {}

在抛出异常UserNameNoMatchPassword的时候,ResponseStatusExceptionResolver会提取异常类中是否有注解,有的话,将注解对应的reason="用户名和密码不匹配"值拼到response中返回

DefaultHandlerExceptionResolver的作用:对一些常见的异常解析,如果出现HttpRequestMethodNotSupportedException异常,返回拼接上405;如果出现NoHandlerFoundException,拼接上404(找不到url对应处理器);如果出现MissingPathVariableException,返回拼接上500.......有没有想明白,正是靠这个类来和http返回码接轨

来源三:自定义实现HandlerExceptionResolver接口的类,然后托管给spring ioc容器;一般情况下,不太需要自定义,除非项目中定义了一些新的异常类,需要新异常解析器来处理这些新的异常类

三.HandlerExceptionResolver的使用

springmvc拦截异常,springmvc优缺点

异常解析器集合

循环列表中的HandlerExceptionResolver对象,执行接口方法resolveException,只要不返回null,说明当前HandlerExceptionResolver对象可以处理此异常,结束循环返回,否则交给下一个解析器继续处理