用于解析请求处理过程中出现的异常;
主要功能:给ModelAndView设置内容、设置response相关的属性;
子类:AbstractHandlerExceptionResolver
AbstractHandlerExceptionResolver:
- 1、实现类Order,有先后顺序;
- 2、其他HandlerExceptionResolver的父类,定义了通用的解析流程,使用了模板模式;
- 3、resolveException方法;
①流程:
shouldApplyTo判断当前ExceptionResolver是否可以处理处理器抛出的异常;
prepareResponse设置response;
logException打印日志;
调用doResolveException解析异常,此方法是模板方法,由子类实现;
- 4、shouldApplyTo方法:
①检查mapperHandlers和mapperHandlerClasses属性是否能处理当前异常,两者都为空,可以处理所有的异常;
- 5、prepareResponse方法:
①首先检查preventResponseCaching是否设置禁用缓存属性,默认为false,可以使用缓存;
②如果禁用了,则在header中加入Cache-Control为no-store;
- 6、doResolveException方法:
模板方法,由子类实现;
- 7、logException方法:
打印警告日志;
ExceptionHandlerExceptionResolver:
处理@ExceptionHandler注解标记的方法
- 1、继承AbstractHandlerMethodExceptionResolver;
- 2、实现ApplicationContextAware,可以根据setApplicationContext获取ApplicationContext;
- 3、实现InitializingBean,afterProperties方法用来初始化argumentResolvers和returnValueHandlers,初始化exceptionHandlerAdviceCache以及responseBodyAdvice;
①argumentResolver包含:
SessionAttributeMethodArgumentResolver、
RequestAttributeMethodArgumentResolver、
ServletRequestArgumentResolver、
ServletResponseArgumentResolver、
RedirectAttributesArgumentResolver、
ModelMethodProcessor、
自定义的HandlerMethodArgumentResolver;
②returnValueHandlers包含:
ModelAndViewMethodReturnValueHandler、
ModelMethodProcessor、
ViewMethodReturnValueHandler、
HttpEntityMethodProcessor、
ModelAttributeMethodProcessor、
RequestResponseBodyMethodProcessor、
ViewNameMethodReturnValueHandler、
MapMethodProcessor、
自定义的HandlerMethodReturnValueHandler、
ModelAttributeMethodProcessor
- 4、doResolveHandlerMethodException
DefaultHandlerExceptionResolver
- 1、继承AbstractHandlerExceptionResolver(实现了Order),所以是有顺序的;
- 2、重写了resolveException方法:根据异常的不同调用不同的方法处理,返回ModelAndView;
<1>HttpRequestMethodNotSupportedException:
由handleHttpRequestMethodNotSupported方法处理,将状态码405以及错误信息设置到response中,并返回一个空的ModelAndView;
<2>HttpMediaTypeNotSupportedException:
由handleHttpMediaTypeNotSupported方法处理,设置状态码415,如果supportedMediaType不为空,则设置header中的Accept参数,返回空的ModelAndView;
<3>HttpMediaTypeNotAcceptableException:
由handleHttpMediaTypeNotAcceptable方法处理,设置状态码416,返回空的ModelAndView;
<4>MissingPathVariableException:
由handleMissingPathVariable处理,设置状态码500及错误信息,返回空的ModelAndView;
<5>MissingServletRequestParameterException:
由handleMissingServletRequestParameter处理,设置状态码为400及错误信息,返回空的ModelAndView;
<6>ServletRequestBindingException:
由handleServletRequestBindingException处理,设置状态码400及错误信息,返回空的ModelAndView;
<7>ConversionNotSupportedException:
由handleConversionNotSupported处理,设置response状态码500,设置request的属性javax.servlet.error.exception的值为Exception,返回空的ModelAndView;
<8>TypeMismatchException:
由handleTypeMismatch处理,设置状态码400及错误信息,返回空的ModelAndView;
<9>HttpMessageNotReadableException:
由handleHttpMessageNotReadable处理,设置状态码400,返回空的ModelAndView;
<10>HttpMessageNotWritableException:
由handleHttpMessageNotWritable处理,设置状态码500,设置request的属性javax.servlet.error.exception为Exception,返回空的ModelAndView;
<11>MethodArgumentNotValidException:
由handleMethodArgumentNotValidException处理,设置状态码400,返回空的ModelAndView;
<12>MissingServletRequestPartException:
由handleMissingServletRequestPartException处理,设置状态码400及错误信息,返回空的ModelAndView;
<13>BindException:
由handleBindException处理,设置状态码400,返回空的ModelAndView;
<14>NoHandlerFoundException:
由handleNoHandlerFoundException处理,设置状态码404,返回空的ModelAndView;
<15>AsyncRequestTimeoutException:
由handleAsyncRequestTimeoutException处理,根据response.isCommited为false时,设置状态码503,返回空的ModelAndView;
ResponseStatusExceptionResolve:
- 1、实现MessageSourceAware,获取MessageSource;
- 2、继承AbstractHandlerExceptionResolver,意味着是有先后顺序的;
- 3、用来解析使用了@ResponseStatus注解的异常;
- 4、doResolveException实现过程:
<1>如果异常时ResponseStatusException,则设置状态码为statusCode及异常信息,返回空的ModelAndView;
<2>通过AnnotatedElementUtils获得是否被@ResponseStatusException注解,设置状态码为@ResponseStatusException中设置的code,异常信息为reason,返回空的ModelAndView;
<3>否则获取Exception.getCause(),并递归调用当前类的doResolveException
SimpleMappingExceptionResolver:
- 1、需要配置异常类和view的对应关系才能使用;
- 2、doResolveException方法:
<1>通过determineViewName方法获取到viewName,过程如下:
①如果Class<?>[] excludedExceptions中包含了该异常,则不处理该异常;
②从Properties exceptionMappings属性中获取viewName;
③若viewName为null,则获取默认的defaulErrorView并返回;
<2>通过determineStatusCode方法通过viewName从属性Map<String, Integer> statusCodes中获取,如果获取不到,则使用默认的defaultStatusCode;
<3>如果匹配到的statusCode不为null,设置状态码为statusCode,并设置request的属性javax.servlet.error.status_code为statusCode;
<4>返回viewName的ModelAndView,并设置exception为Exception;