掌握Spring MVC拦截器整合技巧,实现灵活的请求处理与权限控制!
拦截器
- 1.1 拦截器概念
- 1.2 拦截器入门案例
- 1.2.1 环境准备
- 1.2.2 拦截器开发
- 步骤1:创建拦截器类
- 步骤2:配置拦截器类
- 步骤3:SpringMVC添加SpringMvcSupport包扫描
- 步骤4:运行程序测试
- 步骤5:修改拦截器拦截规则
- 步骤6:简化SpringMvcSupport的编写
- 1.3 拦截器参数
- 1.3.1 前置处理方法
- 1.3.2 后置处理方法
- 1.3.3 完成处理方法
- 1.4 拦截器链配置
- 1.4.1 配置多个拦截器
- 步骤1:创建拦截器类
- 步骤2:配置拦截器类
1.1 拦截器概念

(1)浏览器发送一个请求会先到Tomcat的web服务器。
(2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源。
(3)如果是静态资源,会直接到Tomcat的项目部署目录下去直接访问。
(4)如果是动态资源,就需要交给项目的后台代码进行处理。
(5)在找到具体的方法之前,我们可以去配置过滤器(可以配置多个),按照顺序进行执行。
(6)然后进入到到中央处理器,SpringMVC会根据配置的规则进行拦截。
(7)如果满足规则,则进行处理,找到其对应的controller类中的方法进行执行,完成后返回结果。
(8)如果不满足规则,则不进行处理。
(9)这个时候,如果我们需要在每个Controller方法执行的前后添加业务,具体该如何来实现?
这个就是拦截器要做的事。
- 拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
- 作用:
- 在指定的方法调用前后执行预先设定的代码。
- 阻止原始方法的执行。
- 总结:拦截器就是用来做增强。
看完以后,大家会发现
- 拦截器和过滤器在作用和执行顺序上也很相似。
所以这个时候,就有一个问题需要思考:拦截器和过滤器之间的区别是什么?
- 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术。
- 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。

1.2 拦截器入门案例
1.2.1 环境准备
-
创建一个Web的Maven项目
-
pom.xml添加SSM整合所需jar包
-
创建对应的配置类
-
创建模型类Book
-
编写Controller
@RestController @RequestMapping("/books") public class BookController {@PostMappingpublic String save(@RequestBody Book book){System.out.println("book save..." + book);return "{'module':'book save'}";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id){System.out.println("book delete..." + id);return "{'module':'book delete'}";}@PutMappingpublic String update(@RequestBody Book book){System.out.println("book update..."+book);return "{'module':'book update'}";}@GetMapping("/{id}")public String getById(@PathVariable Integer id){System.out.println("book getById..."+id);return "{'module':'book getById'}";}@GetMappingpublic String getAll(){System.out.println("book getAll...");return "{'module':'book getAll'}";} }
1.2.2 拦截器开发
步骤1:创建拦截器类
让类实现HandlerInterceptor接口,重写接口中的三个方法。
@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {@Override//原始方法调用前执行的内容public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...");return true;}@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...");}
}
注意:拦截器类要被SpringMVC容器扫描到。
步骤2:配置拦截器类
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books" );}
}
步骤3:SpringMVC添加SpringMvcSupport包扫描
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig{}
步骤4:运行程序测试
使用PostMan发送http://localhost/books

如果发送http://localhost/books/100会发现拦截器没有被执行,原因是拦截器的addPathPatterns方法配置的拦截路径是/books,我们现在发送的是/books/100,所以没有匹配上,因此没有拦截,拦截器就不会执行。
步骤5:修改拦截器拦截规则
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*" );}
}
这个时候,如果再次访问http://localhost/books/100,拦截器就会被执行。
拦截器中的preHandler方法,如果返回true,则代表放行,会执行原始Controller类中要请求的方法,如果返回false,则代表拦截,后面的就不会再执行了。
步骤6:简化SpringMvcSupport的编写
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}
}
此后咱们就不用再写SpringMvcSupport类了。
最后我们来看下拦截器的执行流程:

