17.SpringMVC核心技术-拦截器
SpringMVC 中的 Interceptor 拦截器是非常重要和相当有用的,它的主要作用是拦截指定 的用户请求,
并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提 交的请求映射出了所要执行的处理器类,
并且也找到了要执行该处理器类的处理器适配器, 在处理器适配器执行处理器之前”。
当然,在处理器映射器映射出所要执行的处理器类时, 已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。
一个拦截器的执行
1.自定义拦截器
1 /*处理器执行链就是 处理器 加上这些拦截器,处理器执行链交给 中央调度器去处理*/ 2 public class FirstInterceptor implements HandlerInterceptor { 3 4 /*该方法在处理器方法执行之前执行, 其返回值 为 boolean,若为true,则紧接着会执行处理器方法,且会将 aferCompletion()方法 放入到一个专门的方法栈中等待执行*/ 5 /*如果返回的 false,则 该拦截器 和 处理器之间的 联系就断了,就不会执行处理器的任何方法了,更别谈 postHandle 方法, aferCompletion()有可能执行,因为它是独立放在一个栈中*/ 6 @Override 7 public boolean preHandle(HttpServletRequest request, 8 HttpServletResponse response, Object handler) throws Exception { 9 System.out.println("执行 FirstInterceptor 的 preHandle 方法!!!"); 10 return true; 11 } 12 13 /*该方法在处理器执行之后执行。处理器方法若最终未被执行,则该方法不会执行 。*/ 14 @Override 15 public void postHandle(HttpServletRequest request, 16 HttpServletResponse response, Object handler, 17 ModelAndView modelAndView) throws Exception { 18 System.out.println("执行 FirstInterceptor 的 postHandle 方法!!!"); 19 20 } 21 22 /*aferComletion 执行的前提:1.preHandle方法需要被执行 2.preHandle方法的返回值为 true*/ 23 /*此时才会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法 (即该方法是在中央调度器渲染(数据填充)页面之后,才执行)*/ 24 @Override 25 public void afterCompletion(HttpServletRequest request, 26 HttpServletResponse response, Object handler, Exception ex) 27 throws Exception { 28 System.out.println("执行 FirstInterceptor 的 afterCompletion 方法!!!"); 29 30 } 31 32 }
自定义拦截器,需要实现 HandlerInterceptor 接口。而该接口中含有三个方法:
preHandle(request, response, Object handler): 该方法在处理器方法执行之前执行。其返回值为 boolean,
若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。
postHandle(request, response, Object handler, modelAndView): 该方法在处理器方法执行之后执行。
处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,
且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
afterCompletion(request, response, Object handler, Exception ex):当 preHandle()方法返回 true 时,
会将该方法放到专门的方法栈中,等到对请求进行响应的所有 工作完成之后才执行该方法。
即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此 时对 ModelAndView 再操作也对响应无济于事。
拦截器中方法与处理器方法的执行顺序如下图:
2.注册拦截器
1 <mvc:interceptors> 2 <mvc:interceptor> 3 <!-- 指定注册的拦截器 可以拦截的路径请求 --> 4 <mvc:mapping path="/*"/> 5 <bean class="com.springmvc.interceptor.FirstInterceptor"/> 6 </mvc:interceptor>
多个拦截器的执行
/*当存在多个拦截器时,拦截器的方法调用顺序是 链式的 (1 2 3 2 1)*/