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

Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程

Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程


目录

  1. 概述
    • 什么是拦截器(Interceptor)?
    • 什么是过滤器(Filter)?
    • 两者的核心区别
  2. 使用场景
    • 拦截器的典型应用
    • 过滤器的典型应用
  3. 实现步骤
    • 拦截器的创建与配置
    • 过滤器的创建与配置
  4. 代码示例
    • 自定义拦截器
    • 自定义过滤器
  5. 执行顺序与流程
    • 过滤器、拦截器、Controller的执行顺序
    • 可视化流程图
  6. 常见问题与解决方案
  7. 总结

1. 概述

1.1 什么是拦截器(Interceptor)?

拦截器是 Spring MVC 框架的组件,基于 AOP(面向切面编程) 实现。它允许在请求处理的不同阶段(如Controller方法执行前后)插入自定义逻辑。

1.2 什么是过滤器(Filter)?

过滤器是 Java Servlet规范 定义的组件,作用于所有进入容器的请求(如Tomcat)。它可以在请求到达Servlet前或响应返回客户端前进行预处理和后处理。

1.3 核心区别

特性拦截器(Interceptor)过滤器(Filter)
所属框架Spring MVCServlet API
作用范围仅Spring MVC管理的请求所有请求(包括静态资源)
依赖依赖Spring容器依赖Servlet容器(如Tomcat)
执行时机Controller方法前后Servlet处理前后
获取Bean支持(通过Spring上下文)不支持(需通过其他方式注入)

2. 使用场景

2.1 拦截器的典型应用

  • 日志记录:记录请求参数、响应时间。
  • 权限验证:检查用户是否登录或拥有权限。
  • 事务管理:在Controller方法前后开启/提交事务。
  • 性能监控:统计接口耗时。

2.2 过滤器的典型应用

  • 全局字符编码:统一设置请求/响应的编码(如UTF-8)。
  • 跨域处理:添加CORS响应头。
  • XSS防御:过滤请求参数中的恶意脚本。
  • 请求压缩:对响应内容进行GZIP压缩。

3. 实现步骤

3.1 创建拦截器

步骤:

  1. 实现 HandlerInterceptor 接口,重写以下方法:
    • preHandle():在Controller方法执行前调用。
    • postHandle():在Controller方法执行后、视图渲染前调用。
    • afterCompletion():在请求完成后调用(视图渲染后)。
  2. 注册拦截器到Spring MVC配置。

代码示例:

public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 检查用户是否登录if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/login");return false; // 中断请求}return true;}
}

