SpringMVC-拦截器
  TEZNKK3IfmPf 2023年11月13日 38 0

Java 里的拦截器是动态拦截 ​​action​​​ 调用的对象,可以对 Controller 中的方法执行之前与执行之后, 及页面显示完毕后, 执行指定的方法,自定义的拦截器必须实现 ​​HandlerInterceptor​​ 接口

方法介绍

preHandle

????在业务处理器处理请求之前被调用

postHandle

????在业务处理器处理完请求后被调用

afterCompletion

????在 ​​DispatcherServlet​​ 完全处理完请求后被调用

使用 SpringMVC 拦截器

拦截所有请求

创建一个类实现 ​​HandlerInterceptor​​ 接口详细内容如下

/**
* @author BNTang
*/
public class MyFirstInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("处理器方法执行之前调用 → preHandle");
return false;
}

@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");
}
}

preHandle 返回值 ​​true​​​ 代表放行 ​​false​​ 代表不放行就执行不了处理器方法

然后紧接着就是修改核心配置文件了,在配置文件当中添加 ​​拦截器​

<mvc:interceptors>
<!--设置自定义,拦截器,拦截所有请求-->
<bean class="top.it6666.web.interceptor.MyFirstInterceptor"/>
</mvc:interceptors>

SpringMVC-拦截器

启动工程,访问工程中的某一个 Controller 查看效果如下

SpringMVC-拦截器

拦截指定请求

修改 SpringMVC 核心配置文件,配置一下需要拦截的指定请求,哪些请求不需要拦截

SpringMVC-拦截器

<mvc:interceptors>
<mvc:interceptor>
<!--设置拦截哪些请求-->
<mvc:mapping path="/local"/>
<!--设置哪些请求不拦截-->
<mvc:exclude-mapping path="/exception"/>
<bean class="top.it6666.web.interceptor.MyFirstInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

启动工程,访问被拦截的接口效果如下

SpringMVC-拦截器

SpringMVC-拦截器

配置多个拦截器的执行顺序

在配置了多个拦截器它们的执行顺序是怎样的呢,首先先把 ​​preHandle​​​ 方法的返回值都改为 ​​tru​​​ 也就是放行,然后启动工程访问 ​​local​​ 接口,查看控制台的输出信息如下

SpringMVC-拦截器

结果发现,​​preHandle​​​ 是按顺序执行了,而其他的都是按照倒序执行的,至于为什么就要来看看源码了,源码分析如下, 多个拦截器都返回 ​​true​​​ 的源码执行流程如下,首先来看一下 ​​preHandle​​​、​​postHandle​​​、​​afterCompletion​​​ 这三个方法的分别调用时机吧,还是一样的从 ​​DispatcherServlet​​ 开始,调用时机如下图

SpringMVC-拦截器

调用时机看完了之后,现在就一个一个来分析它内部的执行流程吧,先来看 ​​applyPreHandle​​​ 先不看别的就看循环它是怎么循环的即可,该方法的循环为 ​​++​​,那么就说明了是按照顺序一个一个取出进行执行了

SpringMVC-拦截器

经过如上的图就可以得出 ​​preHandle​​​ 为啥是按顺序执行的了,那么紧接着就来看 ​​postHandle​​​ 为啥是倒序执行吧,postHandle 对应的源码方法为 ​​applyPostHandle​​​ 进入代码内容发现该方法的循环为 ​​–​​ 那么这也就是为啥是倒序执行的原因了

SpringMVC-拦截器

废话不多说,最后一个直接上源码了,原理同上

SpringMVC-拦截器

如上都是返回 ​​true​​​ 的情况,那么返回 ​​false​​​ 的情况呢,如下,第一个拦截器返回 ​​false​​​ 第二个拦截器返回 ​​true​​ 的执行流程如下

SpringMVC-拦截器

