【SpringMVC】深入解析自定义拦截器、注册配置拦截器、拦截路径方法及常见拦截路径、排除拦截路径、拦截器的执行流程



拦截器
上个章节我们完成了强制登录的功能, 后端程序根据Session来判断用户是否登录, 但是实现方法是比较麻烦的:
- 需要修改每个接口的处理逻辑
- 需要修改每个接口的返回结果
- 接口定义修改, 前端代码也需要跟着修改
有没有更简单的办法, 统一拦截所有的请求, 并进行Session校验呢, 这里我们学习一种新的解决办法: 拦截器
什么是拦截器?
拦截器是Spring框架提供的核心功能之一,主要用来拦截用户的请求, 在指定方法(目标方法)前后, 根据业务需要执行预先设定的代码.
也就是说, 允许开发人员提前预定义一些逻辑, 在用户的请求响应前后执行. 也可以在用户请求前阻止其执行.
在拦截器当中,开发人员可以在应用程序中做一些通用性的操作;
比如通过拦截器来拦截前端发来的请求, 判断Session中是否有登录用户的信息. 如果有就可以放行, 如果没有就进行拦截.

拦截器的基本使用
拦截器的使用步骤分为两步:
- 定义拦截器
- 注册配置拦截器
自定义拦截器
自定义拦截器:实现HandlerInterceptor接口,并重写其所有方法



重写完上面三个方法,我们就已经定义好了拦截器,接下来,我们需要定义拦截器需要完成的工作:



preHandle():- 目标方法
执行前执行. - 返回true: 继续执行后续操作; 返回false: 中断后续操作.
- 目标方法
postHandle():- 目标方法
执行后执行
- 目标方法
afterCompletion():- 视图渲染完毕后执行,最后执行(后端开发现在几乎不涉及视图, 暂不了解)
使用addInterceptors( )注册配置拦截器
注册配置拦截器:实现WebMvcConfigurer接口,并重写addInterceptors方法
实现WebMvcConfigurer接口:

重写addInterceptors方法 :

创建一个拦截器对象:

创建一个拦截器对象还是太吃操作了,煮啵,有没有更简单好用的方法推荐一下呢?
有的兄弟,有的!我们已经学过了 SpringIoC 和 DI,也就是依赖管理与依赖注入,能否把创建拦截器对象这个操作,交由 Spring 进行,而不用我们自己手动创建呢?

思考,比起手动创建对象,使用 Spring 帮我们管理对象,并且使用 DI 依赖注入,这样操作有什么优点呢?
【Spring DI】深入解析依赖注入 DI:搭配类注解通过 @Autowired 注解完成属性注入、构造方法注入、Setter 注入方法和三种注入方法的优缺点分析-CSDN博客
将 loginInterceptor 注册到 Spring MVC 的拦截器链中,并配置其拦截的请求路径规则

