Spring系列(七) Spring MVC 异常处理 (4)

从processDispatchResult方法中可以看到, 如果参数exception不为null, 则会处理异常, 对于ModelAndViewDefiningException类型的异常单独处理, 对于其他类型的异常, 转交给processHandlerException方法处理, 这个方法就是异常处理逻辑的核心.

@Nullable protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception { // Success and error responses may use different content types request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); // 使用注册的Resolver处理 ModelAndView exMv = null; if (this.handlerExceptionResolvers != null) { for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) { exMv = resolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } } } if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { String defaultViewName = getDefaultViewName(request); if (defaultViewName != null) { exMv.setViewName(defaultViewName); } } if (logger.isTraceEnabled()) { logger.trace("Using resolved error view: " + exMv, ex); } if (logger.isDebugEnabled()) { logger.debug("Using resolved error view: " + exMv); } WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv; } throw ex; }

从上面代码可以看到, this.handlerExceptionResolvers就是在程序启动时初始化注册的, spring通过遍历Resolver列表的方式处理异常, 如果返回结果不为null, 说明处理成功, 就跳出循环.

总结

Spring的异常解析器实现全部继承自接口ResponseStatusExceptionResolver, 上面我们详细了解了该接口在Spring中的几种实现, 比如处理预定义异常的DefaultHandlerExceptionResolver, 可以映射异常到状态码的ResponseStatusExceptionResolver, 还有功能更为强大的ExceptionHandlerExceptionResolver. 同时也简单了解了其使用方式,使用@ExceptionHandler来将方法标记为异常处理器, 结合@ControllerAdvice处理全局异常.

最后我们探究了异常处理器的加载和处理方式, 我们知道了其通过 DispatcherServlet 的初始化方法initHandlerMappings完成加载器列表的注册初始化, 并且在具体处理请求的doDispatch中检测异常, 最终processDispatchResult方法委托给processHandlerException, 该方法循环注册的异常处理器列表完成处理过程.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspsxg.html