目录
在springMVC中我们可以自定义拦截器来对请求进行拦截,进行相应的处理
拦截器是一个接口,里面有3个方法
示意图如下

首先创建一个类,实现HandlerInterceptor接口
- @Component
- public class MyInterceptor01 implements HandlerInterceptor {
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("调用preHandle方法");
- //返回false不会执行目标方法
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("调用postHandle方法");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("调用afterCompletion方法");
- }
- }
创建一个handler
- @RequestMapping("/member")
- @Controller
- public class MemberController {
-
- @RequestMapping("/f1")
- public String f1() {
- System.out.println("执行目标f1方法");
- return "success";
- }
- }
然后配置拦截器要对哪些请求进行拦截
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <ref bean="myInterceptor01"/>
- mvc:interceptor>
- mvc:interceptors>
上面配置的是会对所有请求进行拦截(**表示多级目录),下面访问对应handler查看输出

我们将preHandle方法返回值改为false
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("调用preHandle方法");
- //返回false不会执行目标方法
- return false;
- }
再次请求

在前面的基础上,再创建一个拦截器
- @Component
- public class MyInterceptor02 implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("调用preHandle--02方法");
- //返回false不会执行目标方法
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("调用postHandle--02方法");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("调用afterCompletion--02方法");
- }
- }
配置拦截器
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <ref bean="myInterceptor02"/>
- mvc:interceptor>
现在2个拦截器的preHandl都是返回true,放行的,下面查看输出

可以知道执行顺序是 A(pre)->B(pre)->目标方法->B(post)->A(post)->B(after)->A(after)的顺序执行的。
我们方法为什么是过滤器01先执行呢,其实这个顺序就是和spring配置顺序一样的,我在配置文件中先配置的过滤器01,下面交换一下顺序
- <mvc:interceptors>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <ref bean="myInterceptor02"/>
- mvc:interceptor>
- <mvc:interceptor>
- <mvc:mapping path="/**"/>
- <ref bean="myInterceptor01"/>
- mvc:interceptor>
- mvc:interceptors>
再次请求,输出如下,还是符合A(pre)->B(pre)->目标方法->B(post)->A(post)->B(after)->A(after)

将顺序换回来,然后将第一个拦截器的和第二个拦截器的preHandle方法分别返回false,输出如下


可以发现,只要preHandle执行后返回为true,那么afterCompletion就会执行
拦截器可以对请求的一些消息进行过滤,也可以在视图渲染之后执行一些释放的操作,拦截器可以说是和过滤器十分的相似。