拦截器使用细节
拦截器的入门程序完成之后,接下来我们来介绍拦截器的使用细节。拦截器的使用细节我们主要介绍两个部分:
- 拦截器的拦截路径配置
- 拦截器实现原理
拦截路径
拦截路径是指我们定义的这个拦截器, 对哪些请求生效.
我们在注册配置拦截器的时候, 通过addPathPatterns()方法指定要拦截哪些请求.
也可以通过excludePathPatterns()指定不拦截哪些请求.
上述代码中, 我们配置的是
/**, 表示拦截所有的请求.
比如用户登录校验, 我们希望可以对除了登录之外所有的路径生效.

启动服务,注意观察构造请求前后日志变化:

使用 postman 访问任意请求:

观察后端日志 ,此时的目标方法是 login 接口:

可以看到, preHandle方法执行之后就放行了, 开始执行目标方法
目标方法执行完成之后执行postHandle和afterCompletion方法.
我们把拦截器中preHandle方法的返回值改为false:

再观察运行结果

可以看到, 拦截器拦截了请求, 没有进行响应.
我们对所有路径进行拦截,程序启动程序,使用 Postman 构造请求:

我们看看日志中执行的 SQL

常见拦截路径设置
在拦截器中除了可以设置/**拦截所有资源外,还有一些常见拦截路径设置:

以上拦截规则可以拦截此项目中的使用URL,包括静态文件(图图片文件, JS 和 CSS 等文件).
拦截器执行流程
正常的调用顺序:

有了拦截器之后,会在调用Controller之前进行相应的业务处理,执行的流程如下图

- 添加拦截器后, 执行
Controller的方法之前, 请求会先被拦截器拦截住. - 执行preHandle()方法, 这个方法需要返回一个布尔类型的值.
- 如果返回true, 就表示放行本次操作, 继续访问controller中的方法.
- 如果返回false,则不会放行(controller中的方法也不会执行).
- controller当中的方法执行完毕后,再回过来执行
postHandle()这个方法以及afterCompletion()方法 - 执行完毕之后,最终给浏览器响应数据.
排除拦截路径

registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/css/**", "/login"); // 排除静态资源和登录页registry.addInterceptor(loginInterceptor).addPathPatterns("/api/**") // 拦截所有 /api/ 开头的请求.excludePathPatterns("/api/login"); // 排除 /api/login 路径
excludePathPatterns( )的源码解读及排除拦截页面的方法
完整的背景在这篇博客下面,这里单独提取排除拦截页面请求的方法
图书管理系统:基于拦截器完成登录校验功能
我们来看下面的注册配置拦截器 WebConfig 中 addInterceptors() 的逻辑:

excludePathPatterns( )的源码解读
接下来,我们修改注册配置拦截器拦截的页面,排除拦截页面需要用到的方法是 excludePathPatterns()
对于excludePathPatterns(),可以传集合,也可以传字符串:

分别表示的排除拦截页面的方法:
硬编码排除:- 链式调用多个
excludePathPatterns(),来排除多个页面请求; - 适合路径较少且固定的情况,代码直观。
- 链式调用多个
动态排除:- 把要排除的页面设置成集合,使用一个
excludePathPatterns()排除集合中的所有页面请求; - 适合路径较多或可能动态变化的情况,便于维护和扩展。
- 把要排除的页面设置成集合,使用一个
方法一:硬编码排除
@Configuration
public class WebConfig implements WebMvcConfigurer {// 自定义的拦截器对象@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // 设置拦截器拦截的请求路径(/**表示拦截所有请求).excludePathPatterns("/user/login") // 设置拦截器排除拦截的路径.excludePathPatterns("/**/*.js") // 排除前端静态资源.excludePathPatterns("/**/*.css").excludePathPatterns("/**/*.png").excludePathPatterns("/**/*.html");}
}
方法二:动态排除
@Configuration
public class WebConfig implements WebMvcConfigurer {// 自定义的拦截器对象@Autowiredprivate LoginInterceptor loginInterceptor;private List<String> excludePaths = Arrays.asList("/user/login","/**/*.js","/**/*.css","/**/*.png","/**/*.html");@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册自定义拦截器对象registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // 设置拦截器拦截的请求路径(/**表示拦截所有请求).excludePathPatterns(excludePaths); // 设置拦截器排除拦截的路径}
}


