Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器(自己编写的Controller)进行预处理和后处理。用户可以自己定义一些拦截器来实现特定的功能
拦截器概述
谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。说到这里,可能大家脑海中有了一个疑问,这不是我们之前学的过滤器吗?是的它和过滤器是有几分相似,但
是也有区别,接下来我们就来说说他们的区别:
| 类别 |
使用范围 |
拦截范围 |
| 拦截器 |
SpringMVC项目 |
只会拦截访问的控制器方法的请求 |
| 过滤器 |
任何web项目 |
任何资源(servlet,控制器,jsp,html等) |
我们要想自定义拦截器, 要求必须实现: HandlerInterceptor 接口。
自定义拦截器入门
- 编写一个普通类实现 HandlerInterceptor 接口
package com.jwang.interceptor;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class PermissionInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PermissionInterceptor的preHandle方法执行了..."); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("PermissionInterceptor的postHandle方法执行了..."); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("PermissionInterceptor的afterCompletion方法执行了..."); } }
|
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.jwang"/>
<!--配置拦截器--> <mvc:interceptors> <!-- 里面可以配置多个拦截器,每一个interceptor就是一个拦截器 --> <mvc:interceptor> <!-- mapping表示这个拦截器的拦截范围 --> <mvc:mapping path="/**" /> <!-- exclude-mapping --> <mvc:exclude-mapping path="/hello/sayHaha.do"/> <!-- bean标签表示对我们要进行配置的拦截器做IOC --> <bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean> </mvc:interceptor> </mvc:interceptors> </beans>
|
自定义拦截器进阶
拦截器的放行

拦截器的路径
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com.jwang"/>
<!--配置拦截器--> <mvc:interceptors> <!-- 里面可以配置多个拦截器,每一个interceptor就是一个拦截器 --> <mvc:interceptor> <!-- mapping表示这个拦截器的拦截范围 /**表示拦截所有控制器方法 --> <mvc:mapping path="/**" /> <!-- exclude-mapping --> <mvc:exclude-mapping path="/hello/sayHaha.do"/> <!-- bean标签表示对我们要进行配置的拦截器做IOC --> <bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean> </mvc:interceptor> </mvc:interceptors> </beans>
|
拦截器的其它方法
- afterCompletion 在目标方法完成视图层渲染后执行。
- postHandle 在目标方法执行完毕获得了返回值后执行。
- preHandle 被拦截的目标方法执行之前执行。
package com.jwang.interceptor;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
public class PermissionInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PermissionInterceptor的preHandle方法执行了..."); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("PermissionInterceptor的postHandle方法执行了..."); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("PermissionInterceptor的afterCompletion方法执行了..."); } }
|
多个拦截器执行顺序
回想多个过滤器的执行顺序:
如果采用配置文件方式配置过滤器,那么就按照过滤器的配置先后顺序执行
2. 如果采用注解方式配置过滤器,那么就按照类名的排序执行
我们可以配置多个拦截器, 所以就存在一个优先级问题了.多个拦截器的优先级是按照配置的顺序决定的。

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/hello/sayHaha.do"/>
<bean id="permissionInterceptor" class="com.jwang.interceptor.PermissionInterceptor"> </bean> </mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="secondInterceptor" class="com.jwang.interceptor.SecondInterceptor"> </bean> </mvc:interceptor> </mvc:interceptors>
|