【WEB系列】过滤器Filter

Filter,过滤器,属于Servlet规范,并不是Spring独有的。其作用从命名上也可以看出一二,拦截一个请求,做一些业务逻辑操作,然后可以决定请求是否可以继续往下分发,落到其他的Filter或者对应的Servlet
简单描述下一个http请求过来之后,一个Filter的工作流程:

  • 首先进入filter,执行相关业务逻辑
  • 若判定通行,则进入Servlet逻辑,Servlet执行完毕之后,又返回Filter,最后在返回给请求方
  • 判定失败,直接返回,不需要将请求发给Servlet

image.png
这次测试用到的依赖:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>3.0.7</version>
</dependency>

<!-- MySQL Connector -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.11</version>
</dependency>

<!-- Lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.32</version>
  <scope>provided</scope>
</dependency>

<!-- MyBatis-Plus -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
  <version>3.5.5</version>
</dependency>


<!-- Spring Boot Starter JDBC -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
  <version>3.3.0</version>
</dependency>

<!-- HikariCP -->
<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <version>5.0.0</version>
</dependency>

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.13.1</version>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>RELEASE</version>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>6.0.9</version>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-test</artifactId>
  <version>3.0.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.47</version>
</dependency>

</dependencies>

在Spring中,如果需要定义一个过滤器,直接实现Filter接口即可

package com.hayaizo.transactional.filter;

import com.alibaba.fastjson.JSON;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;


@Slf4j
@WebFilter
public class ReqFilter implements Filter {
    public ReqFilter() {
        System.out.println("init reqFilter");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        log.info("url={}, params={}", req.getRequestURI(), JSON.toJSONString(req.getParameterMap()));
        chain.doFilter(req, response);
    }

    @Override
    public void destroy() {
    }
}

实现一个自定义的Filter容易,一般有两个步骤

  • 实现 Filter 接口
  • 在doFilter方法中添加业务逻辑,如果允许访问继续,则执行chain.doFilter(req, response);; 不执行上面这一句,则访问到此为止

接下来的一个问题就是如何让我们自定义的Filter生效,在SpringBoot项目中,有两种常见的使用方式

  • @WebFilter
  • 包装Bean: FilterRegistrationBean

那么如何让@WebFilter生效呢?

在Spring的启动类上添加@ServletComponentScan注解即可。

image.png
WebFilter常用属性如下,其中urlPatterns最为常用,表示这个filter适用于哪些url请求(默认场景下全部请求都被拦截)
@WebFilter注解是Java Servlet规范中用于定义过滤器的注解。它有多个属性,每个属性都有特定的类型和用途。以下是@WebFilter注解的属性、类型和用途的表格:

属性名类型用途
filterNameString指定过滤器的名称。
urlPatternsString[]指定过滤器的URL模式(可以是多个)。
valueString[]等同于urlPatterns,是一个快捷方式(不能同时使用urlPatternsvalue)。
servletNamesString[]指定过滤器应用到的Servlet名称。
dispatcherTypesDispatcherType[]指定过滤器应用到的调度类型,如REQUEST, FORWARD, INCLUDE, ERROR, ASYNC
initParamsWebInitParam[]指定过滤器的初始化参数。
asyncSupportedboolean指定过滤器是否支持异步操作,默认为false
descriptionString过滤器的描述信息。
displayNameString过滤器的显示名称。
smallIconString过滤器的小图标。
largeIconString过滤器的大图标。

下面给出一个具体例子来更好的理解这些注解的使用方法和含义

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

