SpringMvc之HandlerExceptionResolver

来源:互联网 发布:网络爬虫的目的和意义 编辑:程序博客网 时间:2024/05/22 17:21

故事先从SpringMvc的dispatcherServlert开始

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的配置.

原创粉丝点击