拦截器VS过滤器:Spring Boot中请求处理的艺术!

news2025/5/22 23:17:36

在这里插入图片描述

目录

    • 一、拦截器(Interceptor)和过滤器(Filter):都是“守门员”!
    • 二、如何实现拦截器和过滤器?
    • 三、拦截器和过滤器的区别
    • 四、执行顺序
    • 五、真实的应用场景
    • 六、总结

🌟如果喜欢作者的讲解方式,关注作者不迷路,同时也可以看看我的其他文章! 感谢!!!
🌟 从乐高积木到乐队指挥,用最通俗易懂的方式带你玩转 Spring Boot Bean!

就让我用这篇文章来讲解 SpringBoot 的拦截器和过滤器吧,给它安排明白!😎

一、拦截器(Interceptor)和过滤器(Filter):都是“守门员”!

想象一下,你的 SpringBoot 应用就像一个豪华酒店🏨。

  • 过滤器(Filter): 就像酒店大门口的保安👮,负责检查所有进出酒店的人(请求)。它可以决定是否允许客人进入,或者在客人进入前做一些处理,比如检查身份证、测量体温🌡️。
  • 拦截器(Interceptor): 就像酒店内部各个楼层的楼层经理👩‍💼,只负责检查进入特定楼层(Controller)的客人。它可以在客人进入楼层前、进入楼层后、离开楼层后都进行干预,比如登记访客信息、提供楼层指引🗺️。

二、如何实现拦截器和过滤器?

1. 过滤器(Filter):

  • 步骤一: 创建一个类,实现 javax.servlet.Filter 接口。
  • 步骤二: 实现 doFilter() 方法。这个方法就是过滤器的核心逻辑,在这里你可以对请求和响应进行处理。
  • 步骤三: 使用 @WebFilter 注解或者在 WebConfig 类中注册过滤器。
// 方式一:使用 @WebFilter 注解
@WebFilter(urlPatterns = "/*", filterName = "MyFilter") // 拦截所有请求
public class MyFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤器:请求来了!我要检查一下!🧐");
        // 可以对 request 和 response 进行处理
        HttpServletRequest req = (HttpServletRequest) request;
        String uri = req.getRequestURI();
        System.out.println("请求的URI:" + uri);

        // 放行,让请求继续往下走
        chain.doFilter(request, response);

        System.out.println("过滤器:请求走了!我要记录一下!📝");
    }
}

// 方式二:在 WebConfig 类中注册
@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistrationBean() {
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*"); // 拦截所有请求
        registration.setName("MyFilter");
        registration.setOrder(1); // 设置优先级,数字越小优先级越高
        return registration;
    }
}

2. 拦截器(Interceptor):

  • 步骤一: 创建一个类,实现 org.springframework.web.servlet.HandlerInterceptor 接口。
  • 步骤二: 实现 preHandle()postHandle()afterCompletion() 方法。
    • preHandle():在 Controller 处理请求之前调用,可以进行权限验证、参数校验等。如果返回 false,则请求会被拦截,不会继续执行。
    • postHandle():在 Controller 处理请求之后,但在视图渲染之前调用,可以对 ModelAndView 进行修改。
    • afterCompletion():在整个请求处理完毕之后调用,可以进行资源清理、日志记录等。
  • 步骤三: 创建一个配置类,实现 org.springframework.web.servlet.config.annotation.WebMvcConfigurer 接口,并重写 addInterceptors() 方法,将拦截器注册到 Spring 容器中。