相关文章:
【SpringMVC】深入解析自定义拦截器、注册配置拦截器、拦截路径方法及常见拦截路径、排除拦截路径、拦截器的执行流程
拦截器 上个章节我们完成了强制登录的功能, 后端程序根据Session来判断用户是否登录, 但是实现方法是比较麻烦的: 需要修改每个接口的处理逻辑需要修改每个接口的返回结果接口定义修改, 前端代码也需要跟着修改 有没有更简单的办法, 统一拦截所有的请求, 并进行Se…...
基于VS Code 为核心平台的python语言智能体开发平台搭建
以下是基于 VS Code 为核心平台,整合 Node-RED、Gradio、Docker Desktop 的智能体可视化开发平台优化方案,聚焦工具链深度集成与开发效率提升: 一、核心架构设计 #mermaid-svg-f8l9kYPAlJ2TlpGF {font-family:"trebuchet ms",verd…...
使用最新threejs复刻经典贪吃蛇游戏的3D版,附完整源码
基类Entity 建立基类Entity,实现投影能力、动画入场效果(从小变大的弹性动画)、计算自己在地图格位置的方法。 // 导入gsap动画库(用于创建补间动画) import gsap from gsap// 定义Entity基类 export default class …...
论坛测试报告
作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 🎂 作者介绍: 🎂🎂 🎂 🎉🎉🎉…...
IPMI 与 Redfish API简介
--- ### **IPMI 与 Redfish API 详解** #### **1. IPMI(智能平台管理接口)** **简介** IPMI(Intelligent Platform Management Interface)是一种硬件级别的带外管理标准,允许管理员通过独立于操作系统的网络通道(BMC)监控和管理服务器硬件,即使主机已关机或操作系…...
zset.
zset 有序集合 zset 保留了 set 不能有重复元素的特点 zset 中的每个元素都有一个唯一的浮点类型的分数(score)与之关联,使得 zset 内部的元素是可以维护有序性的。但是这个有序不是用下标作为排序依据的,而是根据分数…...
Windows 部署 DeepSeek 详细教程
一、准备工作 系统要求: 建议Windows 10 22H2 或更高版本,家庭版或专业版上网环境: 建议科学上网,国内访问部分网站会很慢设备要求: 内存8G以上、关闭防火墙 二、安装Ollama 官网链接: https://ollama.com/downloadg…...
过去十年前端框架演变与技术驱动因素剖析
一、技术演进脉络(2013-2023) 2013-2015:结构化需求催生框架雏形 早期的jQuery虽然解决了跨浏览器兼容性问题(如IE8兼容性处理),但其松散的代码组织方式难以支撑复杂应用开发。Backbone.js的出现首次引入M…...
从零开始学A2A一:A2A 协议的高级应用与优化
A2A 协议的高级应用与优化 学习目标 掌握 A2A 高级功能 理解多用户支持机制掌握长期任务管理方法学习服务性能优化技巧 理解与 MCP 的差异 分析多智能体场景下的优势掌握不同场景的选择策略 第一部分:多用户支持机制 1. 用户隔离架构 #mermaid-svg-Awx5UVYtqOF…...
#Linux动态大小裁剪以及包大小变大排查思路
1 动态库裁剪 库分为动态库和静态库,动态库是在程序运行时才加载,静态库是在编译时就加载到程序中。动态库的大小通常比静态库小,因为动态库只包含了程序需要的函数和数据,而静态库则包含了所有的函数和数据。静态库可以理解为引入…...
基于微信小程序的中医小妙招系统的设计与实现
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…...
sqlite3的API以及命令行
sqlite是目前最流行的嵌入式数据库。 所谓嵌入式,就是足够简单,可以嵌入到我们自己开发的应用程序之中。 在Linux系统中,sqlite的使用只需要使用它的API,连接它的动态连接库,甚至都不用连接,sqlite的实现…...
css button 点击效果
<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>button点击效果</title><style>#container {display: flex;align-items: center;justify-content: center;}.pushable {position: relat…...
表征流体作用力的参数及其特性
在圆柱绕流研究中,这些参数分别表征流体作用力的关键特性,以下是详细解析: 📊 参数物理意义及工程应用 符号名称物理意义典型值范围(参考)工程意义 C d m a x C_{dmax} Cdmax最大阻力系数瞬时阻力系数&a…...
Foundation Agent:深度赋能AI4DATA
2025年5月17日,第76期DataFunSummit:AI Agent技术与应用峰会将在DataFun线上社区举办。Manus的爆火并非偶然,随着基础模型效果不断的提升,Agent作为大模型的超级应用备受全世界的关注。为了推动其技术和应用,本次峰会计…...
Docker--Docker镜像原理
docker 是操作系统层的虚拟化,所以 docker 镜像的本质是在模拟操作系统。 联合文件系统(UnionFS) 联合文件系统(UnionFS) 是Docker镜像实现分层存储的核心技术,它通过将多个只读层(Image Laye…...
SpringAI+DeepSeek大模型应用开发——2 大模型应用开发架构
目录 2.大模型开发 2.1 模型部署 2.1.1 云服务-开放大模型API 2.1.2 本地部署 搜索模型 运行大模型 2.2 调用大模型 接口说明 提示词角色 编辑 会话记忆问题 2.3 大模型应用开发架构 2.3.1 技术架构 纯Prompt模式 FunctionCalling RAG检索增强 Fine-tuning …...
Transformer 架构 - 编码器 (Transformer Architecture - Encoder)
1.Transformer 编码器整体结构 Transformer 编码器的结构相对直观:它由 N 个完全相同的编码器层 (Encoder Layer) 堆叠而成。 图1: Transformer 编码器整体结构示意图 (简化) 输入序列(例如,通过 embedding 层转换后的词向量)首先会加上位置编码,然后传入第一个编码器层…...
2.2/Q2,Charls最新文章解读
文章题目:Association of uric acid to high-density lipoprotein cholesterol ratio with the presence or absence of hypertensive kidney function: results from the China Health and Retirement Longitudinal Study (CHARLS) DOI:10.1186/s12882-…...
下拉框select标签类型
在我们很多页面里有下拉框的选择,这种元素怎么定位呢?下拉框分为两种类型:我们分别针对这两种元素进行定位和操作 select标签 : 通过select类处理。 非select标签 1、针对下拉框元素,如果是Select标签类型,…...
CentOS 7 linux系统从无到有部署项目
环境部署操作手册 一、Maven安装与配置 1. 下载与解压 下载地址:https://maven.apache.org/download.cgi?spm5238cd80.38b417da.0.0.d54c32cbnOpQh2&filedownload.cgi上传并解压解压命令: tar -zxvf apache-maven-3.9.9-bin.tar.gz -C /usr/loc…...
李飞飞团队新作WorldScore:“世界生成”能力迎来统一评测,3D/4D/视频模型同台PK
从古老神话中对世界起源的幻想,到如今科学家们在实验室里对虚拟世界的构建,人类探索世界生成奥秘的脚步从未停歇。如今,随着人工智能和计算机图形学的深度融合,我们已站在一个全新的起点,能够以前所未有的精度和效率去…...
如何在米尔-STM32MP257开发板上部署环境监测系统
本文将介绍基于米尔电子MYD-LD25X开发板(米尔基于STM35MP257开发板)的环境监测系统方案测试。 摘自优秀创作者-lugl4313820 一、前言 环境监测是当前很多场景需要的项目,刚好我正在论坛参与的一个项目:Thingy:91X 蜂窝物联网原型…...
MySQL之SQL优化
目录 1.插入数据 2.大批量插入数据 3.order by优化 4.group by优化 5.limit优化 6.count优化 count用法 7.update优化 1.插入数据 如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化 第一个:批量插入数据 Insert into tb_test va…...
python_level1.2
目录 一、变量 例如:小正方形——>大正方形 【1】第一次使用这个变量,所以说:定义一个变量length; 【2】:是赋值符号,不是等于符号。(只有赋值,该变量才会被创建)…...
Linux、Kylin OS挂载磁盘,开机自动加载
0.实验环境: 1.确定挂载目录,如果没有使用mkdir 进行创建: mkdir /data 2.查看磁盘 lsblk #列出所有可用的块设备df -T #查看磁盘文件系统类型 3.格式化成xfs文件系统 (这里以xfs为例,ext4类似) mkfs.xfs /dev/vdb 4.挂载到…...
FPGA-VGA
目录 前言 一、VGA是什么? 二、物理接口 三、VGA显示原理 四、VGA时序标准 五、VGA显示参数 六、模块设计 七、波形图设计 八、彩条波形数据 前言 VGA的FPGA驱动 一、VGA是什么? VGA(Video Graphics Array)是IBM于1987年推出的…...
java的lambda和stream流操作
Lambda 表达式 ≈ 匿名函数 (Lambda接口)函数式接口:传入Lambda表达作为函数式接口的参数 函数式接口 只能有一个抽象方法的接口 Lambda 表达式必须赋值给一个函数式接口,比如 Java 8 自带的: 接口名 作用 Functio…...
【嵌入式】【阿里云服务器】【树莓派】学习守护进程编程、gdb调试原理和内网穿透信息
目录 一. 守护进程的含义及编程实现的主要过程 1.1守护进程 1.2编程实现的主要过程 二、在树莓派中通过三种方式创建守护进程 2.1nohup命令创建 2.2fork()函数创建 2.3daemon()函数创建 三、在阿里云中通过三种方式创建守护进程 3.1nohup命令创建 3.2fork()函数创建 …...
数据结构学习笔记 :树与二叉树详解
目录 树的基本概念二叉树的定义与特性二叉树的存储结构 3.1 顺序存储 3.2 链式存储二叉树遍历特殊二叉树类型总结与应用场景 一、树的基本概念 核心定义 树:由根节点和若干子树构成的层次结构。叶子节点(终端节点):没有子节点的…...
