《知识点扫盲 · 过滤器 Filter》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻一周,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,如需交流,欢迎留言评论。👍

文章目录

    • 写在前面的话
    • 过滤器 Filter
      • 前置概念介绍
      • 如何自定义过滤器
      • OncePerRequestFilter
      • 如何注册过滤器
      • 非SB项目实现过滤器
      • SB3.x实现过滤器
      • 实际过滤器示例
      • 过滤器和拦截器区别
    • 总结陈词

写在前面的话

  • 过滤器(Filter)是一种用来过滤每个 HTTP 请求和响应的组件,它可以对请求和响应进行预处理和后处理,例如进行日志记录、安全检查、编码转换等操作。
  • 过滤器 Filter 是主要是基于 Servlet API 的概念,并不是 Spring 独有的。Servlet Filter 是 Java Web 应用程序中用来对请求和响应进行预处理和后处理的组件,定义在 Servlet 规范中。Spring 基于 Servlet API 提供了对过滤器的支持,使其可以更方便地集成和配置。 只不过,Spring Boot 提供了简单的方式来配置和使用过滤器。
  • 过滤器 Filter 是 JavaWeb 三大组件(Servlet,Filter,Listener)之一,关于拦截器上文刚介绍完,参考《知识点扫盲 · 拦截器 Interceptor》,接下来开始过滤器。

过滤器 Filter

前置概念介绍

1、 Servlet 中的过滤器 Filter 是实现了 javax.servlet.Filter 接口的服务器端程序,通过Filter技术可以对 WEB 服务器的文件进行拦截,从而实现一些特殊的功能。
2、 传统 SpringMVC 项目,只要你在 web.xml 文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对在传入控制器前对请求或响应(Request、Response) 做一些前置处理,它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
3、 使用场景:登录状态判断、编码格式设置、访问权限控制、敏感字符过滤、跨域处理。

如何自定义过滤器

过滤在 SpringBoot 中的实现有两种方式,基础都是需要实现Filter。

public class CustomFilter implements Filter {@Overridepublic void init(FilterConfig config) throws ServletException {if (log.isInfoEnabled()) {log.info("CustomFilter初始化......");}}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {chain.doFilter(request, response);}@Overridepublic void destroy() {if (log.isInfoEnabled()) {log.info("CustomFilter过滤器销毁......");}}
}

OncePerRequestFilter

在Spring框架中推荐使用 OncePerRequestFilter ,它是Spring框架提供的一个抽象类,用于确保过滤器只在每个请求中被调用一次。它继承自 GenericFilterBean 类,并在 doFilter 方法中添加了对请求是否已被过滤的判断逻辑。
OncePerRequestFilter 和 Filter 的根本区别在于 OncePerRequestFilter 提供了一个确保过滤器只在每个请求中被调用一次的机制,而 Filter 接口本身并没有提供这样的机制。

Tips:使用起来区别不大。

public class MyOncePerRequestFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {// 过滤器逻辑System.out.println("Filter executed once per request");// 继续过滤器链filterChain.doFilter(request, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化逻辑(可选)}@Overridepublic void destroy() {// 销毁逻辑(可选)}
}

如何注册过滤器

第一种是使用如下注解,这种方式需要启动类上搭配注解@ServletComponentScan,该注解用于注解用于扫描 @WebFilter、@WebListener 和 @WebServlet 注解。

@Component
@WebFilter(filterName = "customFilter", urlPatterns = "/*")
@Order(value = 1)

第二种是利用FilterRegistrationBean来注册,具体下面代码。

@Bean
public FilterRegistrationBean filterRegist() {FilterRegistrationBean frBean = new FilterRegistrationBean();frBean.setFilter(new CustomFilter());frBean.addUrlPatterns("/*");frBean.addInitParameter("encoding", "UTF-8");frBean.addInitParameter("baseUrl", baseUrl);frBean.setName("sessionFilter");return frBean;
}

非SB项目实现过滤器

<!--添加包装request-->
<filter><filter-name>wrapRequestFilter</filter-name><filter-class>com.zoe.optimus.core.common.web.filter.WrapParameterFilter</filter-class>
</filter>
<filter-mapping><filter-name>wrapRequestFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

