目录
1.2、HandlerExceptionResolver组件
二、AbstractHandlerExceptionResolver类
三、DefaultHandlerExceptionResolver 类
四、SimpleMappingExceptionResolver类
4.2.1、SimpleMappingExceptionResolver概述
五、ResponseStatusExceptionResolver类
六、ExceptionHandlerExceptionResolver 类
6.2.2、doResolveHandlerMethodException方法
6.2.3、getExceptionHandlerMethod方法
6.2.4、getExceptionHandlerMethod方法
HandlerExceptionResolver干啥的
1.1、前言
在了解HandlerExceptionResolver相关组件作用之前,项目难免会有异常,不管是系统交互过程中的常见异常NullPointerException,还在业务自定义的异常处理,对于异常处理常规操作是进行try-catch 包裹 catch中进行异常处理操作。这样代码中充斥着大量的重复try-catch代码,且不符合我们要求,那么对于异常我们想要进行统一的处理,且提供友好的视图信息或者json格式对于这种场景springMVC(Spring 3.2 带来的新特性) 提供了HandlerExceptionResolver组件来帮我们解决这样的问题。
1.2、HandlerExceptionResolver组件
如上问题尤其是web项目,因为它一般直接面向用户,所以良好的异常处理就显得格外的重要。Spring MVC作为如此优秀的web层框架,自然考虑到了这一点,其提供了异常处理器HandlerExceptionResolver。HandlerExceptionResolver主要用于解析request请求进入Controller(Handler)对象处理过程中对于抛出异常的解析处理从上面描述中可以知道其处于springMVC范畴的组件统一异常处理过程中出现的异常和视图解析过程中的异常时无法处理的。
HandlerExceptionResolver 接口有一个抽象方法AbstractHandlerExceptionResolver主要有四大类 HandlerExceptionResolverComposite(包含多个不同HandlerExceptionResolver 排除)
- SimpleMappingExceptionResolver 该类通过配置Exception和viewName映射关系,解析异常的时候通过业务抛出的相关异常信息获取到对应的viewName(String)
- DefaultHandlerExceptionResolver 其提供了对Http特定异常的处理,主要是在response中设置相关的异常响应信息。
- ResponseStatusExceptionResolver 主要用来解析使用@ResponseStatus注解修饰的异常并对其进行处理
- ExceptionHandlerExceptionResolver 这个是我们开发场景中经常使用的异常解析组件
其和 @ExceptionHandler+@ControllerAdvice进行全局的异常处理配合使用进行。下面我们从示例和源码的角度来学习springMVC的九大组件之一的异常处理解析器组件HandlerExceptionResolver。
1.3、核心方法
ExceptionHandlerExceptionResolver只有一个核心方法resolveException,该方法主要作用处理对应请求Handler过程中产生的异常并创建对应的ModelView返回。
/**
* springMVC异常解析的核心方法
* @param request http请求信息
* @param response http响应信息
* @param handler 使用请求url映射的处理请求逻辑的Handler处理器
* @param ex 对应的需要解析的异常父类
* @return 异常解析完成返回的视图对象
*/
ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
其对应在springMVC调用的地方为DispatcherServlet的入口类:
org.springframework.web.servlet.DispatcherServlet#processDispatchResult()方法中的某个分支对应异常处理盗用其类processHandlerException()方法。
二、AbstractHandlerExceptionResolver类
AbstractHandlerExceptionResolver对接口进行了一个抽象,实现其中的通用逻辑,并暴露对应的doResolveException方法交由子类实现
2.1、resolveException方法
public ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
//先判断该异常处理类是否支持处理handler执行过程中产生的异常
if (shouldApplyTo(request, handler)) {
//设置response禁用缓存 使用preventResponseCaching(默认是false不经用缓存)
prepareResponse(ex, response);
//交由子类进行真实的异常处理
ModelAndView result = doResolveException(request, response, handler, ex);
if (result != null) {
//打印日志
if (logger.isDebugEnabled() && (this.warnLogger == null || !this.warnLogger.isWarnEnabled())) {
logger.debug("Resolved [" + ex + "]" + (result.isEmpty() ? "" : " to " + result));
}
// Explicitly configured warn logger in logException method.
logException(ex, request);
}
return result;
}
else {
return null;
}
}
抽象类中的实现了异常解析接口的核心方法,提供了一个通用的逻辑处理,1、比如是否支持处理handler对应的异常的shouldApplyTo方法,开发过程可以自定义的配置该异常处理器可以处理的异常(下面给出了源码),2、设置响应信息(这里禁用缓存)3、调用子类实现的doResolveException() 真正解析异常处理,抽象方法子类实现,4、自定义日志输出
其中对于doResolveException方法的分析我们会在后面根据不同的子类进行分别分析。这里按下不表。
2.2、shouldApplyTo方法
使用该方法判断是否支持处理Handler(请求参数) 产生的异常
//该方法使用两个参数来判断是否支持handler异常处理 分别是 mappedHandlers(包含支持handler异常处理的set集合)
//mappedHandlerClasses(包含Handler处理器对应类的class属性) 这两个属性可以在配置解析类的时候自定义设置
protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {
//判断mappedHandlers是否包含handler(true表示支持该handler的异常处理)
if (handler != null) {
if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) {
return true;
}
//判断mappedHandlerClasses是否包含handler对应类的class(true表示支持该handler的异常处理)
if (this.mappedHandlerClasses != null) {
for (Class<?> handlerClass : this.mappedHandlerClasses) {
if (handlerClass.isInstance(handler)) {
return true;
}
}
}
}
//如果两个属性不设置 则支持所有的异常处理
return (this.mappedHandlers == null && this.mappedHandlerClasses == null);
}
三、DefaultHandlerExceptionResolver 类
DefaultHandlerExceptionResolver 类实现了抽象类AbstractHandlerExceptionResolver的doResolveException方法主要负责处理一些Http请求常见错误,比如请求方法不支持,请求传参方式不支持等。
- HttpRequestMethodNotSupportedException http请求方法不支持异常
- HttpMediaTypeNotSupportedException http请求的Context-type类型不支持
- HttpMediaTypeNotAcceptableException http请求的Context-type类型不接受
- MissingPathVariableException url请求path参数丢失
- MissingServletRequestParameterException request中param参数丢失
- ServletRequestBindingException reuqest请求映射绑定到实体异常
- ConversionNotSupportedException 不支持转换异常
- TypeMismatchException 类型不匹配
- HttpMessageNotReadableException 信息无法获取
- HttpMessageNotWritableException 信息无法响应
- MethodArgumentNotValid