SpringMvc—拦截器「建议收藏」

SpringMvc—拦截器「建议收藏」SpringMvc拦截器作用拦截器是用来拦截经过dispatcherServlet【请求控制器】的请求。它用来拦截控制器方法的执行。拦截器通过实现接口HandlerInterceptor并在S

大家好,又见面了,我是你们的朋友全栈君。

SpringMvc—拦截器

作用

拦截器是用来拦截经过dispatcherServlet【请求控制器】的请求。它用来拦截控制器方法的执行。

拦截器通过实现接口HandlerInterceptor并在SpringMvc配置文件中添加配置实现拦截功能。记得为拦截器类加注解把它加到IOC容器中

使用

在拦截器中

首先添加注解,@Component【既不是bean、也不是service、也不是controller,是一个基本java类,所以用它声明,用别的也行】,然后实现接口HandlerInterceptor,实现三个方法

@Component
public class FirstInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor--preHandle--控制器方法执行之前执行");
        return true;
    }
​
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor--postHandle---控制器方法执行之后执行");
    }
​
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor---afterCompletion----视图渲染完毕执行");
    }
}

 

 

在SpringMvc配置文件中

首先添加命名空间mvc、context,开启组件扫描、添加视图解析器thymeleaf、开启mvc注解扫描。

配置文件中的标签的作用注释里都有

    <mvc:interceptors>
<!--使用bean标签注册的拦截器会对经过dispatcherServlet的所有请求进行处理,使用ref也是一样的-->
<!--        <bean class="xlw.com.SpringMvc03.Interceptor.FirstInterceptor"></bean>-->
<!--        <ref bean="firstInterceptor"></ref>-->
<!--        <mvc:interceptor>-->
<!--使用标签mvc:interceptor可以规定那些请求被拦截哪些不被拦截,可以设置多个,最后要对拦截器注册-->
<!--            <mvc:mapping path="/test?"/>-->
<!--            <mvc:exclude-mapping path="/"/>-->
<!--            <mvc:exclude-mapping path="/test1"/>-->
<!--            <ref bean="firstInterceptor"></ref>-->
<!--        </mvc:interceptor>--><ref bean="firstInterceptor"></ref>
        <ref bean="secondInterceptor"></ref></mvc:interceptors>
 

 

多个拦截器(preHandle返回true)

在上面的配置文件中配置两个拦截器,在对请求进行拦截时可以发现方法的执行顺序 有些不同

第二个拦截器

@Component
public class SecondInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SecondInterceptor--preHandle--控制器方法执行之前执行");
        return true;
    }
​
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("SecondInterceptor--postHandle---控制器方法执行之后执行");
    }
​
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("SecondInterceptor---afterCompletion----视图渲染完毕执行");
    }
}

 

 

拦截器处理请求后结果

可以发现,preHandle执行顺序是跟在配置文件的先后注册顺序执行的,postHandle和AfterCompletion是反过来执行的

FirstInterceptor--preHandle--控制器方法执行之前执行
SecondInterceptor--preHandle--控制器方法执行之前执行
SecondInterceptor--postHandle---控制器方法执行之后执行
FirstInterceptor--postHandle---控制器方法执行之后执行
SecondInterceptor---afterCompletion----视图渲染完毕执行
FirstInterceptor---afterCompletion----视图渲染完毕执行

 

在源码中

首先为控制器方法打上断点。debug启动服务器,进入断点模式,然后再debug底下的控制台执行方法找到DispatchServlet的1061,点进去,做好以下断点。

再对断点放行,再次请求资源。开始观察。

第一个断电对应的正是preHandle方法,在if的判断条件中,发现需要一个true的返回值,与感叹号一起使判断条件变成false,才能使程序继续往下执行,否则就会终结当前循环

SpringMvc---拦截器「建议收藏」

 

 

 

点击下一行进入applyPreHandle方法具体执行中,发现有一个++的for循环,里面循环执行一个Interceptor的list数组,可以看见list里面正是SpringMvc自己的interceptor和我自己注册的interceptor,++执行就确保了PreHandle方法按照在配置文件中的顺序执行。

 

在for循环中的if判断,就是判断返回值是不是false,如果是就会执行当前的afterCompletion方法【就是最后执行的那个方法】,并且返回false终结掉DispatcherServlet中的程序执行。如果返回的是true,就会按照在list中的顺序执行

 

 

