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)
上一篇 2022年7月1日 上午9:36
下一篇 2022年7月1日 上午9:46


相关推荐

  • jstorm安装配置

    jstorm安装配置jstorm 安装配置前言下载配置启动前言 jstorm 介绍 jstormJStorm 是一个类似 HadoopMapRed 的系统 用户按照指定的接口实现一个任务 然后将这个任务递交给 JStorm 系统 Jstorm 将这个任务跑起来 并且按 7 24 小时运行起来 一旦中间一个 Worker 发生意外故障 调度器立即分配一个新的 Worker 替换这个失效的 Worker 因此 从应

    2026年3月20日
    1
  • Anaconda python3.6版本安装[通俗易懂]

    Anaconda python3.6版本安装[通俗易懂]官方地址在下面,3.6的对应的是Anaconda3-5.2,5.3以后的都是python3.7的不要看错了往下滑动就是了官方地址:https://repo.anaconda.com/archive/清华大学镜像:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/…

    2022年6月6日
    147
  • 豆包大模型为什么取消联网搜索按钮?

    豆包大模型为什么取消联网搜索按钮?

    2026年3月12日
    4
  • win开启审计功能_windows文件共享审计功能开启

    win开启审计功能_windows文件共享审计功能开启Windowsserver2003的DC也是支持开启审计功能的,步骤如下:1.在DC上打开“ActiveDirectoryUsersandComputer”。2.在“View”菜单上,单击“Advance”。3.右键单击“DC”,然后单击“properties”。4.单击“GroupPolicy”选项卡,单击“DefaultdomainControllerPolicy”,然后…

    2022年5月13日
    138
  • 局域网vlan配置步骤_局域网vlan划分案例

    局域网vlan配置步骤_局域网vlan划分案例计算机网络技术的发展犹如戏剧舞台,你方唱罢我登台。从传统的以太网(10Mb/s)发展到快速以太网(100Mb/s)和千兆以太网(1000Mb/s)也不过几年的时间,其迅猛的势头实在令人吃惊。而现在中大型规模网络建设中,以千兆三层交换机为核心的所谓“千兆主干跑、百兆到桌面”的主流网络模型已不胜枚举。现在,网络业界对“三层交换”和VLAN这两词已经不感到陌生了。一、什么是三…

    2026年1月21日
    2
  • java类中serialVersionUID的作用

    java类中serialVersionUID的作用原文出处 https www cnblogs com duanxz p 3511695 html 实现 Serializable 接口的目的是为类可持久化 比如在网络传输或本地存储 为系统的分布和异构部署提供先决条件 若没有序列化 现在我们所熟悉的远程调用 对象数据库都不可能存在 serialVersio 适用于 java 序列化机制 简单来说 JAVA 序列化的机制是通过判断类的 serialVer

    2026年3月26日
    2

发表回复

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

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