• 011 异常处理


    一 . 概述

      标准的mvc框架都有一个异常处理机制,springmvc同样也提供了一个处理的方式.

      在之前的源码之中,我们看到了springmvc统一获取了异常,也就是说springmvc获得了统一处理异常的方式.


    二 . 异常处理器

      在springmvc之中,将统一的异常处理交给了异常处理器.

    我们首先看一下异常处理器的结构: 

    public interface HandlerExceptionResolver {
    
      
        ModelAndView resolveException(
                HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
    
    }

    其中有一个核心的方法,我们从参数之中就可以看出,几乎处理异常所需要的所有的参数都拥有了.


    三 .自定义异常处理器

      上面我们看到了springmvc的跟接口,我们就自定义一个异常处理器.  

    public class InnerExecptionHandler implements HandlerExceptionResolver{
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) {
            System.out.println(ex);
            return null;
        }
    
    }

    我们将上面的处理器配置到springmvc配置文件之中.

        <bean class="com.trek.execptionHandler.InnerExecptionHandler">
        </bean>
        @RequestMapping("/exception")
        public String exception() {
            int i = 1/ 0 ;
            return "/WEB-INF/jsp/success.jsp";
        }

    现在当我们请求时,我们会发现出现了异常在控制台会有打印了.

      那个打印的语句就是异常处理器完成的.


    四 .原理分析

      springmvc容器在加载的时候,会初始化异常解析器.  

    protected void initStrategies(ApplicationContext context) {
            initMultipartResolver(context);
            initLocaleResolver(context);
            initThemeResolver(context);
            initHandlerMappings(context);
            initHandlerAdapters(context);
            initHandlerExceptionResolvers(context);
            initRequestToViewNameTranslator(context);
            initViewResolvers(context);
            initFlashMapManager(context);
        }

    我们进入代码之中:  

    if (this.detectAllHandlerExceptionResolvers) {
                // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
                Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
                        .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
                if (!matchingBeans.isEmpty()) {
                    this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());
                    // We keep HandlerExceptionResolvers in sorted order.
                    AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
                }
            }

    springmvc会寻找所有的HandlerExceptionResolver的子类,加入到异常处理器之中.

      当出现异常的时候,我们看源码:  

    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) {
                    logger.debug("ModelAndViewDefiningException encountered", exception);
                    mv = ((ModelAndViewDefiningException) exception).getModelAndView();
                }
                else {
                    Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                    mv = processHandlerException(request, response, handler, exception);
                    errorView = (mv != null);
                }
            }
    
            // Did the handler return a view to render?
            if (mv != null && !mv.wasCleared()) {
                render(mv, request, response);
                if (errorView) {
                    WebUtils.clearErrorRequestAttributes(request);
                }
            }

    我们看到这里统一对异常进行了处理,会调用processHandlerException()方法.

    这个方法的核心就是从所有的注册的异常解析器之中获取,然后依次尝试进行处理.

  • 相关阅读:
    模拟
    广搜——最优方案
    动态规划——背包
    动态规划——树规
    动态规划——区间
    fill 的用法
    状态压缩dp
    超大背包问题
    lower_bound
    弹性碰撞 poj 3684
  • 原文地址:https://www.cnblogs.com/trekxu/p/9128954.html
Copyright © 2020-2023  润新知