SB3.x实现过滤器

1、创建过滤器类,实现 jakarta.servlet.Filter 接口,重写 doFilter 方法;

Tips:从SB3.0开始,改为jakarta.servlet.Filter,而不是java.servlet.Filter。

2、为自定义类添加过滤器注解@WebFilter
3、为启动类添加扫描@ServletComponentScan
4、启动项目后,访问任意接口,即可测试效果

实际过滤器示例

WrapParameterFilter:自定义的包装参数过滤器,解析特定格式的参数。
CorsFilter:自定义的跨域处理过滤器。
CharacterEncodingFilter:SpringMVC 字符编码过滤器。

public class CorsFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers","operator, apiKey, requestId, deptCode, langType, orgCode, clientId, clientIp, districtCode, reqToken");filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
}

过滤器和拦截器区别

1、Filter 依赖于Servlet容器,属于Servlet规范的一部分,生命周期由Servlet容器管理,可拦截所有Web资源(包括JSP、Servlet、静态资源等);
2、Interceptor 依赖于SpringMVC框架,通过IOC容器来管理,可通过注入等方式来获取其Bean的实例,只能拦截Controller;
3、两者在功能上类似,前置拦截效果基本可以实现,但拦截器还支持后置操作;


总结陈词

上文介绍了过滤器的用法,仅供参考。过滤器主要针对请求前后做出处理,没有像拦截器那样出现在很多库,同时,两者的实际适用场景其实存在若干重叠。
选择使用过滤器还是拦截器,取决于具体需求和处理的阶段。过滤器更适合全局的请求和响应处理,而拦截器更适合与控制器方法紧密相关的处理。

💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

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

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

相关文章

mac 安装homebrew

vim brew_install.sh 输入&#xff1a; #!/bin/bash set -u# First check if the OS is Linux. if [[ "$(uname)" "Linux" ]]; thenHOMEBREW_ON_LINUX1 fi# Check if macOS is ARM if [[ "$(uname)" "Darwin" ]] && [[ &q…

Java--Map集合