注册拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/static/**");}
}

注册多个拦截器:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 第一个拦截器:日志(优先级高)registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**")       // 拦截所有路径.excludePathPatterns("/static/**"); // 排除静态资源// 第二个拦截器:权限(优先级低)registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");  // 仅拦截/api路径}
}

关键配置选项

配置方法说明
addPathPatterns("/api")指定拦截的路径(支持Ant风格)
excludePathPatterns("/login")排除特定路径
order(1)显式设置顺序(默认按注册顺序)

若要手动指定顺序,可添加:

registry.addInterceptor(new LogInterceptor()).order(1);
registry.addInterceptor(new AuthInterceptor()).order(2);

3.2 创建过滤器

步骤:

  1. 实现 javax.servlet.Filter 接口,重写 doFilter 方法。
  2. 注册过滤器到Servlet容器(通过注解或配置类)。

代码示例:

@WebFilter(urlPatterns = "/*")
public class LoggingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("请求开始: " + ((HttpServletRequest) request).getRequestURI());chain.doFilter(request, response); // 继续执行后续过滤器或ServletSystem.out.println("请求结束");}
}

注册过滤器(若未使用@WebFilter):

@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<LoggingFilter> loggingFilter() {FilterRegistrationBean<LoggingFilter> bean = new FilterRegistrationBean<>();bean.setFilter(new LoggingFilter());bean.addUrlPatterns("/*");bean.setOrder(1); // 设置执行顺序return bean;}
}

注意: 确保主类添加 @ServletComponentScan 以启用 @WebFilter 注解。


4. 执行顺序与流程

4.1 执行顺序

  1. 过滤器(FilterChain) → 2. 拦截器(preHandle) → 3. Controller方法 → 4. 拦截器(postHandle) → 5. 视图渲染 → 6. 拦截器(afterCompletion) → 7. 过滤器后续处理

4.2 流程图

客户端 → Filter.doFilter() → Interceptor.preHandle()→ Controller → Interceptor.postHandle()→ 视图渲染 → Interceptor.afterCompletion()→ Filter.doFilter()后续处理 → 客户端

5. 常见问题与解决方案

Q1:如何控制多个拦截器/过滤器的执行顺序?

  • 拦截器:通过 registry.addInterceptor() 的顺序决定。
  • 过滤器:通过 FilterRegistrationBean.setOrder() 设置优先级(值越小越先执行)。

Q2:拦截器中如何获取Spring管理的Bean?

直接从Spring容器注入:

public class AuthInterceptor implements HandlerInterceptor {@Autowiredprivate UserService userService; // 直接注入
}

Q3:过滤器中如何修改请求参数?

通过自定义 HttpServletRequestWrapper

public class ModifyRequestWrapper extends HttpServletRequestWrapper {// 重写getParameter等方法以修改参数
}// 在Filter中替换Request对象
chain.doFilter(new ModifyRequestWrapper(request), response);

Q4:拦截器和过滤器执行时出现异常如何处理?

  • 拦截器:在 afterCompletion 中处理异常。
  • 过滤器:使用 try-catch 包裹 chain.doFilter()

Q5:如何让某个拦截器全局生效?

使用 addPathPatterns("/**")

registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");

Q6:如何跳过特定拦截器的执行?

preHandle 中返回 false

@Override
public boolean preHandle(...) {if (跳过条件) {return false; // 后续拦截器和Controller不会执行}return true;
}

Q7:拦截器之间如何共享数据?

通过 request.setAttribute 传递:

// 在第一个拦截器中存储数据
request.setAttribute("key", "value");// 在后续拦截器中获取
String value = (String) request.getAttribute("key");

6. 总结

  • 选择拦截器还是过滤器?

    • 需要访问Spring上下文或Controller信息 → 拦截器。
    • 需处理所有请求(包括静态资源) → 过滤器。
  • 最佳实践

    • 优先使用拦截器处理业务相关逻辑。
    • 使用过滤器处理底层Servlet容器的任务(如编码、压缩)。

相关文章:

Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程

Spring Boot拦截器&#xff08;Interceptor&#xff09;与过滤器&#xff08;Filter&#xff09;详细教程 目录 概述 什么是拦截器&#xff08;Interceptor&#xff09;&#xff1f;什么是过滤器&#xff08;Filter&#xff09;&#xff1f;两者的核心区别 使用场景 拦截器的典…...

HTML-05NPM使用踩坑

2025-03-04-NPM使用踩坑 本文讲述了一个苦逼程序员在使用NPM的时候突然来了一记nmp login天雷&#xff0c;然后一番折腾之后&#xff0c;终究还是没有解决npm的问题&#x1f61e;&#x1f61e;&#x1f61e;,最终使用cnpm完美解决的故事。 文章目录 2025-03-04-NPM使用踩坑[toc…...

自学嵌入式第29天-----epoll、sqlite3

1. 正确选择触发模式&#xff08;ET 和 LT&#xff09; 水平触发&#xff08;LT&#xff09;&#xff1a;默认模式&#xff0c;只要文件描述符处于就绪状态&#xff0c;epoll_wait 会持续通知。适合大多数场景&#xff0c;编程简单。 边缘触发&#xff08;ET&#xff09;&…...

工作学习笔记:HarmonyOS 核心术语速查表(v14 实战版)

作为在 HarmonyOS 开发一线摸爬滚打的工程师&#xff0c;笔者在 v14 版本迭代中整理了这份带血的实战术语表。 一、架构基础术语速查 A 系列术语 术语官方定义笔者解读&#xff08;v14 实战版&#xff09;开发陷阱 & 解决方案abc 文件ArkCompiler 生成的字节码文件打包时…...

解决AWS EC2实例无法使用IAM角色登录AWS CLI

问题背景 有时&#xff0c;我们希望一台AWS EC2实例&#xff0c;即云服务器&#xff0c;能够使用AWS CLI访问AWS管理控制台资源。 例如&#xff0c;这里&#xff0c;我们想让它能够列出所有IAM用户组。 aws iam list-groups于是&#xff0c;我们使用下面的命令&#xff0c;在…...

Java核心语法:从变量到控制流

一、变量与数据类型&#xff08;对比Python/C特性&#xff09; 1. 变量声明三要素 // Java&#xff08;强类型语言&#xff0c;需显式声明类型&#xff09; int age 25; String name "CSDN"; // Python&#xff08;动态类型&#xff09; age 25 name …...

manus是什么?能干啥?

Manus哪儿来的&#xff1f; ​ Manus是一款由中国团队Monica.im于2025年3月5日发布的通用型AI代理&#xff08;AI Agent&#xff09;产品&#xff0c;旨在通过自主思考、系统规划和灵活工具调用&#xff0c;帮助用户完成各种复杂任务&#xff0c;从而解放用户的时间与创…...

大型语言模型训练的三个阶段:Pre-Train、Instruction Fine-tuning、RLHF (PPO / DPO / GRPO)

前言 如果你对这篇文章可感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 当前的大型语言模型训练大致可以分为如下三个阶段&#xff1a; Pre-train&#xff1a;根据大量可获得的文本资料&#…...

Elasticsearch 2025/3/7

高性能分布式搜索引擎。 数据库模糊搜索比较慢&#xff0c;但用搜索引擎快多了。 下面是一些搜索引擎排名 Lucene是一个Java语言的搜索引擎类库&#xff08;一个工具包&#xff09;&#xff0c;apache公司的顶级项目。 优势&#xff1a;易扩展、高性能&#xff08;基于倒排索引…...

发行基础:热销商品榜单

转载自官方文件 ------------------ 热销商品榜单 Steam 在整个商店范围内有各种热销商品榜单&#xff0c;最醒目的莫过于 Steam 主页上的榜单了。 您也可以在浏览单个标签、主题、类型时找到针对某个游戏类别的热销商品榜单。 主页热销商品榜单 该榜单出现在 Steam 主页上…...

实战案例分享:Android WLAN Hal层移植(MTK+QCA6696)

本文将详细介绍基于MTK平台&#xff0c;适配高通&#xff08;Qualcomm&#xff09;QCA6696芯片的Android WLAN HAL层的移植过程&#xff0c;包括HIDL接口定义、Wi-Fi驱动移植以及wpa_supplicant适配过程&#xff0c;涵盖STA与AP模式的常见问题与解决方法。 1. HIDL接口简介 HID…...

物联网系统搭建

实验项目名称 构建物联网系统 实验目的 掌握物联网系统的一般构建方法。 实验要求&#xff1a; 1&#xff0e;构建物联网系统&#xff0c;实现前后端的交互。 实验内容&#xff1a; CS模式MQTT&#xff08;不带数据分析处理功能&#xff09; 实现智能设备与应用客户端的交…...

微前端框架 Qiankun 的应用及问题分析

一、Qiankun 的核心应用场景与优势 多技术栈共存与灵活集成 Qiankun 支持主应用与子应用使用不同技术栈&#xff08;如 Vue、React、Angular 等&#xff09;&#xff0c;通过 HTML Entry 方式接入子应用&#xff0c;无需深度改造子应用即可实现集成&#xff0c;降低了技术迁移成…...

设计模式-结构型模式-适配器模式

概述 适配器模式 : Adapter Pattern 是一种结构型设计模式. 作用 &#xff1a; 使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 实现思路 &#xff1a; 适配器模式通过将一个类的接口转换成客户希望的另外一个接口来实现这一点。 这里的“接口”指的是类所提供的…...

6. 机器人实现远程遥控(具身智能机器人套件)

1. 启动控制脚本 远程作到 Raspberry Pi 中&#xff0c;并运行以下脚本&#xff1a; conda activate lerobotpython lerobot/scripts/control_robot.py \--robot.typelekiwi \--control.typeremote_robot登录笔记本电脑上&#xff0c;同时运行以下脚本&#xff1a; conda ac…...

多模态知识图谱融合

1.Knowledge Graphs Meet Multi-Modal Learning: A Comprehensive Survey 1.1多模态实体对齐 1.2多模态实体链接 研究进展&#...

windows 平台如何点击网页上的url ,会打开远程桌面连接服务器

你可以使用自定义协议方案&#xff08;Protocol Scheme&#xff09;实现网页上点击URL后自动启动远程桌面连接&#xff08;mstsc&#xff09;&#xff0c;参考你提供的C代码思路&#xff0c;如下实现&#xff1a; 第一步&#xff1a;注册自定义协议 使用类似openmstsc://协议…...

基于Spark的热门动漫推荐数据分析与可视化系统的设计与实现(采用Python语言Django框架,Hadoop,spider爬虫等技术实现)

基于Hadoop的热门动漫推荐数据分析与可视化系统 基于Django的热门动漫推荐数据分析与可视化系统 1. 开发工具和实现技术 Pycharm, Python3.7&#xff0c;Django框架&#xff0c;Hadoop&#xff0c;Spark&#xff0c;Hive&#xff0c;spider爬虫&#xff08;爬取动漫之家的动…...

8. 机器人模型训练与评估(具身智能机器人套件)

1. 训练 使用python lerobot/scripts/train.py可以进行机器人控制模型训练&#xff0c;一般需要几个小时&#xff0c;可以在outputs/train/act_lekiwi_test/checkpoints查看锚点数据&#xff0c;下面为一组示例参数&#xff1a; python lerobot/scripts/train.py \--dataset.…...

计算机网络-服务器模型

一.服务器模型 1.支持多客户端访问 //单循环服务器 socket bind listen while(1) { accept while(1) { recv/send } } close 注&#xff1a;该模式remvform为阻塞态&#xff0c;服务器将等待接收数据 2..支持多客户端同时访问 (并发能力) socket…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...