preHandel执行完后会跳到下一个断点,就是那个mv那一行,进行获取视图名称。再跳到下一个断点就会回到控制器方法,在跳到下一个断点就是那个postHandel方法。

 

来到postHandel的哪一行断点,点击下一行,进入postHandel,发现是一个–的for循环,循环的依旧是那个interceptor的list集合,所以就能知道为什么postHandel的执行顺序和配置文件中的相反。afterCompletion方法的执行也和这个postHandel一样–for循环

 

SpringMvc---拦截器「建议收藏」

 

 

 

 

SpringMvc---拦截器「建议收藏」

 

 

 

多个拦截器(preHandel返回false)

依旧是断点模式,但是是将preHandel返回值变成false。就会发现,在进入applyPreHandel方法中后,先执行第一个注册的interceptor的preHandel方法,执行后再执行第二个拦截器,但是第二个拦截器的返回值被修改为false,就会通过applyPreHandel的for循环中的if判断,中执行第一个interceptor的triggerAfterCompletion并返回false。

再回到Dispatch Servlet中就会通过if判断,执行return,后面的就不执行了。请求被拦截。

 

所以在有多个interceptor被注册后,其中有一个interceptor的preHandel方法的返回值为false,那么在这个拦截器之前注册的拦截器的preHandel方法和afterCompletion方法都会执行,这个拦截器的preHandel方法也会执行。post Handel方法都不执行

 

SpringMvc---拦截器「建议收藏」

 

 

 

 

 

 SpringMvc---拦截器「建议收藏」

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154784.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MySQL日期格式化

    MySQL日期格式化示例date_format(now(),’%Y-%m-%d%H:%i:%S’)点位符详解%Y:年,4位%y:年,2位%M:月名%m:月,数值(00-12)%D:带有英文前缀的月中的天%d:月的天,数值(00-31)%e:月的天,数值(0-31)%H:小时(00-23)%h:小时(01-12)%I:小时(01-12)%i:分钟,数值(00-59)%S:秒(00…

    2022年6月3日
    42
  • vscode插件大全_腾讯视频vip插件

    vscode插件大全_腾讯视频vip插件VSCode最全实用插件(VIP典藏版)

    2022年9月30日
    3
  • 范冰:增长黑客入门训练营

    范冰:增长黑客入门训练营之前刚入门产品的时候,增长的概念已经很流行了,连着读了SeanEllis的《增长黑客:如何低成本实现爆发式成长》和范冰的《增长黑客:创业公司的用户与收入增长秘籍》以及相应的公开课,如果你不知道SeanEllis,那我觉得你应该认真花点时间去了解一下这位“增长黑客之父”了,之前已经分享过SeanEllis的公开课和关于这本书的读书笔记,比较开心的是无意中发现2019年《增长黑客:创业公司的用户与收入增长秘籍》的作者范冰就已经亲自开了这本增长黑客的课程,还是觉得好物不容错过!欢迎要资源,欢迎交流沟通过~

    2022年5月11日
    76
  • MySQL数据库下载_数据库管理数据的特征

    MySQL数据库下载_数据库管理数据的特征官方网站:https://www.adminer.org/下载页面:文件名为adminer-4.7.1-mysql.php将文件放到网站上,访问即可。

    2022年8月2日
    5
  • Git安装配置教程

    Git安装配置教程1.Git简介Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理1。Git是LinusTorvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。2.Git工作示意图3.Windows下安装Git3.1Git下载下载地址:https://git-for-windows.github.io/下载有时候很慢,请耐心

    2022年5月10日
    30
  • mac 安装ll命令[通俗易懂]

    mac 安装ll命令[通俗易懂]mac安装ll命令mac-bash:ll:commandnotfound在linux系统下我们经常使用ll、la命令。但在mac系统时缺没有。提示:-bash:ll:commandnotfound。这是因为ll、la不是真的命令,而是一些常用命令和参数搭配的别名。所以我们在MacOS下配置下就好了。1、跳到个人目录下面localhost:~huangfy20$cdlocalhost:~huangfy20$pwd/Users/huangfy202、打开.bash

    2025年12月1日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号