拦截器
- 自定义拦截器概述
- Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口
- preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
- postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理。
- afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
- 实验代码(单个拦截器)
- 自定义拦截器类
package com.sirius.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class FirstHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; } } |
- 配置拦截器
<mvc:interceptors> <!-- 声明自定义拦截器 --> <bean id="firstHandlerInterceptor" class="com.sirius.springmvc.interceptors.FirstHandlerInterceptor"></bean> </mvc:interceptors> |
- 断点调试拦截器执行流程
|
- 拦截器方法执行顺序(小总结)
- 实验代码(多个拦截器)
- 自定义拦截器类(两个)
package com.sirius.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class FirstHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; }
} | package com.sirius.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class SecondHandlerInterceptor implements HandlerInterceptor {
@Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion"); }
@Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println(this.getClass().getName() + " - postHandle"); }
@Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println(this.getClass().getName() + " - preHandle"); return true; }
} |
- 配置自定义拦截器
<mvc:interceptors> <!-- 声明自定义拦截器 --> <bean id="firstHandlerInterceptor" class="com.sirius.springmvc.interceptors.FirstHandlerInterceptor"></bean> <!-- 配置拦截器引用 --> <mvc:interceptor> <mvc:mapping path="/empList"/> <!-- <mvc:exclude-mapping path="/empList"/> --> <bean id="secondHandlerInterceptor" class="com.sirius.springmvc.interceptors.SecondHandlerInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> |
两个都是返回true : com.sirius.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.sirius.springmvc.interceptors.SecondHandlerInterceptor - preHandle ************************************biz method******************************* com.sirius.springmvc.interceptors.SecondHandlerInterceptor - postHandle com.sirius.springmvc.interceptors.FirstHandlerInterceptor - postHandle com.sirius.springmvc.interceptors.SecondHandlerInterceptor - afterCompletion com.sirius.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
两个都是返回false: com.sirius.springmvc.interceptors.FirstHandlerInterceptor - preHandle |
true,false com.sirius.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.sirius.springmvc.interceptors.SecondHandlerInterceptor - preHandle com.sirius.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
false,true |
com.sirius.springmvc.interceptors.FirstHandlerInterceptor - preHandle |
- 多个拦截方法的执行顺序
- 关于执行顺序
com.sirius.springmvc.interceptors.FirstHandlerInterceptor - preHandle com.sirius.springmvc.interceptors.SecondHandlerInterceptor – preHandle ************************************biz method******************************* com.sirius.springmvc.interceptors.SecondHandlerInterceptor - postHandle com.sirius.springmvc.interceptors.FirstHandlerInterceptor - postHandle com.sirius.springmvc.interceptors.SecondHandlerInterceptor - afterCompletion com.sirius.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion |
- 执行顺序图解
- 从源代码的执行角度分析流程:
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { if (getInterceptors() != null) { for (int i = 0; i < getInterceptors().length; i++) { HandlerInterceptor interceptor = getInterceptors()[i]; if (!interceptor.preHandle(request, response, this.handler)) { triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; } |
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { if (getInterceptors() == null) { return; } for (int i = getInterceptors().length - 1; i >= 0; i--) { HandlerInterceptor interceptor = getInterceptors()[i]; interceptor.postHandle(request, response, this.handler, mv); } } |
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
if (getInterceptors() == null) { return; } for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = getInterceptors()[i]; try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } |
- 源码分析:分析interceptorIndex的值情况