SpringMvc之HandlerExceptionResolver
2017-08-14 21:28
393 查看
故事先从SpringMvc的dispatcherServlert开始
当发生异常后执行processDispatchResult
如果存在异常且为非ModelAndViewDefiningException类异常,则执行processHandlerException
1.执行onRefresh时调用initStrategies
protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }
2.执行initStrategies
protected void initStrategies(ApplicationContext context) { this.initMultipartResolver(context); this.initLocaleResolver(context); this.initThemeResolver(context); this.initHandlerMappings(context); this.initHandlerAdapters(context); this.initHandlerExceptionResolvers(context); this.initRequestToViewNameTranslator(context); this.initViewResolvers(context); this.initFlashMapManager(context); }
3.初始化异常处理器
private void initHandlerExceptionResolvers(ApplicationContext context) { this.handlerExceptionResolvers = null; if(this.detectAllHandlerExceptionResolvers) { Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); if(!matchingBeans.isEmpty()) { this.handlerExceptionResolvers = new ArrayList(matchingBeans.values()); OrderComparator.sort(this.handlerExceptionResolvers); } } else { try { HandlerExceptionResolver her = (HandlerExceptionResolver)context.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); this.handlerExceptionResolvers = Collections.singletonList(her); } catch (NoSuchBeanDefinitionException var3) { ; } } if(this.handlerExceptionResolvers == null) { this.handlerExceptionResolvers = this.getDefaultStrategies(context, HandlerExceptionResolver.class); if(this.logger.isDebugEnabled()) { this.logger.debug("No HandlerExceptionResolvers found in servlet '" + this.getServletName() + "': using default"); } } }
Controller是如何将异常交给HandlerExceptionResolver处理的
1.springMvc的核心,doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = this.checkMultipart(request); multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest); if(mappedHandler == null || mappedHandler.getHandler() == null) { this.noHandlerFound(processedRequest, response); return; } HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); String method = request.getMethod(); boolean isGet = "GET".equals(method); if(isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if(this.logger.isDebugEnabled()) { this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) { return; } } if(!mappedHandler.applyPreHandle(processedRequest, response)) { return; } mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if(asyncManager.isConcurrentHandlingStarted()) { return; } this.applyDefaultViewName(request, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception var19) { dispatchException = var19; } ________________________________________________________________________ 执行Controller方法后调用processDispatchResult方法检测及处理异常 ________________________________________________________________________ this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception var20) { this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20); } catch (Error var21) { this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21); } } finally { if(asyncManager.isConcurrentHandlingStarted()) { if(mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else if(multipartRequestParsed) { this.cleanupMultipart(processedRequest); } } }
当发生异常后执行processDispatchResult
2.执行processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; if(exception != null) { if(exception instanceof ModelAndViewDefiningException) { this.logger.debug("ModelAndViewDefiningException encountered", exception); mv = ((ModelAndViewDefiningException)exception).getModelAndView(); } else { ________________________________________________________________________ 如果不是ModelAndViewDefiningException类异常则调用processHandlerException()方法 ________________________________________________________________________ Object handler = mappedHandler != null?mappedHandler.getHandler():null; mv = this.processHandlerException(request, response, handler, exception); errorView = mv != null; } } if(mv != null && !mv.wasCleared()) { this.render(mv, request, response); if(errorView) { WebUtils.clearErrorRequestAttributes(request); } } else if(this.logger.isDebugEnabled()) { this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling"); } if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { if(mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, (Exception)null); } } }
如果存在异常且为非ModelAndViewDefiningException类异常,则执行processHandlerException
3.执行processHandlerException
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { ModelAndView exMv = null; Iterator var6 = this.handlerExceptionResolvers.iterator(); ________________________________________________________________________ 遍历开始时初始化的HandlerExceptionResolver列表,调用其resolveException方法 ________________________________________________________________________ while(var6.hasNext()) { HandlerExceptionResolver handlerExceptionResolver = (HandlerExceptionResolver)var6.next(); exMv = handlerExceptionResolver.resolveException(request, response, handler, ex); if(exMv != null) { break; } } if(exMv != null) { if(exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } else { if(!exMv.hasView()) { exMv.setViewName(this.getDefaultViewName(request)); } if(this.logger.isDebugEnabled()) { this.logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex); } WebUtils.exposeErrorRequestAttributes(request, ex, this.getServletName()); return exMv; } } else { throw ex; } }
自定义及使用异常处理器
1.实现HandlerExceptionResolver
public class MyExceptionResolver implements HandlerExceptionResolver { private ExceptionLogDao exceptionLogDao; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { __________________________________________________________ 异常处理 __________________________________________________________ ModelAndView modelAndView = new ModelAndView("errorPage"); return modelAndView; __________________________________________________________ 若返回null则继续下一个HandlerExceptionResolver __________________________________________________________ } }
2.将此Bean配置到Spring容器中
<bean class="com.xxg.MyExceptionResolver" />
3.与web.xml中的error-page冲突问题
有HandlerExceptionResolver则跳转到HandlerExceptionResolver中的view,如果没有则使用web.xml的配置.相关文章推荐
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
- SpringMVC源码情操陶冶-AbstractHandlerExceptionResolver
- SpringMvc中的异常处理ExceptionHandlerExceptionResolver的使用
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
- 利用HandlerExceptionResolver对SpringMVC进行统一异常处理
- SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
- SpringMVC的HandlerExceptionResolver
- springmvc 之HandlerExceptionResolver
- SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
- [置顶] SpringMvc 你该知道如何在HandlerExceptionResolver中获取Model
- 【SpringMVC】异常处理ExceptionHandlerExceptionResolver
- SpringMVC 异常处理 - HandlerExceptionResolver
- SpringMVC 学习笔记(十) 异常处理HandlerExceptionResolver
- SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
- SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
- SpringMVC框架中的异常解析器-ExceptionHandler和HandlerExceptionResolver
- 【原创】遨游springmvc之HandlerExceptionResolver
- SpringMVC 异常处理 - HandlerExceptionResolver
- springMvc 自定义错误处理--HandlerExceptionResolver
- springmvc 捕获全局异常 实现 HandlerExceptionResolver