- 作为SpringMVC提供的拦截器,HandlerInterceptor有以下三个方法:
方法 |
说明 |
||||||||||
preHandle() |
请求处理前被调用,通过返回值,判定请求是否向下传递
|
||||||||||
postHandle() |
在preHandle()成功执行并返回为true的条件下,在请求处理后,数据模型产生后被调用,对数据的二次处理
|
||||||||||
afterCompletion() |
在preHandle()成功执行并返回为true的条件下,请求被返回或视图被返回,处理完成后调用
|
- 有两种使用方式
- 实现HandlerInterceptor接口
- 继承HandlerInterceptorAdapter类
示例
- MyInteceptor.java
public class MyInterceptor implements HandlerInterceptor { /** * preHandle: 预先处理请求的方法。 * 1. 预处理方法他的执行时间: 在控制器方法之前先执行的。 * 2. 可以对请求做处理, 可以做登录的检查, 权限的判断, 统计数据等等。 * 3. 决定请求是否执行。 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("=====MyInterceptor拦截器的preHandle===="); return true; }
/** * postHandle: 后处理方法 * 1. 在控制器方法之后执行的。 * 2. 能获取到控制器方法的执行结果。 可以修改原来的执行结果。 * 可以修改数据, 也可以修改视图 * 3. 可以做对请求的二次处理。 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception { System.out.println("=====MyInterceptor拦截器的postHandle===="); }
/** * afterCompletion: 最后执行的方法 * 1. 在请求处理完成后执行的, * 请求处理完成的标志是 视图处理完成,对视图执行forward操作后。 * * 2. 可以做程序最后要做的工作, 释放内存, 清理临时变量。 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("=====MyInterceptor拦截器的afterCompletion===="); } } |
- dispatcher-servlet.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--声明拦截器--> <mvc:interceptors> <!--声明第一个拦截器--> <mvc:interceptor> <!--指定拦截器的拦截地址 path:拦截的uri地址,使用 ** 通配符。 例如: path="/user/**" http://localhost:8080/user/listUser.do http://localhost:8080/user/query/queryUser.do --> <mvc:mapping path="/**" /> <!--指定使用的拦截器--> <bean class="com.bjpowernode.handler.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors> </beans> |
注
- 相较与Filter,HandlerInterceptor能够更加细粒度的拦截请求,从上面配置也可以看到,HandlerInterceptor能够配置多个拦截地址,并且能够排除也就是不过滤特殊请求。
- 关于请求链的传递,HandlerInterceptor通过布尔返回值判定是否继续传递,而Filter需要主动调用传递,也就是说ServletRequest和ServletResponse这两个对象在Filter传递时可以被替换
- Filter执行时优先于HandlerInterceptor,拦截器是侧重对请求做判断的,处理的, 可以截断请求。 过滤器是侧重对request,response对象的属性,参数设置值的
多个拦截器组合
- 在多拦截器的情况下,多个拦截器, 串在一个链条上的。 多个拦截器和一个控制器对象在一个链条上 ,框架中使用HandlerExecutionChain(处理器执行链),表示这个执行链条,
public class HandlerExecutionChain {
private final Object handler; // 存放控制器对象的,MyController @Nullable private HandlerInterceptor[] interceptors; // 存放多个拦截器对象的。MyInterceptor 1, 2 @Nullable private List<HandlerInterceptor> interceptorList; } |
- Spring mvc会先遍历所有拦截器的preHandle()方法,若存在flase,则忽略后面的拦截器,再从第一个拦截器开始执行其他方法