学科分类
目录
SSM框架

多个拦截器的执行流程

在大型的企业级项目中,通常不会只有一个拦截器,开发人员可能会定义很多拦截器来实现不同的功能。那么多个拦截器的执行顺序又是怎样的呢?下面通过一张图来描述多个拦截器的执行流程(假设有两个拦截器Interceptor1和Interceptor2,并且在配置文件中, Interceptor1拦截器配置在前),如图1所示。

图1 多个拦截器的执行流程

从图1可以看出,当有多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。

为了验证上述描述,下面通过修改15.2.1小节的案例来演示多个拦截器的执行,具体步骤如下。

(1)在com.itheima.interceptor包中,创建两个拦截器类Interceptor1和Interceptor2,这两个拦截器类均继承自HandlerInterceptor,并重写其中的方法,如文件1和文件1所示。

文件1 Interceptor1.java

 1    package com.itheima.interceptor;
 2    import javax.servlet.http.HttpServletRequest;
 3    import javax.servlet.http.HttpServletResponse;
 4    import org.springframework.web.servlet.HandlerInterceptor;
 5    import org.springframework.web.servlet.ModelAndView;
 6    /**
 7     * 以实现接口的方式定义拦截器
 8     */
 9    public class Interceptor1 implements HandlerInterceptor {
 10        @Override
 11        public boolean preHandle(HttpServletRequest request, 
 12            HttpServletResponse response, Object handler) throws Exception {
 13            System.out.println("Intercepter1...preHandle");
 14            return true;
 15        }
 16        @Override
 17        public void postHandle(HttpServletRequest request, 
 18            HttpServletResponse response, Object handler,
 19            ModelAndView modelAndView) throws Exception {
 20            System.out.println("Intercepter1...postHandle");
 21        }
 22        @Override
 23        public void afterCompletion(HttpServletRequest request, 
 24            HttpServletResponse response, Object handler, 
 25            Exception ex) throws Exception {
 26            System.out.println("Intercepter1...afterCompletion");
 27        }
 28    }

文件2 Interceptor2.java

 1    package com.itheima.interceptor;
 2    import javax.servlet.http.HttpServletRequest;
 3    import javax.servlet.http.HttpServletResponse;
 4    import org.springframework.web.servlet.HandlerInterceptor;
 5    import org.springframework.web.servlet.ModelAndView;
 6    /**
 7     * 以实现接口的方式定义拦截器
 8     */
 9    public class Interceptor2 implements HandlerInterceptor{
 10        @Override
 11        public boolean preHandle(HttpServletRequest request, 
 12            HttpServletResponse response, Object handler) throws Exception {
 13            System.out.println("Interceptor2...preHandle");
 14            return true;
 15        }
 16        @Override
 17        public void postHandle(HttpServletRequest request, 
 18            HttpServletResponse response, Object handler,
 19            ModelAndView modelAndView) throws Exception {
 20            System.out.println("intercepter2...postHandle");
 21        }
 22        @Override
 23        public void afterCompletion(HttpServletRequest request, 
 24            HttpServletResponse response, Object handler, Exception ex)
 25            throws Exception {
 26            System.out.println("Intercepter2...afterCompletion");
 27        }
 28    }

(2)在配置文件springmvc-config.xml中的<mvc:interceptors>元素内配置上面所定义的两个拦截器,配置代码如下所示。

<!-- 拦截器1 -->
<mvc:interceptor>
    <!-- 配置拦截器作用的路径 -->
    <mvc:mapping path="/**" />
    <!-- 定义在<mvc:interceptor>下面的表示匹配指定路径的请求才进行拦截的 -->
    <bean class="com.itheima.interceptor.Interceptor1" />
</mvc:interceptor>
<!-- 拦截器2 -->
<mvc:interceptor>
    <mvc:mapping path="/hello" />
    <bean class="com.itheima.interceptor.Interceptor2" />
</mvc:interceptor>

在上述拦截器的配置代码中,第一个拦截器会作用于所有路径下的请求,而第二个拦截器会作用于以“/hello”结尾的请求。

小提示:

为了不影响程序的输出结果,可将上一小节案例中所配置的CustomInterceptor的拦截器配置注释掉。

(3)发布项目到Tomcat服务器并启动,在浏览器中访问地址http://localhost:8080/chapter15/hello,控制台中输出的信息如图2所示。

图2 运行结果

从图2可以看出,程序先执行了前两个拦截器类中的preHandle()方法,这两个方法的执行顺序与配置文件中定义的顺序相同;然后执行了控制器类中的Hello()方法;最后执行了两个拦截器类中的postHandle()方法和afterCompletion()方法,且这两个方法的执行顺序与配置文件中所定义的拦截器顺序相反。

点击此处
隐藏目录