SpringMVC:进阶( 四 )

测试拦截器的拦截效果编写 com.renda.controller.TargetController , 请求到 controller , 跳转页面
@Controllerpublic class TargetController {@RequestMapping("/target")public String targetMethod() {System.out.println("targetMethod executed ...");return "success";}}success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>SUCCESS</title></head><body>?<h3>success... ${username}</h3><% System.out.println("Success...");%>?</body></html>控制台输出结果:
preHandle1....targetMethod executed ...postHandle1....Success...afterCompletion1....拦截器链开发中拦截器可以单独使用 , 也可以同时使用多个拦截器形成一条拦截器链 。开发步骤和单个拦截器是一样的 , 只不过注册的时候注册多个 , 注意这里注册的顺序就代表拦截器执行的顺序 。
同上 , 再编写一个 MyHandlerInterceptor2 操作:
public class MyInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle2....");return true;}?@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle2....");}?@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion2...");}}spring-mvc.jsp
<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.renda.interceptor.MyInterceptor1"></bean></mvc:interceptor><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.renda.interceptor.MyInterceptor2"></bean></mvc:interceptor></mvc:interceptors>控制台输出结果:
preHandle1....preHandle2....targetMethod executed ...postHandle2....postHandle1....Success...afterCompletion2...afterCompletion1....当MyInterceptor1 的 preHandler 方法返回 true , MyHandlerInterceptor2 的 preHandler 方法返回 false;此时 , MyInterceptor1 的 preHandler 方法优先执行并返回 true , 即便MyHandlerInterceptor2 的 preHandler 方法返回 false , MyInterceptor1 的 afterCompletion 方法仍然被执行了 。控制台输出结果:
preHandle1....preHandle2....afterCompletion1....当 MyInterceptor1 的 preHandler 方法返回 false , MyHandlerInterceptor2 的 preHandler 方法返回 true;此时 , MyInterceptor1 的 preHandler 方法优先执行并返回 false , 方法被拦截 , MyHandlerInterceptor2 的 preHandler 方法也无法执行 。控制台输出结果:
preHandle1....所以形成拦截器链时 , 当拦截器 1 的 preHandler 方法成功执行并返回 true 后 , 被它拦截的方法即便被另一个拦截器 2 所拦截并返回了 false , 拦截器 1 的afterCompletion 方法仍然会被执行 。
源码解释:
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors. * Will just invoke afterCompletion for all interceptors whose preHandle invocation * has successfully completed and returned true. */void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)throws Exception {...} 
小结拦截器中的方法说明:

  • preHandle() - 方法将在请求处理之前进行调用 , 该方法的返回值是布尔值类型的 , 当它返回为 false 时 , 表示请求结束 , 后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时就会继续调用下一个 Interceptor 的 preHandler 方法
  • postHandle() - 该方法是在当前请求进行处理之后被调用 , 前提是 preHandler 方法的返回值为 true 时才能被调用 , 且它会在 DispatcherServlet 进行视图返回渲染之前被调用 , 所以可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作
  • afterCompletion() - 该方法在整个请求结束之后 , 就是在DispatcherServlet 渲染了对应的视图之后执行 , 前提是 preHandler 方法的返回值为 true 时才能被调用
想了解更多 , 欢迎关注我的微信公众号:Renda_Zhang

【SpringMVC:进阶】


推荐阅读