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


相关推荐
nice_lcj5203 小时前
【从零理解 Spring AI · 14】RAG 的四个环节:加载、切分、向量化、检索
java·spring boot·embedding·向量数据库·rag·spring ai·ai应用开发
SomeOtherTime3 小时前
Rust所有权(AI回答)
开发语言·后端·rust
程序员cxuan4 小时前
离谱,AI 大佬顺手搓了个 YouTube ,而我顺手给他搓了个中文插件
人工智能·后端·程序员
学长毕设4 小时前
基于springboot科创竞赛信息平台-附源码
java·spring boot·后端
深蓝AI5 小时前
Gemini Decisions API 来了:一次前向打分取代逐字解码,校准误差 0.0250 才是 agent 分支调用的真门槛
人工智能·后端
聪明的笨猪猪5 小时前
Java 工程案例:AI 生成 @Async 异步线程池踩坑
java·经验分享·面试·ai编程
学长毕设5 小时前
基于SpringBoot公务员考试交流平台-附源码
java·spring boot·后端
IT_陈寒6 小时前
Vue的watch把我坑惨了,原来要这样用才靠谱
前端·人工智能·后端
黃芢輝7 小时前
开源实战:基于 Spring Boot 3 + Vue 3 + Redis 的高校选修课管理系统(志愿填报 + 统一抽签)
后端
小雨的AI中台笔记7 小时前
502 还是 503?「无可用渠道」其实只有三个原因
后端