当前位置: 首页 > news >正文

13SpringMVC中拦截器的配置(拦截规则)和多个拦截器的preHandle,postHandle执行顺序原理详解

拦截器

Servlet中的过滤器的实现及其原理,参考文章

配置一个拦截器

SpringMVC中请求的处理流程: 用户请求—>listener—>filter—>DispatcherServlet—>filter—>preHandle—>controller—>postHandle

第一步: 编写一个Java类实现HandlerInterceptor(HandlerInterceptorAdapter已过时)接口,由于接口中的方法都有默认的方法体,我们可以根据需求实现方法

方法名功能
boolean preHandle(processedRequest, response)在控制器方法执行之前执行 , 返回true表示放行即调用控制器方法 , 返回false表示拦截即不调用控制器方法
postHandle(processedRequest, response, mv)在控制器方法执行之后执行
afterComplation()在控制器方法执行之后,且模型数据都被渲染到视图上后执行
// 将当前bean加入IoC容器,这样就可以在配置文件中引用当前的bean作为拦截器
@Component
public class FirstInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("FirstInterceptor-->preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("FirstInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("FirstInterceptor-->afterCompletion");}
}

第二步: 在SpringMVC的配置文件中将实现了HandlerInterceptor接口的类设置为拦截器并设置拦截的规则

  • 通过ref或bean标签可以设置拦截器但是不能设置拦截规则,此时默认拦截DispatcherServlet处理的所有的请求
  • 通过mvc:interceptor标签可以设置拦截器同时设置拦截的规则即拦截哪些请求或放行哪些请求
  • 使用view-controller标签配置的视图控制器对应的跳转页面的请求只要符合拦截器拦截的规则也会被拦截
