SpringMVC 拦截器使用方法 SpringMVC Interceptor拦截器执行顺序理解
一、拦截器作用
1、Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
二、使用方法
1、依赖 spring-webmvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>
2、创建一个LogInterceptor 类,
实现 org.springframework.web.servlet.HandlerInterceptor 接口
3、重写的 preHandle 、 postHandle 、 afterCompletion 作用如下:
/**
* preHandle: Controller 执行之前,调用该方法
* 返回 true,表示继续执行 ; 返回 false ,终止执行。
* 应用: 登陆校验、权限拦截 等。
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("LogInterceptor =====> preHandle ");
return true;
}
/**
* postHandle: Controller 执行之后,但未返回视图前,调用此方法。
* 应用:对模型数据进行加工处理,加入公用信息以便页面显示 ; 或者手机、平板等移动端访问,返回对应页面数据。
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView view)
throws Exception {
System.out.println("LogInterceptor =====> postHandle ");
if(null != view) {
System.out.println("viewName: "+view.getViewName());
}
}
/**
* afterCompletion: Controller 执行之后,且返回视图后,调用此方法。
* 应用:日志记录、异常记录、资源清理等。
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("LogInterceptor =====> afterCompletion ");
}
4、spirng-mvc.xml 中配置拦截器
<mvc:interceptors>
<!-- LogInterceptor -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="logInterceptor" class="com.runcode.interceptor.LogInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
5、启动项目,请求任意一个url,可以看到控台输出:
LogInterceptor =====> preHandle // 执行Controller 之前
hello // 执行Controller
LogInterceptor =====> postHandle // 执行Controller,返回视图之前
LogInterceptor =====> afterCompletion // 执行Controller,返回视图之后
三、执行顺序理解
1、分别创建 FirstInterceptor 和 SecondInterceptor
public class FirstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("FirstInterceptor ---> preHandle" );
return true;
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("FirstInterceptor ---> postHandle" );
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("FirstInterceptor ---> afterCompletion" );
}
}
2、FirstInterceptor 和 SecondInterceptor 顺序 配置如下(先First,后Second):
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/userController/**"/>
<bean class="com.runcode.interceptor.FirstInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/userController/**"/>
<bean class="com.runcode.interceptor.SecondInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
3、FirstInterceptor 和 SecondInterceptor 的 preHandle 方法都返回 true
4、控制台输出如下:
FirstInterceptor ---> preHandle
SecondInterceptor ---> preHandle
SecondInterceptor ---> postHandle
FirstInterceptor ---> postHandle
SecondInterceptor ---> afterCompletion
FirstInterceptor ---> afterCompletion
5、SecondInterceptor 和 FirstInterceptor 倒序 配置如下(先Second,后First)
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/userController/**"/>
<bean class="com.runcode.interceptor.SecondInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/userController/**"/>
<bean class="com.runcode.interceptor.FirstInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
6、FirstInterceptor 和 SecondInterceptor 的 preHandle 方法都返回 true 。
7、控制台输出如下:
SecondInterceptor ---> preHandle
FirstInterceptor ---> preHandle
FirstInterceptor ---> postHandle
SecondInterceptor ---> postHandle
FirstInterceptor ---> afterCompletion
SecondInterceptor ---> afterCompletion
8、根据拦截器配置顺序:
配置在前: preHandle 先执行; postHandle 和 afterCompletion,后执行。
四、返回false时测试
1、FirstInterceptor 和 SecondInterceptor 顺序配置,但FirstInterceptor 的 preHandle返回 false , SecondInterceptor 的preHandle返回 true 。 (先First,后Second , 配置 【三-2】)
2、控制台输出如下:
FirstInterceptor ---> preHandle
3、结论: SecondInterceptor 和 Controller 都不执行。
4、FirstInterceptor 和 SecondInterceptor 顺序配置,但FirstInterceptor的preHandle返回 true , SecondInterceptor 的preHandle返回 false 。(先First,后Second , 配置 【三-2】)
FirstInterceptor ---> preHandle
SecondInterceptor ---> preHandle
FirstInterceptor ---> afterCompletion
5、结论:拦截器中只要有返回false,则 postHandle 方法不会执行 ; 单一拦截器中,preHandle 返回true, afterCompletion 才会执行。
五、总结
1、按照 springmvc.xml中配置的拦截器先后顺序,规律如下:
- preHandle 按照顺序执行 (配置在前,先执行)
- postHandle 按照倒序执行。 (配置在前,后执行)
- afterCompletion 同 postHandle 。