Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺 序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。 拦截器与过滤器有几分相似,我们来对比下他们:
过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截,包括静态资源。拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦 截的。它也是 AOP 思想的具体应用。 我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。 拦截器的工作流程图
第一步:编写拦截器,实现HandlerInterceptor接口
/* 自定义拦截器 * jdk1.8之后对接口进行了增强,可以在接口中实现方法,所以我们实现接口没有实现方法时并没有报错 * */ public class MyInterceptor implements HandlerInterceptor { // 预处理 // 返回值为true: 方行->执行下一个拦截器(没有跳过)->controller方法 // 返回值为false: 不放行 // 在预处理中做逻辑判断等 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("拦截器执行了--预处理111"); return true; } // 后处理,执行顺序和上面一样 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器执行了--后处理111"); } // 最后处理,在浏览器跳转到指定页面之后再执行 // 一般用于释放资源 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("拦截器执行了--最后处理111"); } }第二步:配置拦截器
<!-- 配置拦截器 --> <mvc:interceptors> <!-- 配置第一个拦截器 --> <mvc:interceptor> <!-- 要拦截的具体方法 --> <mvc:mapping path="/user/*"/> <!-- 不要拦截的方法,和上者设置一个即可 --> <!-- <mvc:exclude-mapping path=""/>--> <!-- 配置该拦截对象 --> <bean id="myInterceptor1" class="cn.Interceptor.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>第三步:测试
即定义多个拦截器,多个拦截器的执行顺序如下 在上面的基础上在定义一个拦截器
public class MyInterceptor2 implements HandlerInterceptor { // 预处理 // 返回值为true: 方行->执行下一个拦截器(没有跳过)->controller方法 // 返回值为false: 不放行 // 在预处理中做逻辑判断等 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("拦截器执行了--预处理222"); return true; } // 后处理,执行顺序和上面一样 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器执行了--后处理222"); } // 最后处理,在浏览器跳转到指定页面之后再执行 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("拦截器执行了--最后处理222"); } }在配置文件中多配置一个拦截器
<!-- 配置拦截器 --> <mvc:interceptors> <!-- 配置第一个拦截器 --> <mvc:interceptor> <!-- 要拦截的具体方法 --> <mvc:mapping path="/user/*"/> <!-- 不要拦截的方法,和上者设置一个即可 --> <!-- <mvc:exclude-mapping path=""/>--> <!-- 配置该拦截对象 --> <bean id="myInterceptor1" class="cn.Interceptor.MyInterceptor"></bean> </mvc:interceptor> <!-- 配置第二个拦截器 --> <mvc:interceptor> <!-- 要拦截的具体方法 --> <mvc:mapping path="/user/*"/> <!-- 不要拦截的方法,和上者设置一个即可 --> <!-- <mvc:exclude-mapping path=""/>--> <!-- 配置该拦截对象 --> <bean id="myInterceptor2" class="cn.Interceptor.MyInterceptor2"></bean> </mvc:interceptor> </mvc:interceptors>测试