当有拦截器后,请求会先进入preHandle方法,
如果方法返回true,则放行继续执行后面的handle[controller的方法]和后面的方法。
如果返回false,则直接跳过后面方法的执行。
1.3 拦截器参数
1.3.1 前置处理方法
原始方法之前运行preHandle
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {System.out.println("preHandle");return true;
}
- request:请求对象
- response:响应对象
- handler:被调用的处理器对象,本质上是一个方法对象,对反射中的Method对象进行了再包装
使用request对象可以获取请求数据中的内容,如获取请求头的Content-Type
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contentType = request.getHeader("Content-Type");System.out.println("preHandle..."+contentType);return true;
}
使用handler参数,可以获取方法的相关信息
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod hm = (HandlerMethod)handler;String methodName = hm.getMethod().getName();//可以获取方法的名称System.out.println("preHandle..."+methodName);return true;
}
1.3.2 后置处理方法
原始方法运行后运行,如果原始方法被拦截,则不执行
public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {System.out.println("postHandle");
}
前三个参数和上面的是一致的。
modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整
因为咱们现在都是返回json数据,所以该参数的使用率不高。
1.3.3 完成处理方法
拦截器最后执行的方法,无论原始方法是否执行
public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {System.out.println("afterCompletion");
}
前三个参数与上面的是一致的。
ex:如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理。
因为我们现在已经有全局异常处理器类,所以该参数的使用率也不高。
这三个方法中,最常用的是preHandle,在这个方法中可以通过返回值来决定是否要进行放行,我们可以把业务逻辑放在该方法中,如果满足业务则返回true放行,不满足则返回false拦截。
1.4 拦截器链配置
目前,我们在项目中只添加了一个拦截器,如果有多个,该如何配置?配置多个后,执行顺序是什么?
1.4.1 配置多个拦截器
步骤1:创建拦截器类
实现接口,并重写接口中的方法
@Component
public class ProjectInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle...222");return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...222");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...222");}
}
步骤2:配置拦截器类
@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Autowiredprivate ProjectInterceptor2 projectInterceptor2;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");}
}
步骤3:运行程序,观察顺序

拦截器执行的顺序是和配置顺序有关,先进后出。
- 当配置多个拦截器时,形成拦截器链。
- 拦截器链的运行顺序参照拦截器添加顺序为准。
- 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行。
- 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作。

