百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

炸场!Spring Boot 9 大内置过滤器实战手册:从坑到神

off999 2025-09-21 21:18 3 浏览 0 评论

炸场!Spring Boot 9 大内置过滤器实战手册:从坑到神

在 Java 开发圈摸爬滚打十年,见过太多团队重复造轮子 —— 明明 Spring Boot 自带的过滤器就能解决的问题,偏偏要手写几十行代码。今天就带大家深挖 Spring Boot 内置的 9 个过滤器,从配置到排坑,全是能直接复用的实战经验。

一、先搞懂过滤器的 "生存法则"

很多人分不清过滤器 (Filter) 和拦截器 (Interceptor),其实记住三句话就够了:过滤器是 Servlet 规范的 "老炮儿",作用于所有请求包括静态资源;拦截器是 Spring 的 "后起之秀",只认 Controller 方法。过滤器像小区门卫,管你是住户还是快递员都得查;拦截器则像单元楼门禁,只拦去拜访业主的人。

在 Spring Boot 里注册过滤器有两种姿势:用 @WebFilter+@ServletComponentScan 是 "简单模式",适合快速开发;用 FilterRegistrationBean 是 "专业模式",能精确控制顺序和 URL 匹配,生产环境强烈推荐后者。记住过滤器的生命周期:init () 初始化只执行一次,doFilter () 每次请求都触发,destroy () 销毁时释放资源。

二、9 大过滤器实战拆解

1. CharacterEncodingFilter:终结中文乱码的终极方案

新手常踩的坑:页面提交的中文变成问号,排查半天发现是编码没配置对。这个过滤器就是来救场的,Spring Boot 2.x 默认启用,3.x 需要手动配置。

实战配置要注意两个关键点:

java

@Bean
public FilterRegistrationBean<CharacterEncodingFilter> encodingFilter() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true); // 强制覆盖容器编码,必须设为true
    FilterRegistrationBean<CharacterEncodingFilter> bean = new FilterRegistrationBean<>(filter);
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE); // 优先级要最高
    return bean;
}

曾经接手过一个项目,因为把 forceEncoding 设为 false,Tomcat 的 ISO-8859-1 编码把 UTF-8 覆盖了,导致乱码问题反复出现。记住:这个过滤器必须第一个执行,否则后面的处理都是白搭。

2. HiddenHttpMethodFilter:让表单支持 RESTful 的魔法

HTML 表单天生只认 GET 和 POST,想实现 PUT/DELETE 请求怎么办?这个过滤器能把 POST 请求 "伪装" 成其他方法,只需前端加个隐藏字段:

html

<form action="/user/1" method="post">
    <input type="hidden" name="_method" value="DELETE">
</form>

Spring Boot 3.x 需要手动开启:

yaml

spring.mvc.hiddenmethod.filter.enabled: true

注意它只对 POST 请求生效,且要和 @PathVariable 配合使用。现在前后端分离项目常用 Axios 直接发 PUT 请求,这个过滤器更多用于传统 JSP 项目。

3. FormContentFilter:PUT 请求的表单解析器

Servlet 规范有个坑:PUT 请求的表单数据不会被解析到 request.getParameter () 里。这个过滤器就是来填坑的,它会把表单数据包装成可解析的格式。

在 Spring Boot 3.x 中默认启用,无需额外配置。适合那些还在使用表单提交,但又想遵循 RESTful 规范的老项目。测试时发现,它对 multipart/form-data 类型的支持不太好,文件上传还是乖乖用 POST 吧。

4. RequestContextFilter:让请求信息随处可用

想在 Service 层获取当前请求的 IP 地址?这个过滤器能帮你实现。它通过 RequestContextHolder 把请求上下文绑定到线程,在任何地方都能拿到:

java

HttpServletRequest request = ((ServletRequestAttributes) 
    RequestContextHolder.getRequestAttributes()).getRequest();

它的升级版
OrderedRequestContextFilter 支持设置执行顺序,当需要在其他过滤器中使用请求信息时,一定要让它先执行。曾经在日志拦截器里拿不到请求信息,就是因为没控制好这个过滤器的顺序。

5. CorsFilter:跨域问题的终极解决方案

前后端分离项目必用!比 @CrossOrigin 注解更适合全局配置。复杂场景的配置示例:

java

@Bean
public CorsFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Arrays.asList("https://admin.example.com"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
    config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
    config.setAllowCredentials(true); // 允许带cookie
    config.setMaxAge(3600L); // 预检请求缓存1小时
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", config);
    return new CorsFilter(source);
}

