一、概述
1.1 HandlerExceptionResolver 的作用
HandlerExceptionResolver是Spring MVC的核心组件之一,用于处理控制器方法执行过程中抛出的异常。它可以将异常转换成合适的视图,或者将异常信息记录下来以便后续处理。
1.2 了解显示异常处理流程
在了解HandlerExceptionResolver之前,需要了解Spring MVC的异常处理流程。当控制器方法执行过程中抛出异常时,Spring MVC会按照以下顺序进行异常处理:
- 如果控制器方法定义了@ExceptionHandler注解,则会调用对应的异常处理方法进行处理。
- 如果控制器方法未定义@ExceptionHandler注解,则会将异常抛出到DispatcherServlet。
- DispatcherServlet会将异常交给HandlerExceptionResolver进行处理。
- 如果没有合适的HandlerExceptionResolver进行处理,DispatcherServlet会将异常交给Servlet容器进行处理。
二、常见ExceptionResolver实现类
2.1 SimpleMappingExceptionResolver
SimpleMappingExceptionResolver是一个基于异常类型和视图名称的异常解析器。它可以根据异常类型匹配对应的视图名称,并将异常信息传递给视图进行渲染。
public class SimpleMappingExceptionResolver extends AbstractHandlerExceptionResolver {
private Map<Class<? extends Throwable>, String> exceptionMappings;
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String viewName = findViewName(ex);
return getModelAndView(viewName, ex);
}
// ...
}
上述代码中,SimpleMappingExceptionResolver继承了AbstractHandlerExceptionResolver抽象类,并重写了doResolveException方法。doResolveException方法根据异常类型和视图名称进行匹配,并将异常信息传递给视图进行渲染并返回ModelAndView对象。
2.2 DefaultHandlerExceptionResolver
DefaultHandlerExceptionResolver是Spring MVC默认的异常处理器。它可以处理常见的异常类型,并将异常信息记录到日志中。
public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
if (ex instanceof HttpMediaTypeNotAcceptableException) {
response.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
return new ModelAndView();
}
// ...
}
// ...
}
上述代码中,DefaultHandlerExceptionResolver继承了AbstractHandlerExceptionResolver抽象类,并重写了doResolveException方法。doResolveException方法处理常见的异常类型,并将异常信息记录到日志中。
2.3 ResponseStatusExceptionResolver
ResponseStatusExceptionResolver是用于处理使用@ResponseStatus注解声明的异常的HandlerExceptionResolver实现类。它可以将注解中定义的状态码和原因短语设置到响应头中。
public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
if (responseStatus != null) {
applyResponseStatus(response, responseStatus);
return new ModelAndView();
}
// ...
}
// ...
}
上述代码中,ResponseStatusExceptionResolver继承了AbstractHandlerExceptionResolver抽象类,并重写了doResolveException方法。doResolveException方法根据@ResponseStatus注解中定义的状态码和原因短语设置响应头并返回空的ModelAndView对象。
三、自定义ExceptionResolver
3.1 实现HandlerExceptionResolver接口
要自定义HandlerExceptionResolver,需要实现HandlerExceptionResolver接口,并实现doResolveException方法。在doResolveException方法中,可以根据异常类型和需要的处理方式进行自定义处理。
3.2 注册到Spring配置中
自定义HandlerExceptionResolver需要注册到Spring配置中,可以使用
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Bean
public HandlerExceptionResolver customExceptionResolver() {
return new CustomExceptionResolver();
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.add(customExceptionResolver());
}
// ...
}
上述代码中,使用Java配置类来配置自定义HandlerExceptionResolver。首先使用@EnableWebMvc注解启用Spring MVC注解驱动,然后定义一个customExceptionResolver方法来返回自定义的HandlerExceptionResolver实现类。最后在configureHandlerExceptionResolvers方法中将自定义HandlerExceptionResolver添加到resolver中。
四、扩展
4.1 实现HandlerExceptionResolverComposite
如果需要扩展多个HandlerExceptionResolver,可以实现HandlerExceptionResolverComposite接口。HandlerExceptionResolverComposite接口可以将多个HandlerExceptionResolver组合起来,形成一个处理器链,按照顺序依次处理异常。
public class CustomExceptionResolverComposite implements HandlerExceptionResolverComposite {
private List<HandlerExceptionResolver> resolvers;
public CustomExceptionResolverComposite(List<HandlerExceptionResolver> resolvers) {
this.resolvers = resolvers;
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
resolvers.addAll(this.resolvers);
}
// ...
}
上述代码中,CustomExceptionResolverComposite实现了HandlerExceptionResolverComposite接口,并在extendHandlerExceptionResolvers方法中将传入的HandlerExceptionResolver添加到处理器链中。
4.2 使用自定义ExceptionResolver
可以在Spring MVC的配置中使用自定义HandlerExceptionResolver。除了在Java配置类中使用@Bean方法配置HandlerExceptionResolver外,还可以使用
<mvc:annotation-driven>
<mvc:exception-resolvers>
<bean class="com.example.CustomExceptionResolver1"/>
<bean class="com.example.CustomExceptionResolver2"/>
</mvc:exception-resolvers>
</mvc:annotation-driven>
上述代码中,使用
五、总结
HandlerExceptionResolver是Spring MVC的核心组件之一,用于处理控制器方法执行过程中抛出的异常。本文介绍了HandlerExceptionResolver的作用、常见实现类、自定义ExceptionResolver以及使用HandlerExceptionResolverComposite扩展实现。需要注意的是,不同的HandlerExceptionResolver可能会产生不同的结果,需要根据实际需求进行选择。
文章评论