在 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 完整请求链路
请求进入顺序:
-
Tomcat
-
Filter(过滤器)
-
Spring DispatcherServlet
-
Interceptor(拦截器 preHandle)
-
Controller
-
Interceptor(postHandle)
-
视图渲染
-
Interceptor(afterCompletion)
-
Filter 后续处理
-
返回响应
一句话:Filter 最前,Interceptor 中间,Controller 最后。
十、Filter VS Interceptor
| 特性 | Filter | Interceptor |
|---|---|---|
| 规范 | Servlet | SpringMVC |
| 范围 | 所有请求 | 只拦截 Controller |
| 时机 | 更早(容器层) | 稍后(Spring层) |
| 能获取Bean | 不能 | 能 |
| 能中断请求 | 能 | 能 |
| 适用场景 | 编码、跨域、限流 | 登录、权限、日志 |
十一、使用建议
- 统一编码、跨域、限流、风控、请求日志 → Filter
- 登录鉴权、权限校验、接口日志 → Interceptor
- 参数校验、返回封装 → Controller + AOP
十二、总结
-
Filter 是Servlet 组件,拦截所有请求
-
核心方法:doFilter
-
注册:@WebFilter、FilterRegistrationBean
-
顺序:Order 越小越先执行
-
请求链路:Filter → Interceptor → Controller