Map 映射(map)是存储键和值间关联(即&#xff0c;键值对)的对象。给定一个键&#xff0c;可以找到其值。键和值都是对象。键必须唯一&#xff0c;但是值可以重复。 支持映射的接口 接 口 描 述 Map 将唯一键映射到值 NavigableMap 扩展SortedMap接口&#xff0c;以处理…

yarn的安装与配置(秒懂yarn用法)

Yarn 是一个快速、可靠和安全的 JavaScript 包管理工具。下面是关于在 Windows 上安装和配置 Yarn 的步骤&#xff0c;以及一些基本的用法介绍。 ### 一、安装 Yarn #### 1. 通过安装 Node.js 和 npm 安装 Yarn Yarn 依赖于 Node.js 和 npm&#xff0c;因此首先需要安装 Nod…

Spring Boot与Redis的缓存一致性问题

Spring Boot与Redis的缓存一致性问题 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨一下在Spring Boot中使用Redis时&#xff0c;如何处理缓存一…

使用PID算法实现DAC模拟量输出的快速调节

目录 概述 1 系统框架和算法 1.1 框架结构介绍 1.2 PID算法实现 1.2.1 理论介绍 1.2.2 离散化位置式PID 1.2.3 位置式PID算法 2 STM32Cube 配置项目 2.1 配置参数 2.2 GENERATE项目 3 功能实现 3.1 ADC采样数据功能 3.2 DAC数据转换 3.3 PID相关的调制函数 4 …

基于YOLOv10深度学习的CT扫描图像肾结石智能检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

第10天:字典和集合任务

学习内容&#xff1a; 字典的创建和操作集合的创建和操作 字典&#xff08;Dictionary&#xff09; 字典的创建 # 创建一个空字典 my_dict {}# 创建一个带有初始值的字典 my_dict {"name": "Alice", "age": 25, "city": "N…

【Python】已解决:ModuleNotFoundError: No module named ‘pyhanlp’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘pyhanlp’ 一、分析问题背景 在使用Python进行自然语言处理时&#xff0c;有时我们可能会用到pyhanlp这个库&#xff0c;它是一个基于J…

【JVM】Java虚拟机运行时数据分区介绍

JVM 分区&#xff08;运行时数据区域&#xff09; 文章目录 JVM 分区&#xff08;运行时数据区域&#xff09;前言1. 程序计数器2. Java 虚拟机栈3. 本地方法栈4. Java 堆5. 方法区6. 运行时常量池7. 直接内存 前言 之前在说多线程的时候&#xff0c;提到了JVM虚拟机的分区内存…

HarmonyOS APP应用开发项目- MCA助手(Day01持续更新中~)

简言&#xff1a; gitee地址&#xff1a;https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5 注&#xff1…

MySQL 9.0 悄悄上线,支持面向AI的向量数据库

MySQL狂热粉丝群已经发现MySQL官网上MySQL9.0这两天悄然上线&#xff0c;已经可以下载体验了&#xff0c;目前被定义为创新版本&#xff08;Innovation&#xff09;。 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 支持主流的操作系统&#xff0c;安装后可以直…

DDD学习笔记六

基类与继承 领域模型中何时发掘和应用基类与继承&#xff1a; 1&#xff09;基类概念必须是通用语言的一部分&#xff0c;并且对应领域中的一个抽象概念。 2&#xff09;这个概念必须被进一步细化&#xff0c;才能具备实际业务含义。 3&#xff09;基类概念被细化的子类存在着不…

QT 线程计时器

qt自带的计时器QTimer是与界面主线程绑定在一起的&#xff0c;如果操作界面有可能会影响计时器的执行&#xff0c;所以查找一些资料写了一个长期运行的线程计时器。 1.线程类的头文件 #ifndef WORKTH_H #define WORKTH_H#include <QDebug> #include <QThread> #i…

分布式服务——注册中心

介绍 想象一下&#xff0c;一个繁忙的周末&#xff0c;阳光明媚&#xff0c;公园里的孩子们在尽情玩耍&#xff0c;大人们则坐在长椅上享受着难得的闲暇时光。突然&#xff0c;一个小女孩跑到一位陌生的先生面前&#xff0c;甜甜地说&#xff1a;“叔叔&#xff0c;你能不能帮…

论坛入门与提升

前言 明确设计思路&#xff0c;精准定位问题&#xff0c;对于我们后期理解迭代工程有很大的帮助。 这就是我们常说的40%设计&#xff0c;20%编写和剩下的40%时间进行调试优化。 今天为大家带来的是通过对论坛的深入了解&#xff0c;来解决大家遇到问题时的迷茫&#xff0c;合…

基于字符和词特征融合的恶意域名检测

传统的恶意域名检测方法在检测由域名生成算法&#xff08;DGA&#xff09;随机生成的恶意域名方面性能不佳&#xff0c;尤其是对于那些由随机单词组成的域名。文章提出了一种新的检测算法&#xff0c;通过融合字符和词特征来提高对恶意域名的检测能力&#xff0c;特别是对于更具…

SpringCloud基础篇

文章目录 创建新模块拷贝yml配置文件修改配置文件的信息修改pom.xml文件启动入口拷贝相关文件接口文档配置配置启动项注册中心原理Nacos注册中心创建nacos数据库存储数据部署nacos在docker容器中 服务注册引入依赖配置Nacos地址启动 服务发现(调用)引入依赖配置nacos地址发现并…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《面向电网调峰的电动汽车聚合商多层级实时控制策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID

有时候经常会有个别容器占用磁盘空间特别大&#xff0c; 这个时候就需要通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID&#xff1a; 1、 首先进入到 /var/lib/docker/overlay2 目录下,查看谁占用的较多 [rootPPS-97-8-ALI-HD1H overlay2]# cd /var/lib/doc…

Linux基础 - MariaDB 数据库管理系统

目录 零. 简介 一. 安装 二. 基本使用 1. 设置root密码 2. 创建库 3. 创建表 4.添加数据 5. 查看数据 三. 管理表单及数据 四. 数据库的备份及恢复 零. 简介 MariaDB 是一种流行的开源数据库管理系统&#xff0c;它是 MySQL 的一个分支。 MariaDB 保留了与 MySQL 的…