SpringBoot 过滤器(Filter)与请求链路梳理

在 SpringBoot 里,Filter(过滤器)是最底层的请求处理组件,比拦截器更早、更底层。
它能对
所有请求
进行过滤、编码、跨域、日志、限流、请求头处理等。

这一篇我们讲讲Filter 是什么、怎么用、三种注册方式、实战场景、执行顺序、和拦截器的区别、完整请求链路


一、什么是 Filter过滤器?

Filter 是 Servlet 规范中的组件,运行在 Tomcat 容器层。

作用:

  • 对请求进行预处理后处理

  • 过滤、修改请求头 / 响应头

  • 统一编码设置

  • 全局跨域处理

  • 日志、限流、风控

  • 敏感词过滤

特点:

  • 拦截所有请求

    (包括静态资源、图片、HTML)

  • 比 Spring 拦截器更早执行

  • 依赖 Servlet 容器,不依赖 Spring

  • 可以决定是否放行请求


二、Filter 核心方法

只需要实现 Filter 接口,重写 3 个方法:

go 复制代码
1publicinterfaceFilter{
2
3// 初始化:项目启动时执行一次
4voidinit(FilterConfig filterConfig)throwsException;
5
6// 核心过滤逻辑(每次请求都执行)
7voiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsException;
8
9// 销毁:项目关闭时执行一次
10voiddestroy();
11}

99% 场景只需要写 doFilter


三、SpringBoot 注册 Filter 的 3 种方式

方式1:@WebFilter

go 复制代码
1@WebFilter(urlPatterns ="/*", filterName ="demoFilter")
2publicclassDemoFilterimplementsFilter{
3@Override
4publicvoiddoFilter(...){
5// 过滤逻辑
6        chain.doFilter(request, response);// 放行
7}
8}

启动类加:

go 复制代码
1@ServletComponentScan// 扫描Filter
2@SpringBootApplication
3publicclassApp{}

方式2:JavaConfig 注册

go 复制代码
1@Configuration
2publicclassFilterConfig{
3
4@Bean
5publicFilterRegistrationBean<DemoFilter>demoFilter(){
6FilterRegistrationBean<DemoFilter> bean =newFilterRegistrationBean<>();
7        bean.setFilter(newDemoFilter());
8        bean.addUrlPatterns("/*");
9        bean.setOrder(1);// 数字越小越先执行
10return bean;
11}
12}

方式3:Component 自动注册

go 复制代码
1@Component
2@Order(1)
3publicclassDemoFilterimplementsFilter{}

四、统一编码过滤器

go 复制代码
1@WebFilter("/*")
2publicclassEncodingFilterimplementsFilter{
3@Override
4publicvoiddoFilter(ServletRequest request,ServletResponse response,FilterChain chain)throwsException{
5        request.setCharacterEncoding("UTF-8");
6        response.setCharacterEncoding("UTF-8");
7        response.setContentType("application/json;charset=utf-8");
8        chain.doFilter(request, response);
9}
10}

五、请求日志过滤器

go 复制代码
1@Slf4j
2@WebFilter("/*")
3publicclassLogFilterimplementsFilter{
4@Override
5publicvoiddoFilter(ServletRequest req,ServletResponse resp,FilterChain chain)throwsException{
6HttpServletRequest request =(HttpServletRequest) req;
7        log.info("请求地址:{}", request.getRequestURI());
8        log.info("请求方式:{}", request.getMethod());
9        chain.doFilter(req, resp);
10}
11}

六、拦截非法请求(防盗链、黑名单)

go 复制代码
1@Override
2publicvoiddoFilter(ServletRequest req,ServletResponse resp,FilterChain chain)throwsException{
3HttpServletRequest request =(HttpServletRequest) req;
4String ip = request.getRemoteAddr();
5
6if(blackList.contains(ip)){
7        response.getWriter().write("非法请求");
8return;
9}
10    chain.doFilter(req, resp);
11}

七、包装 Request 实现流重复读

go 复制代码
1@Override
2publicvoiddoFilter(ServletRequest req,ServletResponse resp,FilterChain chain)throwsException{
3// 包装 Request,让body可重复读取
4RepeatedReadRequestWrapper wrapper =newRepeatedReadRequestWrapper((HttpServletRequest) req);
5    chain.doFilter(wrapper, resp);
6}

常用于:日志记录、签名校验、全局加密解密。


八、多个 Filter 执行顺序

执行规则:
Order 数字越小,越先执行

执行流程:

go 复制代码
请求 → Filter1 → Filter2 → Controller → Filter2 → Filter1 → 响应

九、SpringBoot 完整请求链路

请求进入顺序:

  1. Tomcat

  2. Filter(过滤器)

  3. Spring DispatcherServlet

  4. Interceptor(拦截器 preHandle)

  5. Controller

  6. Interceptor(postHandle)

  7. 视图渲染

  8. Interceptor(afterCompletion)

  9. Filter 后续处理

  10. 返回响应

一句话:Filter 最前,Interceptor 中间,Controller 最后。


十、Filter VS Interceptor

特性 Filter Interceptor
规范 Servlet SpringMVC
范围 所有请求 只拦截 Controller
时机 更早(容器层) 稍后(Spring层)
能获取Bean 不能
能中断请求
适用场景 编码、跨域、限流 登录、权限、日志

十一、使用建议

  • 统一编码、跨域、限流、风控、请求日志 → Filter
  • 登录鉴权、权限校验、接口日志 → Interceptor
  • 参数校验、返回封装 → Controller + AOP

十二、总结

  1. Filter 是Servlet 组件,拦截所有请求

  2. 核心方法:doFilter

  3. 注册:@WebFilter、FilterRegistrationBean

  4. 顺序:Order 越小越先执行

  5. 请求链路:Filter → Interceptor → Controller


相关推荐
信誓旦旦的程序猿37 分钟前
【量化系统从零构建 #04】存储设计:选型·建库·交易日历
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
yurenpai(27届找实习中)37 分钟前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18
geovindu1 小时前
CSharp: Observer Pattern
开发语言·后端·观察者模式·设计模式·c#·.netcore·行为模式
Flynt2 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端
IT_陈寒2 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
Tangyuewei2 小时前
给老 Spring 项目装个 AI Agent
java·人工智能·spring
她的男孩2 小时前
多租户和数据权限怎么共存?扒完拦截器注册链路,我找到 4 个隐蔽的坑
java·后端·架构
用户8356290780512 小时前
使用 Python 设置 Excel 页眉和页脚
后端·python
步行cgn3 小时前
IoC 控制反转:从概念到 Spring 的实现
后端
爱勇宝3 小时前
没有 Fn 键关触控板?我做了一个双击即用的 Windows 小工具
前端·后端·程序员