踩过的坑:allowedOrigins 设为 ""时,allowCredentials 必须为 false,否则浏览器会报错。生产环境一定要精确指定允许的源,别图省事用""。

6. ShallowEtagHeaderFilter:带宽杀手的克星

这个过滤器能生成响应内容的哈希值作为 ETag,客户端再次请求时比对 ETag,相同就返回 304,大幅减少数据传输。配置时要注意只对频繁访问且变化少的资源生效:

java

@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> etagFilter() {
    FilterRegistrationBean<ShallowEtagHeaderFilter> bean = new FilterRegistrationBean<>();
    bean.setFilter(new ShallowEtagHeaderFilter());
    bean.addUrlPatterns("/api/reports/*", "/static/docs/*");
    return bean;
}

注意它会增加服务器开销(需要计算哈希),不适合动态内容多的接口。曾经给一个报表接口加了这个过滤器,带宽消耗降了 60%,但服务器 CPU 上升了 5%,需要权衡使用。

7. ForwardedHeaderFilter:反向代理后的 "真实面目"

应用部署在 Nginx 后面时,request.getScheme () 拿到的是 http 而不是 https?这个过滤器能解析 X-Forwarded-* 头信息,还原客户端真实的协议、IP 和端口。

Spring Boot 2.2 + 只需配置:

yaml

server.forward-headers-strategy: FRAMEWORK

在微服务架构中特别重要,不然服务间调用获取到的客户端 IP 都是 Nginx 的地址。记得让 Nginx 配置正确的转发头:

nginx

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

8. ResourceUrlEncodingFilter:静态资源缓存的破局者

前端缓存常导致新功能上线后用户看不到更新,这个过滤器能生成带版本号的资源 URL,如 /style.css 变成 /style-8f4d7b92.css。

配合 Spring 的资源版本策略使用:

java

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/")
                .resourceChain(true)
                .addResolver(new VersionResourceResolver()
                        .addContentVersionStrategy("/**"));
    }
}

这样每次资源内容变化,URL 就会变化,彻底解决缓存更新问题。

9. WelcomePageFilter:首页跳转的隐形推手

这个过滤器默默处理着首页跳转逻辑,当访问根路径时,会自动转发到 index.html。在静态资源目录放个 index.html,就能轻松实现首页功能,无需写 Controller。

如果需要自定义首页,可以通过配置覆盖:

yaml

spring.web.resources.static-locations: classpath:/public/

它的优先级低于 Controller 映射,所以如果有 @RequestMapping ("/"),会优先执行控制器方法。

三、过滤器链的调优秘籍

过滤器多了会影响性能,这几个优化技巧能让你少走弯路:

  1. 精准匹配 URL:用 addUrlPatterns ("/api/") 而不是"/",减少过滤范围。比如编码过滤器需要全局生效,但 ETag 过滤器只需要对特定接口生效。
  2. 控制执行顺序:通过 setOrder () 方法合理排序,推荐顺序:编码过滤器> 上下文过滤器 > CORS 过滤器 > 业务过滤器。曾经因为 CORS 过滤器执行太晚,导致预检请求被其他过滤器拦截,排查了整整一下午。
  3. 禁用不需要的过滤器:Spring Boot 默认启用了一些过滤器,如果用不上可以禁用,比如:

yaml

spring.mvc.formcontent.filter.enabled: false
  1. 异步处理优化:在过滤器中调用 chain.doFilter () 时,如果是异步请求,考虑用 AsyncContext 提高吞吐量。

四、避坑指南:那些年踩过的过滤器陷阱

  1. 过滤器和拦截器执行顺序混淆:过滤器在 DispatcherServlet 之前执行,拦截器在之后,所以拦截器里拿不到过滤器修改后的 request 属性是正常的。
  2. 多个过滤器修改同一属性:比如两个过滤器都想设置 response 头,后执行的会覆盖先执行的,需要注意顺序。
  3. 忘记处理 chain.doFilter ():如果在过滤器中忘记调用这个方法,请求就会被截断,这是新手最容易犯的错误。
  4. 过度使用过滤器:有些功能更适合用 AOP 实现,比如日志记录,过滤器更适合处理与 Servlet 相关的横切逻辑。

结语

Spring Boot 内置的这 9 个过滤器,每一个都解决了实际开发中的痛点问题。很多时候我们不需要从零开始写代码,而是要学会利用好框架提供的工具。记住:优秀的开发者不是写最多代码的人,而是最会用最少代码解决问题的人。

这些过滤器你用过几个?欢迎在评论区分享你的使用经验和踩坑故事,让更多人少走弯路。


