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


相关推荐
Dong先生5 分钟前
Harness vibecoding:从 PRD 到可交付代码的结构化工法
后端
再玩一会儿看代码18 分钟前
JUnit 测试框架详解:从实际开发、业务测试到 Java 面试高频问题
java·经验分享·笔记·junit·面试
yxlalm43 分钟前
2.java秒杀项目第二课-后端登录功能
java·开发语言
雪隐1 小时前
用Flutter做背单词APP-03为了给单词库塞满数据,我让AI给我打了上万份工
前端·人工智能·后端
苏三说技术1 小时前
为什么越来越多的人使用PostgreSQL?
后端
Csvn1 小时前
📊 SQL 入门 Day 1:SELECT & WHERE — 数据查询的基本功
后端·sql
不一样的少年_1 小时前
不用框架,手搓 AI Agent:(一) 先让它跑起来
前端·后端·agent
用户526835677902 小时前
《拒绝当背锅侠!写了个 WebHook 中间件,让局域网硬件在服务挂掉时“喊”出来》
后端
亦暖筑序2 小时前
AgentScope-Java 入门:用 SSE 展示评审任务进度
java·agent·ai编程
云技纵横2 小时前
线上报 Deadlock,怎么从日志里找出是哪两条 SQL 打架?
后端