标签名描述
bean标签的class属性根据全类名告诉SpringMVC哪个类是拦截器
ref标签的bean属性引用IoC容器中的某个bean的Id作为拦截器,所以需要保证容器中注册了对应的bean
mvc:mapping设置需要拦截的请求路径
/**表示拦截所有请求,/* 表示拦截上下文路径后的一层路径的请求
mvc:exclude-mapping设置排除即不需要拦截的请求路径
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--扫描组件--><context:component-scan base-package="com.atguigu.mvc"></context:component-scan><!--使用view-controller标签配置的视图控制器对应的跳转页面的请求也会被拦截--><mvc:view-controller path="/" view-name="index"></mvc:view-controller><mvc:annotation-driven /><!--配置拦截器--><mvc:interceptors><!--根据全类名将某个类设置为拦截器--><bean class="com.atguigu.mvc.interceptors.FirstInterceptor"></bean><!--引用IoC容器中的某个bean的Id作为拦截器,需要保证容器中注册了对应的bean--><ref bean="firstInterceptor"></ref><!--设置拦截器及拦截的规则--><mvc:interceptor><!--配置需要拦截的请求路径--><mvc:mapping path="/**"/><!--配置不需要拦截的请求路径--><mvc:exclude-mapping path="/"/><!--引用容器中的某个bean作为拦截器--><ref bean="firstInterceptor"></ref></mvc:interceptor></mvc:interceptors>
</beans>

第三步: 编写处理请求的控制器方法,测试拦截器方法的执行顺序,只要请求符合拦截的规则,拦截器中重写的方法就一定会执行,无论有没有匹配请求的控制器方法

<a th:href="@{/testInterceptor}">测试拦截器</a>
@Controller
public class TestController {@RequestMapping("/testInterceptor")@ResponseBodypublic String testInterceptor(){return "success";}
}
FirstInterceptor-->preHandle
success
FirstInterceptor-->postHandle
FirstInterceptor-->afterCompletion

配置多个拦截器

多个拦截器的执行顺序和在SpringMVC的配置文件的中配置的拦截器顺序以及拦截器的preHandle()方法的返回值有关

在这里插入图片描述

第一步: 创建一个拦截器类并且preHandle方法的返回值是false

// 将当前bean加入IoC容器,这样就可以在配置文件中引用当前的bean作为拦截器
@Component
public class SecondInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("SecondInterceptor-->preHandle");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("SecondInterceptor-->postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("SecondInterceptor-->afterCompletion");}
}

第二步: 在SpringMVC的配置文件中设置多个拦截器及其拦截规则

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--扫描组件--><context:component-scan base-package="com.atguigu.mvc"></context:component-scan><!--配置视图控制器--><mvc:view-controller path="/" view-name="index"></mvc:view-controller><mvc:annotation-driven /><!--配置拦截器--><mvc:interceptors><ref bean="firstInterceptor"></ref><ref bean="secondInterceptor"></ref></mvc:interceptors>
</beans>

第三步: 编写控制器方法测试多个拦截器中方法的执行顺序

Controller
public class TestController {@RequestMapping("/testInterceptor")@ResponseBodypublic String testInterceptor(){return "success";}
}
FirstInterceptor-->preHandle
SecondInterceptor-->preHandle
success
FirstInterceptor-->afterCompletion

拦截器执行顺序的原理

mappedHandler是控制器执行链,包含控制器方法,拦截器集合(自定义的和SpringMvc提供的),拦截器的索引

正序执行所有拦截器的prehandle方法

if (!mappedHandler.applyPreHandle(processedRequest, response)) {// 如果有一个拦截器的prehandle方法返回fasle,直接终止当前方法即剩下的拦截器和对应控制器的方法都不会执行return;
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {// 遍历拦截器集合中的每一个拦截器for(int i = 0; i < this.interceptorList.size(); i++) {HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);// 判断当前拦截器的prehandle方法的返回值if (!interceptor.preHandle(request, response, this.handler)) {// 如果prehandle方法返回false,调用当前拦截器的afterComplation方法this.triggerAfterCompletion(request, response, (Exception)null);// 返回false后剩下的拦截器和对应控制器的方法都不会执行return false;}// interceptorIndex的值是prehandle方法返回的是false的某个拦截器之前的拦截器的索引this.interceptorIndex = i;}// 返回true后才会执行下一个拦截器或对应控制器的方法return true;
}

反序执行所有拦截器的posthandle方法

mappedHandler.applyPostHandle(processedRequest, response, mv);void applyPostHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {// i的初始值是拦截器集合中的最后一个拦截器的索引for(int i = this.interceptorList.size(); i >= 0; i--) {HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);interceptor.postHandle(request, response, this.handler,mv);    }
}

反序执行所有拦截器的aftercompletion方法

if(mappedHandler != null){mappedHandler.triggerAfterCompletion(request, response, (Exception)null);      
}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response) throws Exception {// i的初始值是最后一个prehandle方法返回的是false的某个拦截器之前的拦截器的索引for(int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);interceptor.afterCompletion(request, response, this.handler,ex);    }
}

相关文章:

13SpringMVC中拦截器的配置(拦截规则)和多个拦截器的preHandle,postHandle执行顺序原理详解

拦截器 Servlet中的过滤器的实现及其原理,参考文章 配置一个拦截器 SpringMVC中请求的处理流程: 用户请求—>listener—>filter—>DispatcherServlet—>filter—>preHandle—>controller—>postHandle 第一步: 编写一个Java类实现HandlerInterceptor(…...

Liunx中系统安全及文件系统(极其粗糙版)

PS&#xff1a;下面知识点还很粗糙下次有时间再改 系统安全&#xff1a; 系统安全和数据防护&#xff0c;数据备份的资质 比如三台服务器&#xff1a; 500万 工信部是有要求的&#xff0c;组织必须保证处理的个人数据的安全性 品牌形象如何维护呢 基于liunx的安全加固措施…...

Java中的数组

前言&#xff1a; 本篇博客将为大家介绍Java中的数组的相关知识。 目录 基本介绍 概念相关 数组的使用 数组是引用类型 应用场景 保存数据 作为方法的参数 作为方法的返回值 练习 数组转字符串 数组拷贝 求数组中元素的平均值 查找数组中的指定元素&#xff08;二…...

Java反射调用jar包实现多态

上一篇实现了反射调用jar包&#xff0c;但是没有实现多态&#xff0c;这次先给自己的jar包类抽象一个接口&#xff0c;然后实现类实现接口。最后调用放反射得到的对像转换成接口类型调用执行。 定义接口&#xff0c;指定包为ZLZJar package ZLZJar;public interface ITest {p…...

PowerBI 一些基础功能

1、PowerBI创建日期表 1.1、Power BI 日期表 - 知乎日期是做数据分析的时候使用最频繁的分析维度&#xff0c;一般建议建立单独的日期维度表&#xff0c;并与事实表的日期字段建立连接。 建立日期维度表可通过DAX函数的方式进行&#xff1a; 日期表 CALENDAR(DATE("2023&…...

Mac用命令行安装Adobe代码字体Source Code Pro

执行命令 brew tap homebrew/cask-fonts && brew cask install font-source-code-pro...

RustDay05------Exercise[31-40]

31.结构体申明 结构体在这里给了三种声明样式 (1)字典样式的键值对(使用花括号) (2)元组样式的数值元组(使用圆括号) (3)空结构体,可以被格式化输出名字 // structs1.rs // Address all the TODOs to make the tests pass! // Execute rustlings hint structs1 or use the…...

wireshark过滤器的简单介绍

wireshark过滤器的简单介绍 Wireshark的过滤器主要分为捕获过滤器和显示过滤器两种&#xff0c;其中捕获过滤器在数据包捕获时起作用&#xff0c;而显示过滤器用于在已捕获的数据包的集合中筛选数据。以下是一些Wireshark过滤器的详细介绍&#xff1a; 捕获过滤器&#xff1a;…...

数据结构:二叉树(1)

目录 树的概念 树的表示形式 二叉树 二叉树的性质 题目 二叉树的存储 链式存储 初始化二叉树 二叉树的遍历 前序遍历&#xff1a;根&#x1f449;左子树&#x1f449;右子树 中序遍历&#xff1a;左子树&#x1f449;根&#x1f449;右子树 后序遍历&#xff1a;左子…...

[nlp] chathome—家居装修垂类大语言模型的开发和评估

ChatHome: Development and Evaluation of a Domain-Specific LanguageModel for Home Renovation ChatHome: 家居装修垂类大语言模型的开发和评估 1、摘要: 我们的方法包括两个步骤:首先,使用广泛的家庭装修数据集(包括专业文章、标准文档和网络内容)对通用模型进行后预训…...

http(下)

http的工作流程&#xff1a; 客户端---服务端通信过程 请求----响应的模型 建立连接&#xff1a;tcp/ip协议与服务器建立连接&#xff08;三次握手&#xff09;&#xff0c;客户端向服务器的80端口发送连接请求 发送请求&#xff1a;一旦连接建立之后&#xff0c;客户端就像…...

Python学习基础笔记七十二——IDE集成开发环境

集成开发环境&#xff0c;英文缩写是IDE。 IDE可以帮你更高效地开发项目代码。因为它提供了非常实用的功能&#xff0c;比如项目文件管理、语法高亮、代码导航、自动补齐代码、语法静态检查、调试、版本控制等等。 两款IDE&#xff1a;Pycharm和VSCode。 pycharm中的代码文件都…...

[MQ]Win平台RocketMQ安装启动

1、下载 官网下载地址&#xff1a;https://rocketmq.apache.org/zh/download 2、解压ZIP包 解压rocketmq-all-x.x.x-bin-release.zip到目录。 比如我解压到了E:\Env\MQ_rocket\rocketmq-all-5.1.4-bin-release 3、配置环境变量 ROCKETMQ_HOME 4、RocketMQ JVM内存配置 这个需要…...

vscode工程屏蔽不使用的文件夹或文件的方法

一. 简介 vscode是一款 微软提供的免费的代码编辑软件。 对于 IMX6ULL-ALPHA开发板而言&#xff0c;NXP官方uboot一定会支持不止 IMX6ULL芯片的代码&#xff0c;也不止支持 一种架构&#xff0c;还支持其他芯片或架构的源码文件。 为了方便阅读代码&#xff0c;vscode软件可…...

黑马JVM总结(三十四)

&#xff08;1&#xff09;JMM概述 &#xff08;2&#xff09;JMM-原子性-synchronized java内存模型是如何保证原子性的呢&#xff0c;它是通过synchroized关键字&#xff0c;来达到这个目的的 第一个线程来了进入同步代码块之后&#xff0c;把这个对象加上锁了&#xff0c;…...

[linux]vncserver常用终端命令合集

开启vnc服务&#xff1a;systemctl start vncserver:1.service 关闭vnc服务&#xff1a;systemctl stop vncserver:1.service 重启vnc服务&#xff1a;systemctl restart vncserver:1.service 设置VNC密码: vncpasswd 开启VNC&#xff1a; vncserver :1 关闭VNC&#xff1…...

亚马逊、eBay,速卖通,国际站买家账号支付异常问题解决方法

如何解决下单被砍、封号问题&#xff0c;建议采取以下措施&#xff1a; 买家账号下单&#xff0c;不单纯只是解决支付卡、IP问题就可以了&#xff0c;因为平台大数据风控点很多&#xff0c; 我们防关联具体要解决几个问题 一&#xff1a;要硬件参数的关联、安全码、地区码、…...

Constitutional AI

用中文以结构树的方式列出这篇讲稿的知识点&#xff1a; Although you can use a reward model to eliminate the need for human evaluation during RLHF fine tuning, the human effort required to produce the trained reward model in the first place is huge. The label…...

TDengine 资深研发整理:基于 SpringBoot 多语言实现 API 返回消息国际化

作为一款在 Java 开发社区中广受欢迎的技术框架&#xff0c;SpringBoot 在开发者和企业的具体实践中应用广泛。具体来说&#xff0c;它是一个用于构建基于 Java 的 Web 应用程序和微服务的框架&#xff0c;通过简化开发流程、提供约定大于配置的原则以及集成大量常用库和组件&a…...

数据结构-冒泡排序Java实现

目录 一、引言二、算法步骤三、原理演示四、代码实战五、结论 一、引言 冒泡排序是一种基础的比较排序算法&#xff0c;它的思想很简单&#xff1a;重复地遍历待排序的元素列表&#xff0c;比较相邻元素&#xff0c;如果它们的顺序不正确&#xff0c;则交换它们。这个过程不断重…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...