感谢关注【AI码力】!

相关推荐

apisix动态修改路由的原理_动态路由协议rip的配置

ApacheAPISIX能够实现动态修改路由(DynamicRouting)的核心原理,是它将传统的静态Nginx配置彻底解耦,通过中心化配置存储(如etcd)+OpenRest...

使用 Docker 部署 OpenResty Manager 搭建可视化反向代理系统

在之前的文章中,xiaoz推荐过可视化Nginx反向代理工具NginxProxyManager,最近xiaoz还发现一款功能更加强大,界面更加漂亮的OpenRestyManager,完全可以替代...

OpenResty 入门指南:从基础到动态路由实战

一、引言1.1OpenResty简介OpenResty是一款基于Nginx的高性能Web平台,通过集成Lua脚本和丰富的模块,将Nginx从静态反向代理转变为可动态编程的应用平台...

OpenResty 的 Lua 动态能力_openresty 动态upstream

OpenResty的Lua动态能力是其最核心的优势,它将LuaJIT嵌入到Nginx的每一个请求处理阶段,使得开发者可以用Lua脚本动态控制请求的生命周期,而无需重新编译或rel...

LVS和Nginx_lvs和nginx的区别

LVS(LinuxVirtualServer)和Nginx都是常用的负载均衡解决方案,广泛应用于大型网站和分布式系统中,以提高系统的性能、可用性和可扩展性。一、基本概念1.LVS(Linux...

外网连接到内网服务器需要端口映射吗,如何操作?

外网访问内网服务器通常需要端口映射(或内网穿透),这是跨越公网与私网边界的关键技术。操作方式取决于网络环境,以下分场景详解。一、端口映射的核心原理内网服务器位于私有IP地址段(如192.168.x.x...

Nginx如何解决C10K问题(1万个并发连接)?

关注△mikechen△,十余年BAT架构经验倾囊相授!大家好,我是mikechen。Nginx是大型架构的必备中间件,下面我就全面来详解NginxC10k问题@mikechen文章来源:mikec...

炸场!Spring Boot 9 大内置过滤器实战手册:从坑到神

炸场!SpringBoot9大内置过滤器实战手册:从坑到神在Java开发圈摸爬滚打十年,见过太多团队重复造轮子——明明SpringBoot自带的过滤器就能解决的问题,偏偏要手写几十...

WordPress和Typecho xmlrpc漏洞_wordpress主题漏洞

一般大家都关注WordPress,毕竟用户量巨大,而国内的Typecho作为轻量级的博客系统就关注的人并不多。Typecho有很多借鉴WordPress的,包括兼容的xmlrpc接口,而WordPre...

Linux Shell 入门教程(六):重定向、管道与命令替换

在前几篇中,我们学习了函数、流程控制等Shell编程的基础内容。现在我们来探索更高级的功能:如何控制数据流向、将命令链接在一起、让命令间通信变得可能。一、输入输出重定向(>、>>...

Nginx的location匹配规则,90%的人都没完全搞懂,一张图让你秒懂

刚配完nginx网站就崩了?运维和开发都头疼的location匹配规则优先级,弄错顺序直接导致500错误。核心在于nginx处理location时顺序严格:先精确匹配=,然后前缀匹配^~,接着按顺序正...

liunx服务器查看故障命令有那些?_linux查看服务器性能命令

在Linux服务器上排查故障时,需要使用一系列命令来检查系统状态、日志文件、资源利用情况以及网络状况。以下是常用的故障排查命令,按照不同场景分类说明。1.系统资源相关命令1.1查看CPU使...

服务器被入侵的常见迹象有哪些?_服务器入侵可以被完全操纵吗

服务器被入侵可能会导致数据泄露、服务异常或完全失控。及时发现入侵迹象能够帮助你尽早采取措施,减少损失。以下是服务器被入侵的常见迹象以及相关的分析与处理建议。1.服务器被入侵的常见迹象1.1系统性能...

前端错误可观测最佳实践_前端错误提示

场景解析对于前端项目,生产环境的代码通常经过压缩、混淆和打包处理,当代码在运行过程中产生错误时,通常难以还原原始代码从而定位问题,对于深度混淆尤其如此,因此Mozilla自2011年开始发起并...

8个能让你的Kubernetes集群“瞬间崩溃”的配置错误

错误一:livenessProbe探针“自杀式”配置——30秒内让Pod重启20次现象:Pod状态在Running→Terminating→CrashLoopBackOff之间循环,重启间隔仅...

取消回复欢迎 发表评论: