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---拦截器「建议收藏」

 

 

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • NPOI导出Excel并下载到客户端

    NPOI导出Excel并下载到客户端利用NPOI导出Excel,把Excel发送到客户端

  • 51单片机最小系统解读

    51单片机最小系统解读提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、51单片机最小系统模块构成二、电源电路1.电源引脚三、时钟电路1.外部晶振引脚2.晶振(时钟电路)3.时钟电路小tips四、复位电路1.按键复位2.上电复位总结前言在学习51单片机的时候我们最先接触到的就是单片机最小系统,单片机最小系统又叫最小应用系统,顾名思义就是能够使单片机实现简单运行的最少原件的组合。提示:以下将以51单片机最小系统为例进行介绍一、51单片机最小系统模块构成二、电源电路一个系统的

  • Admin组件

    Django提供了admin组件为项目提供基本的管理后台功能(对数据表的增删改查)。本篇文章通过对admin源码简单分析admin内部原理,扩展使用方式,为以后进行定制和自己开发组件做铺垫

  • AVA测试框架内部的Promise异步流程控制模型

    AVA测试框架内部的Promise异步流程控制模型作者:肖磊个人主页:github最近将内部测试框架的底层库从mocha迁移到了AVA,迁移的原因之一是因为AVA提供了更好的流程控制。我们从一个例子开始入手:有A,B,C,D4个case,我要实现A–>>B–>>(C|D),A最先执行,B等待A执行完再执行,最后是(C|D)并发执行,使用ava提供的API来完成case就是:constava…

    2022年10月31日
  • jps详解

        首先jps的目录在java中,如下图所示。jps主要用于查看java进程,在查看hdfs的启动进程时可以代替ps-ef|grephdfs命令。    在讨论jps时,我们可以把用户切换到root用户下,然后jps查看进程,会出现以下问题,如下图所示,显示进程信息不可用(processinformationunavailale)  在企业中,若进程不可用,先用ps-ef…

  • c语言return x_没有return

    c语言return x_没有returnint GetX() const;int 表示函数返回值为复int型;()为空表示该函数不需要参数制;const 表示该函数不修改百任何值;加起来就是:定义一个返回值类型为度 int 参数为void 名为GetX 的常知函数;类的常对象只道能调用这种常成员函数。const修饰知变量的时候,表示该变量是常量,也就是不可以改变的变量。当const放在成员函道数”尾巴”上修饰成员函数时,则…

发表回复

您的电子邮箱地址不会被公开。

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