从DispatcherServlet到HandlerExceptionResolver

tomcat启动DispatcherServlet默认加载的HandlerExceptionResolver有:org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver、org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver以及org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver和自定义HandlerExceptionResolver。可以通过重写HandlerExceptionResolver的实现来自定义异常处理器。

HandlerExceptionResolver接口里只有一个方法resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex),这个方法的作用是解决在程序执行期间引发的给定异常,返回一个ModelAndView,根据返回的ModelAndView的isEmpty()方法来判断是否成功解决异常,如果isEmpty()为true 那就表示已经解决,否则则反。

DispatcherServlet在doDispatch(HttpServletRequest request, HttpServletResponse response)方法中捕获异常(如果有的话),

doDispatch方法调用processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception),

processDispatchResult()方法先判断exception是否为空,如果不为空并且异常是一个继承自ModelAndViewDefiningException类型的异常,那就直接返回exception的ModelAndView对象。如果不为空且异常不继承自ModelAndViewDefiningException,则将异常交给processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)方法处理。

protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
			Object handler, Exception ex) throws Exception {

		// Check registered HandlerExceptionResolvers...
		ModelAndView exMv = null;
		for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
			exMv = handlerExceptionResolver.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()) {
				exMv.setViewName(getDefaultViewName(request));
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);
			}
			WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
			return exMv;
		}

		throw ex;
	}

processHandlerException方法先遍历所有的异常解析器,每一个用每一个异常解析器去解析exception。

解析器的resolveException方法返回一个ModelAndView,processHandlerException方法根据resolveException返回的ModelAndView的isEmpty()方法来判断是否成功解决异常,如果isEmpty()为true 那就表示已经解决,为false则返回ModelAndView。

如果resolveException返回ModelAndView不为空且没有被删除processDispatchResult方法将调用WebUtils.clearErrorRequestAttributes(request)方法将错误attributes清理为HttpServletRequest的attributes。

猜你喜欢

转载自blog.csdn.net/qq_26400953/article/details/86642986
今日推荐