preHandle:与配置顺序相同,必定运行
postHandle:与配置顺序相反,可能不运行
afterCompletion:与配置顺序相反,可能不运行。
这个顺序不太好记,最终只需要把握住一个原则即可:以最终的运行结果为准。
后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹
相关文章:
掌握Spring MVC拦截器整合技巧,实现灵活的请求处理与权限控制!
拦截器 1.1 拦截器概念1.2 拦截器入门案例1.2.1 环境准备1.2.2 拦截器开发步骤1:创建拦截器类步骤2:配置拦截器类步骤3:SpringMVC添加SpringMvcSupport包扫描步骤4:运行程序测试步骤5:修改拦截器拦截规则步骤6:简化SpringMvcSupport的编写 1.3 拦截器参数1.3.1 前置处理方法1.3…...
使用xbindkeys设置鼠标侧键
1.安装如下包 sudo apt install xbindkeys xautomation 2.生成配置文件 xbindkeys --defaults > $HOME/.xbindkeysrc 3.确定侧键键号 在终端执行下面的代码: xev | grep button 此时会出现如下窗口,将鼠标指针移动到这个窗口上: 单…...
跨站点请求伪造攻击 - Cross Site Request Forgery (CSRF)
什么是CSRF 最好理解CSRF攻击的方式是看一个具体的例子。 假设你的银行网站提供一个表单,允许当前登录用户将钱转账到另一个银行账户。例如,转账表单可能如下所示: <form method="post"action="/transfer"> <...
PLAN B KRYPTO ASSETS GMBH CO. KG 普兰资产管理公司
引领加密技术不断演进 PLAN B KRYPTO ASSETS普兰资产管理以其独创的「Trident Strategy三叉戟模型」技术为基础,持续推动加密技术的发展,打造 Schutz(舒茨盾) AI 金融隐私匿名公链。致力于提供高效的技术服务,基于机构…...
java接口和多态
1.接口 1.1黑马信息管理系统集合改进 (应用) 使用数组容器的弊端 容器长度是固定的,不能根据添加功能自动增长 没有提供用于赠删改查的方法 优化步骤 创建新的StudentDao类,OtherStudentDao 创建ArrayList集合容器对象 OtherStudentDao中的方法声明…...
C# 图解教程 第5版 —— 第22章 命名空间和程序集
文章目录 22.1 引用其他程序集22.2 命名空间22.2.1 命名空间名称22.2.2 命名空间的补充22.2.3 命名空间跨文件伸展22.2.4 嵌套命名空间 22.3 using 指令22.3.1 using 命名空间指令22.3.2 using 别名指令22.3.3 using static 指令 22.4 程序集的结构22.5 程序集标识符22.6 强命名…...
【Maven】008-Maven 私服搭建与使用
【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步:请求本地仓库第二步:请求 Maven 私服第三步:请求外部远程仓库(远程中央仓库等)…...
TMDB电影数据分析(下)
TMDB电影数据分析(下) 本文对源自Kaggle TMDB电影数据集进行分析影响电影票房的因素,数据分析流程包含数据集概分析、数据清洗、数据统计以及分析影响电影票房的因素。影响票房因素可能是电影预算、电影类型、电影时长、受欢迎程度、电影评分…...
django后台手机号加密存储
需求: 1 :员工在填写用户的手机号时,直接填写,在django后台中输入 2:当员工在后台确认要存储到数据库时,后台将会把手机号进行加密存储,当数据库被黑之后,手机号字段为加密字符 3&am…...
三、Qt Creator 使用
关于Qt的安装及环境配置,在我的上一篇《二、QT下载、安装及问题解决(windows系统)》已经讲过了。 本章节有一个重点,在新建 工程文件时,所在路径不要有中文,否则编译及运行程序不能正常运行。 在使用Qt Creator(以下…...
css 边框渐变
需求: 普通的div 边框不好看,做一个渐变色 进程: 最简单的当然是做一个内部是白色的边框是渐变色的图,然后使用 background: url("back.jpg"),这样看起来就像是做了一个渐变的边框如果做不了图࿰…...
SofaMQ一些常用的API
SofaMQ的十五种常用的API 引言 SofaMQ作为阿里巴巴开源的消息中间件,提供了丰富的API以支持各种消息传递场景。在本文中,我们将介绍SofaMQ的十五种常用API,并通过实例演示其用法。 1. Producer相关API 1.1 SofaMQProducer SofaMQProduce…...
IIS 缓存, 更新后前端资源不能更新问题
解决办法: 通常只需要index.html 不缓存即可, 其他文件都是根据index.html 中的引用去加载; 正确的做法是在 站点下增加 web.config 文件, 内容如下: 我这个是因为目录下有个config.js 配置文件, 也不能缓存, 所以加了两个 <?xml version"1.0" encoding&quo…...
中科院罗小舟团队提出 UniKP 框架,大模型 + 机器学习高精度预测酶动力学参数
作者:李宝珠 编辑:三羊 中国科学院深圳先进技术研究院罗小舟团队提出了,基于酶动力学参数预测框架 (UniKP),实现多种不同的酶动力学参数的预测。 众所周知,生物体内的新陈代谢是通过各种各样的化学反应来实现的。这…...
组件中写选项的顺序(vue的问题)
为什么选项要有统一的书写顺序呢?很简单,就是要将选择和认知成本最小化。 副作用 (触发组件外的影响) el全局感知 (要求组件以外的知识) nameparent组件类型 (更改组件的类型) functional模板修改器 (改变模板的编译方式) delimiterscomments模板依赖 (…...
LUA 对象转excel
1. 首先把LUA 转成JSON 对象 因为是excel, 所以第一层要是数组,否则没有什么意义,即lua对象要是一个数组比较合理。这里使用开源的json.lua, 但是开源的,对于数字作下标的,或者是一个数组里,不同类型的key…...
深入理解 Flink(八)Flink Task 部署初始化和启动详解
JobMaster 部署 Task 核心入口: JobMaster.onStart();部署 Task 链条:JobMaster --> DefaultScheduler --> SchedulingStrategy --> ExecutionVertex --> Execution --> RPC请求 --> TaskExecutor TaskExecutor 处理 JobMaster 的 …...
openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c
文章目录 openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c概述笔记END openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_DSA_paramfromdata.c 概述 开源工程包含的头文件类型是.inc, 要重命名为.h, 否则没有c头文件语法提示 从数组中载入大数p,q,g 建立ossl…...
【k8s】Kubernetes技术和相关命令简介
一、 Kubernetes简介 Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。kubernetes,简称K8s࿰…...
清晰光谱空间:全自动可调波长系统的高光谱成像优势
高光谱成像技术 高光谱成像技术是一种捕获和分析宽波长信息的技术,能够对材料和特征进行详细的光谱分析和识别。高光谱成像技术的实现通过高光谱相机,其工作原理是使用多个光学传感器或光学滤波器分离不同波长的光,并捕获每个波段的图像&…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
