在学习拦截器开发之前提一嘴,大家要搞清楚过滤器和拦截器的区别,发现一篇讲的比较明白的博客,大家可以参考。《拦截器和过滤器的区别》
一、开发拦截器类
为了更好的说明拦截器的执行顺序,我在写了两个拦截器类,其内容是一样的,我在这里只把其中一个拦截器类的代码粘贴过来。
package cool.gjh.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拦截器
* <p>
* 针对/student请求的拦截处理
* </p>
*
* @author ACE_GJH
*/
@Component
public class StudentInterceptor1 implements HandlerInterceptor {
/**
* 请求最先经过的方法,在HandlerAdapter之前调用
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler chosen handler to execute, for type and/or instance evaluation
* @return {@code true} 放行请求;{@code false} 中断请求
* @throws Exception in case of errors
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("StudentInterceptor1:preHandle");
return true;
}
/**
* 请求在HandlerAdapter之后调用
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or {@link HandlerMethod}) that started asynchronous
* execution, for type and/or instance examination
* @param modelAndView the {@code ModelAndView} that the handler returned
* (can also be {@code null})
* @throws Exception in case of errors
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("StudentInterceptor1:postHandle");
}
/**
* 请求完成之后调用。
* <p>注意:仅当此拦截器的{@code preHandle} 方法成功完成并返回{@code true}时才会调用!
* <p>与{@code postHandle}方法一样,该方法将在链中的每个拦截器上以相反的顺序调用,因此第一个拦截器将是最后一个要调用的拦截器。
*
* @param request current HTTP request
* @param response current HTTP response
* @param handler handler (or {@link HandlerMethod}) that started asynchronous
* execution, for type and/or instance examination
* @param ex exception thrown on handler execution, if any
* @throws Exception in case of errors
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("StudentInterceptor1:afterCompletion");
}
}
二、配置拦截器
在springmvc.xml
中配置:
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/student/*"/>
<ref bean="studentInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/student/*"/>
<ref bean="studentInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
三、测试效果
访问:http://localhost:8080/spring/student/data
结论:通过打印结果可以明显看到拦截器中preHandle()、postHandle()和afterCompletion()的执行时机和顺序。
四、拦截器的执行顺序
在上面的结论中我们可以看到,同一个拦截器中三个方法的执行时机是什么,如果项目中有多个拦截器,对某一个请求路径的拦截有顺序要求,那该如何配置呢?估计大家已经想到了,跟配置文件中<mvc:interceptor>
标签的顺序有关,没错,我们来试一下。
springmvc.xml
调整拦截器的配置顺序:
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/student/*"/>
<ref bean="studentInterceptor2"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/student/*"/>
<ref bean="studentInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
测试结果:
结论:说明拦截器配置的执行顺序和配置顺序是一致的。