你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

springMVC自定义拦截器的执行顺序即底层原理实现

2021/12/27 21:13:08

首先自定义2个拦截器MyHandlerInterceptor1和MyHandlerInterceptor2

MyHandlerInterceptor1.java

//拦截器
public class MyHandlerInterceptor1 implements HandlerInterceptor {

    /**
     * 在执行handler之前
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @return true放行   false不放行
     * @throws Exception
     * 使用场景:登陆拦截、权限拦截等
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyHandlerInterceptor1 preHandle handler = "+handler);
        return false;
    }

    /**
     * 在执行handler之后,再返回ModelAndView对象之前
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @param modelAndView 数据+逻辑视图名
     * @throws Exception
     * 使用场景:当执行handler之后,逻辑视图不符合规则,则可以在此同一修改后返回
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyHandlerInterceptor1 postHandle handler = "+handler+ " modelAndView = "+ modelAndView);
    }

    /**
     * 在完成handler执行&返回ModelAndView对象之后执行
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @param ex       异常信息
     * @throws Exception
     * 使用场景:统一异常处理,统一日志处理
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyHandlerInterceptor1 afterCompletion handler = "+handler+" ex = "+ex);
    }
}

MyHandlerInterceptor2.java

//拦截器
public class MyHandlerInterceptor2 implements HandlerInterceptor {

    /**
     * 在执行handler之前
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @return true放行   false不放行
     * @throws Exception
     * 使用场景:登陆拦截、权限拦截等
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyHandlerInterceptor2 preHandle handler = "+handler);
        return false;
    }

    /**
     * 在执行handler之后,再返回ModelAndView对象之前
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @param modelAndView 数据+逻辑视图名
     * @throws Exception
     * 使用场景:当执行handler之后,逻辑视图不符合规则,则可以在此同一修改后返回
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyHandlerInterceptor2 postHandle handler = "+handler+ " modelAndView = "+ modelAndView);
    }

    /**
     * 在完成handler执行&返回ModelAndView对象之后执行
     * @param request  请求
     * @param response 响应
     * @param handler  Controller全类名#方法名(参数列表)
     * @param ex       异常信息
     * @throws Exception
     * 使用场景:统一异常处理,统一日志处理
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyHandlerInterceptor2 afterCompletion handler = "+handler+" ex = "+ex);
    }
}

在dispatcher-servlet.xml配置文件中配置拦截器

    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.igeek.ssm.interceptor.MyHandlerInterceptor1"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.igeek.ssm.interceptor.MyHandlerInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

两个自定义的拦截器的执行情况

关于拦截器放行的问题
第一种情况:MyHandlerInterceptor1 放行 MyHandlerInterceptor2 放行
MyHandlerInterceptor1 preHandle   return true
MyHandlerInterceptor2 preHandle   return true
MyHandlerInterceptor2 postHandle
MyHandlerInterceptor1 postHandle
MyHandlerInterceptor2 afterCompletion
MyHandlerInterceptor1 afterCompletion
第二种情况:MyHandlerInterceptor1 放行 MyHandlerInterceptor2 不放行
MyHandlerInterceptor1 preHandle  return true
MyHandlerInterceptor2 preHandle  return false
MyHandlerInterceptor1 afterCompletion
第三种情况:MyHandlerInterceptor1 不放行 MyHandlerInterceptor2 不放行
MyHandlerInterceptor1 preHandle  return false

对于第二种情况的底层代码解析

为什么会执行MyHandlerInterceptor1 afterCompletion

 

 所以会出现情况二的情况

不足之处敬请谅解!!!