首先调用 ​​applyPreHandle​​​ 的时候里面有四个拦截器其中有一个是 SpringMVC 弄的,另外的3个是我们自己弄的,当循环走到我们的倒数第二个拦截器的时候你会发现,它进入到了 ​​triggerAfterCompletion​​​ 方法内部,那么为啥呢,就因为你在 ​​preHandle​​ 方法中返回了一个 false 然后非一下就成了 true 然后就条件成立进入了

SpringMVC-拦截器

那么 ​​triggerAfterCompletion​​​ 方法内部主要做了什么呢,在进入 ​​triggerAfterCompletion​​​ 方法之前 ​​interceptorIndex​​​ 的索引角标为 ​​1​

SpringMVC-拦截器

而 i 却是等于了 ​​2​​​ 进入 ​​triggerAfterCompletion​​ 方法内部,查看详细内容如下,一样的是取出所有的拦截器数组

SpringMVC-拦截器

不过这个循环你需要注意一下了,它进入这个方法的时候 ​​interceptorIndex​​​ 是为 ​​1​​​ 那么我们的拦截器已经不会再从拦截器数组中获取了这也就是为什么只是输出了一个 ​​preHandle​​ 的原因了

SpringMVC-拦截器

这个方法执行完毕之后在往回执行直接返回了一个 false 在往上又进行了非的逻辑运算符又成了 true 然后就直接结束了后面的都不会再执行了

SpringMVC-拦截器

如上是第一个拦截器返回 false 第二个拦截器返回 true 的情况的执行流程,那么第一个拦截器返回 true 第二个拦截器返回 false 的执行流程是怎样的呢,自行修改 true false, 我这里直接讲解源码流程

SpringMVC-拦截器

如上图的解释就是我们自定义的拦截器第一个返回的是 true 那么 ​​preHandle​​​ 执行了,preHandle 返回的是 true 这个时候不会进入 ​​triggerAfterCompletion​​​ 然后继续往下取,取角标为 ​​3​​​ 的拦截器这个时候 ​​preHandle​​​ 执行了打印了我们的内容,而这个时候 ​​preHandle​​​ 返回的是 false 非一下成为了 ​​true​​​ 会进入 ​​triggerAfterCompletion​​​ 方法体中,这个时候你需要注意一个变量那么就是 ​​interceptorIndex​​​ 这个值,在最后一个拦截器进入到 ​​triggerAfterCompletion​​​ 方法体的时候 ​​interceptorIndex​​​ 这个值为 ​​2​​​ 为 ​​2​​​,那么这个时候又去拦截器数组倒序取,那么最后一个拦截器是不会取出的,只取了第一个,那么第一个的 ​​afterCompletion​​​ 执行了也就是会打印我们在 ​​afterCompletion​​ 方法体中编写的内容

SpringMVC-拦截器

执行完毕返回 false 最外面的方法运用了非的逻辑运算符就成了 true 条件成立导致后面的就都不会在执行了

SpringMVC-拦截器

内部源码分析

还是一样的套路先从 ​​DispatcherServlet​​​ 进入,查看 ​​doDispatch​

SpringMVC-拦截器

如上方框框出来的内容是代表,要应用拦截器,点击方法进入进去查看,进入之后的代码如下

SpringMVC-拦截器

如上的内容你就关注两个点,我方框框着的点即可,如果返回 ​​false​​ 到了之前的那个方法,非一下就成了 ​​true​​ 下面的内容就不在执行了

SpringMVC-拦截器

而返回 ​​true​​ 就不一样了,返回 ​​true​​ 下面的内容就还会继续执行

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2023年11月13日   28   0   0 springMVC上传
  TEZNKK3IfmPf   2023年11月13日   31   0   0 springMVC
  TEZNKK3IfmPf   2023年11月13日   54   0   0 springMVC
  TEZNKK3IfmPf   2023年11月14日   24   0   0 springMVC
  TEZNKK3IfmPf   2023年11月14日   31   0   0 springMVCspring
  TEZNKK3IfmPf   2023年11月14日   31   0   0 springMVC
TEZNKK3IfmPf