// 定义一个过滤器,使用@WebFilter注解
@WebFilter(
    filterName = "ExampleFilter", 
    urlPatterns = {"/example/*"}, 
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}, 
    initParams = {
        @WebInitParam(name = "param1", value = "value1"),
        @WebInitParam(name = "param2", value = "value2")
    },
    asyncSupported = true,
    description = "This is an example filter",
    displayName = "Example Filter"
)
public class ExampleFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 获取初始化参数
        String param1 = filterConfig.getInitParameter("param1");
        String param2 = filterConfig.getInitParameter("param2");
        System.out.println("Filter initialized with parameters: " + param1 + ", " + param2);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 在请求处理之前执行的代码
        System.out.println("ExampleFilter is filtering the request...");
        
        // 继续执行请求
        chain.doFilter(request, response);
        
        // 在响应返回给客户端之前执行的代码
        System.out.println("ExampleFilter has filtered the response...");
    }

    @Override
    public void destroy() {
        // 清理资源
        System.out.println("ExampleFilter is being destroyed...");
    }
}
  • filterName 指定了过滤器的名称为 “ExampleFilter”。
  • urlPatterns 指定了过滤器应用于以 “/example/” 开头的URL。
  • dispatcherTypes 指定了过滤器应用于 REQUESTFORWARD 类型的请求调度。
  • initParams 指定了两个初始化参数 “param1” 和 “param2” 及其对应的值。
  • asyncSupported 指定过滤器支持异步操作。
  • description 提供了过滤器的描述信息。
  • displayName 指定了过滤器的显示名称。

对于执行顺序
结论:对于被Spring管理的Filter过滤器可以使用@Order注解来设置执行顺序
也可以使用FilterRegistrationBean来包装自定义的Filter

@Bean
	public FilterRegistrationBean<ReqFilter> filterRegistrationBean(ReqFilter reqFilter) {
		FilterRegistrationBean<ReqFilter> filterRegistrationBean = new FilterRegistrationBean<>();
		filterRegistrationBean.setFilter(reqFilter);
		filterRegistrationBean.addUrlPatterns("/*");
		filterRegistrationBean.setOrder(2147483647);
		return filterRegistrationBean;
	}

此外格外注意, @WebFilter声明的Filter,优先级为2147483647(最低优先级)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql中optimizer trace的作用

大家好。对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;我们只能通过EXPLAIN语句查看到最后 优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。于是在MySQL5.6以及之后的版本中&#xff0c;MySQL新增了一个optimi…

量化投资分析平台 迅投 QMT(三)字典数据下载后读取成Dataframe形式

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用如何读取下载好的数据出来上代码历史帖子 迅投 QMT 我目前在使用 两个月前&#xff08;2024年4月&#xff09;迅投和CQF有一个互动的活动&#xff0c;进行了平台的一个网上路演&…

初始C++(类与对象)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 文章目录 前言一.引用二.内联函数三.类和对象总结 前言 之前讲c的命令空间和第一个程序的运行&#xff0c;继…

adb shell service命令与SurfaceFlinger调试

“ 在Android上有丰富的shell命令便于开发者用来调试程序&#xff0c;非常方便&#xff0c;本文简单说明下service命令的用法。” 01 基本用法 首先看一下使用说明&#xff0c;带上参数-h 或 -&#xff1f; $ adb shell service -h Usage: service [-h|-?]service listservi…

STM32 MDK Keil5软件调试功能使用(无需连接硬件)

MDK Keil5 在线仿真STM32&#xff08;无需连接硬件&#xff09; 首先点击工具栏的魔术棒配置一下&#xff1a;&#xff08;记得选择自己的STM32芯片类型&#xff09; 开启调试 使用逻辑分析仪查看IO输出 会打开这个界面&#xff0c;点击左边的setup按钮 会打开这个窗口&am…

交易量突破 3000 亿美元,去中心化衍生品协议 APX Finance 成最大的黑马?

“APX Finance 总交易量现已突破 3000 亿美元&#xff0c;已然成为链上衍生品赛道的主力军” 自 2021 年链上衍生品市场进入萌芽期以来&#xff0c;该板块始终保持着较高的市场增速&#xff0c;即便如此该领域仍旧存在极大的发展空间。一方面&#xff0c;衍生品板块交易量目前占…

【Kubernetes】k8s集群的污点、容忍、驱逐 以及排障思路

污点和容忍以及驱逐 一、污点&#xff08;Taint&#xff09; 污点介绍 节点亲和性&#xff0c;是Pod的一种属性&#xff08;偏好或硬性要求&#xff09;&#xff0c;它使Pod被吸引到一类特定的节点。Taint 则相反&#xff0c;它使节点能够排斥一类特定的 Pod。 Taint 和 Tol…

Docker 常用命令以及镜像选择

