Filter,过滤器,属于Servlet规范,并不是Spring独有的。其作用从命名上也可以看出一二,拦截一个请求,做一些业务逻辑操作,然后可以决定请求是否可以继续往下分发,落到其他的Filter或者对应的Servlet
 简单描述下一个http请求过来之后,一个Filter的工作流程:
- 首先进入filter,执行相关业务逻辑
- 若判定通行,则进入Servlet逻辑,Servlet执行完毕之后,又返回Filter,最后在返回给请求方
- 判定失败,直接返回,不需要将请求发给Servlet

 这次测试用到的依赖:
<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注解即可。

 WebFilter常用属性如下,其中urlPatterns最为常用,表示这个filter适用于哪些url请求(默认场景下全部请求都被拦截)
 @WebFilter注解是Java Servlet规范中用于定义过滤器的注解。它有多个属性,每个属性都有特定的类型和用途。以下是@WebFilter注解的属性、类型和用途的表格:
| 属性名 | 类型 | 用途 | 
|---|---|---|
| filterName | String | 指定过滤器的名称。 | 
| urlPatterns | String[] | 指定过滤器的URL模式(可以是多个)。 | 
| value | String[] | 等同于 urlPatterns,是一个快捷方式(不能同时使用urlPatterns和value)。 | 
| servletNames | String[] | 指定过滤器应用到的Servlet名称。 | 
| dispatcherTypes | DispatcherType[] | 指定过滤器应用到的调度类型,如 REQUEST,FORWARD,INCLUDE,ERROR,ASYNC。 | 
| initParams | WebInitParam[] | 指定过滤器的初始化参数。 | 
| asyncSupported | boolean | 指定过滤器是否支持异步操作,默认为 false。 | 
| description | String | 过滤器的描述信息。 | 
| displayName | String | 过滤器的显示名称。 | 
| smallIcon | String | 过滤器的小图标。 | 
| largeIcon | String | 过滤器的大图标。 | 
下面给出一个具体例子来更好的理解这些注解的使用方法和含义
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 指定了过滤器应用于 REQUEST 和 FORWARD 类型的请求调度。
- 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(最低优先级)



