public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器:Controller 要处理请求了!我要先检查一下!👮‍♀️");
        // 可以进行权限验证、参数校验等
        String token = request.getHeader("token");
        if (token == null || token.isEmpty()) {
            System.out.println("拦截器:没有 token,拒绝访问!🚫");
            response.setStatus(401); // 返回未授权状态码
            return false; // 拦截请求
        }
        return true; // 放行请求
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器:Controller 处理完请求了!我可以修改 ModelAndView!🎨");
        // 可以对 ModelAndView 进行修改
        if (modelAndView != null) {
            modelAndView.addObject("message", "拦截器添加的额外信息!🎁");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器:请求处理完成了!我可以清理资源、记录日志!🧹");
        // 可以进行资源清理、日志记录等
    }
}

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/api/**") // 拦截 /api/ 下的所有请求
                .excludePathPatterns("/api/login"); // 排除 /api/login 请求
    }
}

三、拦截器和过滤器的区别

特性过滤器(Filter)拦截器(Interceptor)
实现方式实现 javax.servlet.Filter 接口实现 org.springframework.web.servlet.HandlerInterceptor 接口
拦截范围拦截所有进出 Servlet 容器的请求拦截特定的 Controller 方法
执行时机在 DispatcherServlet 之前和之后执行在 Controller 方法执行之前、之后和完成之后执行
依赖性不依赖 Spring 容器依赖 Spring 容器,可以访问 Spring 上下文
功能字符编码转换、请求内容过滤、敏感词过滤等权限验证、日志记录、参数校验等
精确度粗粒度,只能拦截 URL细粒度,可以访问 HandlerMethod,获取方法信息

总结:

  • 过滤器: 拦截所有请求,不依赖 Spring,功能比较通用。
  • 拦截器: 拦截特定 Controller 方法,依赖 Spring,功能更精细。

四、执行顺序

  1. 过滤器(Filter):在 DispatcherServlet 之前执行。
  2. 拦截器(Interceptor)
    • preHandle():在 Controller 方法执行之前执行。
    • Controller 方法执行。
    • postHandle():在 Controller 方法执行之后,但在视图渲染之前执行。
    • 视图渲染。
    • afterCompletion():在整个请求处理完毕之后执行。

记住: 多个过滤器和拦截器可以配置执行顺序,通常通过 order 属性或者 @Order 注解来设置,数字越小优先级越高。

五、真实的应用场景

  • 过滤器:
    • 字符编码转换: 统一设置请求和响应的字符编码,避免乱码。
    • XSS 攻击防御: 过滤请求中的恶意脚本,防止 XSS 攻击。
    • 日志记录: 记录所有请求的 URL、IP 地址等信息。
  • 拦截器:
    • 权限验证: 检查用户是否已登录,是否有权限访问特定资源。
    • 参数校验: 校验请求参数的合法性,防止恶意请求。
    • 性能监控: 记录 Controller 方法的执行时间,分析性能瓶颈。
    • 防止重复提交: 避免用户重复提交表单。

六、总结

  • 过滤器: 就像酒店大门口的保安,啥人都拦,主要做一些通用的检查,比如身份证、体温啥的。
  • 拦截器: 就像楼层经理,只管特定楼层的人,可以做更细致的检查,比如登记访客信息、提供楼层指引。
  • 执行顺序: 先保安,再楼层经理。保安先检查,楼层经理在客人进房间前、进房间后、离开房间后都可以管。

如果编写了AOP逻辑,会在拦截器之后执行,相关内容请看:
🔗被重复代码逼疯?AOP来当“舔狗”!日志/事务/权限,随叫随到!

希望这篇文章能让你有趣的理解 SpringBoot 的拦截器和过滤器!🎉🎉🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2302098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react实例与总结(二)

目录 一、脚手架基础语法(16~17) 1.1、hello react 1.2、组件样式隔离(样式模块化) 1.3、react插件 二、React Router v5 2.1、react-router-dom相关API 2.1.1、内置组件 2.1.1.1、BrowserRouter 2.1.1.2、HashRouter 2.1.1.3、Route 2.1.1.4、Redirect 2.1.1.5、L…

巧用GitHub的CICD功能免费打包部署前端项目

近年来&#xff0c;随着前端技术的发展&#xff0c;前端项目的构建和打包过程变得越来越复杂&#xff0c;占用的资源也越来越多。我有一台云服务器&#xff0c;原本打算使用Docker进行部署&#xff0c;以简化操作流程。然而&#xff0c;只要执行sudo docker-compose -f deploy/…

使用 DeepSeek 生成商城流程图

步骤 1.下载 mermaid 2.使用 DeepSeek 生成 mermaid 格式 3.复制内容到 4.保存备用。 结束。

VSCode自定义快捷键和添加自定义快捷键按键到状态栏

VSCode自定义快捷键和添加自定义快捷键按键到状态栏 &#x1f4c4;在VSCode中想实现快捷键方式执行某些指令操作&#xff0c;可以通过配置组合式的键盘按键映射来实现&#xff0c;另外一种方式就是将执行某些特定的指令嵌入在面板菜单上&#xff0c;在想要执行的时候&#xff0…

Ubuntu22.04 - gflags的安装和使用

目录 gflags 介绍gflags 安装gflags 使用 gflags 介绍 gflags 是Google 开发的一个开源库&#xff0c;用于 C应用程序中命令行参数的声明、定义和解析。gflags 库提供了一种简单的方式来添加、解析和文档化命令行标志(flags),使得程序可以根据不同的运行时配置进行调整。 它具…

java | MyBatis-plus映射和golang映射对比

文章目录 Java实体类和数据库的映射1.默认驼峰命名规则2.自定义字段映射3.关闭驼峰命名规则4.JSON序列化映射 Golang1. 结构体与表的映射2. 字段与列的映射3. 关联关系映射4. 其他映射相关标签 这篇也是做数据库映射方面的对比&#xff1a; Java 实体类和数据库的映射 1.默认…

正则表达式–断言

原文地址&#xff1a;正则表达式–断言 – 无敌牛 欢迎参观我的个人博客&#xff1a;正则表达式特殊字符 – 无敌牛 断言assertions 1、(?...)&#xff1a;正向预查&#xff08;positive lookahead&#xff09;&#xff0c;表示某个字符串后面应该跟着什么。但这个字符串本身…

电脑想安装 Windows 11 需要开启 TPM 2.0 怎么办?

尽管 TPM 2.0 已经内置在许多新电脑中&#xff0c;但很多人并不知道如何激活这一功能&#xff0c;甚至完全忽略了它的存在。其实&#xff0c;只需简单的几步操作&#xff0c;你就能开启这项强大的安全特性&#xff0c;为你的数字生活增添一层坚固的防护屏障。无论你是普通用户还…

QT之改变鼠标样式

QT改变鼠标图片 资源路径如下 代码实现 QPixmap customCursorPixmap(":/images/mouse.png");QCursor customCursor(customCursorPixmap);QWidget::setCursor(customCursor); // 可以设置为整个窗口或特定控件QWidget::setCursor(); // 设置为透明光标&#xff0c…

ue----git局域网内部署裸仓库,别的机器进行访问

最近由于经常迁移项目到另一台机器上进行部署更新一点就要整个迁移 弄得麻烦了 就在网上学了一下这个方式 首先我们在想要建立裸仓库的电脑上找到一个文件夹放置我们的裸仓库 在此点击鼠标右键选择 open git bash here 输入命令 创裸仓库 git init --bare gitTestName.git…

PaddlePaddle的OCR模型转onnx-转rknn模型_笔记4

一、PaddlePaddle的OCR模型转onnx 1、首先建立一个新的虚拟环境 conda create -n ppocr python3.10 -y conda activate ppocr 2、进入paddlepaddle官网输入以下指令安装paddlepaddle GPU版本 &#xff08;我的cuda版本是11.8,根据你电脑装合适版本&#xff09; pip instal…

【大模型系列篇】DeepSeek-R1如何通过强化学习有效提升大型语言模型的推理能力?

如何通过强化学习&#xff08;RL&#xff09;有效提升大型语言模型&#xff08;LLM&#xff09;的推理能力&#xff1f; 《DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning》由DeepSeek-AI团队撰写&#xff0c;主要介绍了他们开发的第一代…

企业存储系统

一、概述 数字经济 人类通过大数据&#xff08;数字化的知识与信息&#xff09;的识别—选择—过滤—存储—使用&#xff0c;引导、实现资源的快速优化配置与再生&#xff0c;实现经济高质量发展的经济形态。 产业互联网推动发展 企业开始进行数字化转型&#xff0c;将传统…

数据结构系列一:初识集合框架+复杂度

前言 数据结构——是相互之间存在一种或多种特定关系的数据元素的集合。数据结构是计算机专业的基础课程&#xff0c;但也是一门不太容易学好的课&#xff0c;它当中有很多费脑子的东西&#xff0c;之后在学习时&#xff0c;你若碰到了困惑或不解的地方 都是很正常的反应&…

Linux系统编程学习 NO.14——缓冲区的概念、模拟实现Cstdio库

用户缓冲区 先介绍一下关于用户缓冲区的周边知识。 fread和fwrite的返回值 谈一谈fread和fwrite的返回值&#xff0c;如果写入/读取文件成功&#xff0c;fread或fwrite的返回值指的是实际写入/读取的内存块数量(实际的nmemb的大小)。假如fwrite写入的size是5字节&#xff0c;…

某手sig3-ios算法 Chomper黑盒调用

Chomper-iOS界的Unidbg 最近在学习中发现一个Chomper框架&#xff0c;Chomper 是一个模拟执行iOS可执行文件的框架&#xff0c;类似于安卓端大名鼎鼎的Unidbg。 这篇文章使用Chomper模拟执行某手的sig3算法&#xff0c;初步熟悉该框架。这里只熟悉模拟执行步骤以及一些常见的…

MySQL版本选择与安装

MySQL版本选择与安装 MySQL 5.5 优点: 稳定性&#xff1a;5.5版本是长期支持&#xff08;LTS&#xff09;版本&#xff0c;因此它非常稳定&#xff0c;被广泛部署在生产环境中。 兼容性&#xff1a;与旧版本的MySQL和各种应用程序有很好的兼容性。 缺点: 过时&#xff1a;…

【飞行器原理学习】——1. 机翼及机翼参数

飞行器原理学习——1.机翼 一、 概述 飞机的各种机翼是飞机的控制面 通过铰链、钢索、液压等方式连接在机身上 操纵面运动时&#xff0c;会改变机翼的弧度和形状&#xff0c;使流经的空气发生偏转&#xff0c;从而影响空气动力的大小。使飞机围绕着3轴运动 二、机翼的操纵面…

TS语言自定义脚手架

初始化 新建文件夹初始化命令 npm init -ytsc --initnpm i types/nodenpm i typescript# 处理别名npm i -D tsc-alias -y 表示选项都为yes 安装ts相关依赖 新建相关文件 bin 文件夹 src文件夹 commands 文件夹 &#xff08;命令 utils 文件夹 (封装方法&#xff09; index.t…

lab4 CSAPP:Cachelab

写在前面 最简单的一集 实验室分为两个部分。在A部分中&#xff0c;实现一个缓存模拟器。在B部分中&#xff0c;编写一个矩阵针对高速缓存性能优化的转置功能。 感觉是比较经典的问题&#xff0c;之前在体系结构的课程中接触过&#xff0c;终于能通过lab实操一下了。 实验目…