前言-与正文无关 生活远不止眼前的苦劳与奔波&#xff0c;它还充满了无数值得我们去体验和珍惜的美好事物。在这个快节奏的世界中&#xff0c;我们往往容易陷入工作的漩涡&#xff0c;忘记了停下脚步&#xff0c;感受周围的世界。让我们一起提醒自己&#xff0c;要适时放慢脚步…

PS系统教程12

画笔模式-绘画模式 相反组&#xff1a;理解一组即可 叠加、柔光重点理解&#xff0c;后面只是细微的差别差值-排除相当于胶卷留下的底片那样的效果。 正常和溶解的对比 正常-背后 效果&#xff1a;重叠的部分在就图层后面。 清楚与橡皮擦一样。 变暗 原理&#xff1a;比这个…

数学建模笔记

数学建模 定义角度 数学模型是针对参照某种事物系统的特征或数量依存关系&#xff0c;采用数学语言&#xff0c;概括地或近似地表述出的一种数学结构&#xff0c;这种数学结构是借助于数学符号刻画出来的某种系统的纯关系结构。从广义理解&#xff0c;数学模型包括数学中的各…

Linux系统之mv命令的基本使用

Linux系统之mv命令的基本使用 一、mv命令介绍1. mv命令简介2. mv命令的使用结果 二、mv命令的使用帮助1. 在命令行的帮助信息2. mv常用选项 三、mv命令的基本使用1. 创建源目录和目标目录2. 新建测试文件3. 将源目录文件复制到目标目录4. 将文件进行改名5. 将目录的所有文件转移…

Windows下使用Airsim+QGC进行PX4硬件在环HITL(三)

Windows下使用AirsimQGC进行PX4硬件在环HITL This tutorial will guide you through the installation of Airsim and QGC on Windows, so that the hardware-in-the-loop experiment can be conducted. Hardware-in-the-Loop (HITL or HIL) is a simulation mode in which nor…

功效系数法

功效系数法&#xff08;Efficacy Coefficient Method&#xff09;是一种综合评价方法&#xff0c;它根据多目标规划的原理&#xff0c;对每个评价指标确定一个满意值和不允许值&#xff0c;以满意值为上限&#xff0c;以不允许值为下限。计算各指标实现满意值的程度&#xff0c…

以太网扫盲(四)phy驱动link up流程分析

1. 简介 在调试网口驱动的过程中发现phy芯片的驱动框架结构还有点复杂&#xff0c;不仔细研究的话还不好搞懂&#xff0c;另外百度到的资料也不够全面&#xff0c;这篇就总结梳理一下这方面的知识。 我们知道一个 phy 驱动的原理是非常简单的&#xff0c;一般流程如下&#x…

AI视频教程下载:给初学者的ChatGPT提示词技巧

你是否厌倦了花费数小时在可以通过强大的语言模型自动化的琐碎任务上&#xff1f;你是否准备好利用 ChatGPT——世界上最先进的语言模型——并将你的生产力提升到下一个水平&#xff1f; ChatGPT 是语言处理领域的游戏规则改变者&#xff0c;它能够理解并响应自然语言&#xf…

[笔记] 记录docker-compose使用和Harbor的部署过程

容器技术 第三章 记录docker-compose使用和Harbor的部署过程 容器技术记录docker-compose使用和Harbor的部署过程Harborhttps方式部署&#xff1a;测试环境部署使用自签名SSL证书https方式部署&#xff1a;正式环境部署使用企业颁发的SSL证书给Docker守护进程添加Harbor的SSL证…

C++面向对象-继承,多态,重载

目录 零. 简介 一. 继承 1.基类,派生类 2.访问控制和继承: 3.多继承 二. 多态 关键字 virtual override : 用例:工厂模式 三. 重载 函数重载: 操作符重载: 零. 简介 继承&#xff1a;允许一个类从另一个类获取属性和方法。子类可以继承父类的特性&#xff0c;并可以…

python11 序列的相关操作

枚举遍历 序列的相关操作 text "hello,python" # in 判断字符是否在序列中&#xff0c;存在返回true,否则返回false print(p是否存在:,(p in text)) print(a是否存在:,(a in text)) # not in 判断字符不在序列中&#xff0c;不存在返回true,否则返回false print(p不…

代码随想录——二叉搜索树的最近公共祖先(Leetcode235)

题目链接 普通递归法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode…