Spring Boot应用请求头编码问题:ü转为ü的技术问询
这个问题我之前排查过好几次,本质就是请求头的编码解码不匹配——你的Spring Boot应用把原本UTF-8编码的请求头当成了ISO-8859-1来解析,才会出现ü变成ü的乱码(这是UTF-8字节被ISO-8859-1解码的典型结果)。
你之前配置的spring.http.encoding系列参数其实只管请求体、响应内容的编码,请求头的解析逻辑是由Tomcat(Spring Boot默认容器)单独控制的,所以那些配置没起作用很正常。
具体解决方案
1. 内嵌Tomcat(Spring Boot默认打包方式)
在application.properties里添加以下配置,强制Tomcat用UTF-8解析请求头:
# 保留你已有的编码配置,新增下面两行 server.tomcat.uri-encoding=UTF-8 server.tomcat.use-body-encoding-for-uri=true
server.tomcat.use-body-encoding-for-uri=true是核心:它让Tomcat复用请求体的编码(也就是你配置的UTF-8)来解析URI和请求头,默认情况下Tomcat会用ISO-8859-1解析这些内容。
2. 外部Tomcat(war包部署)
如果是把Spring Boot打包成war包部署到独立Tomcat,需要修改Tomcat的conf/server.xml文件,在Connector节点里添加编码配置:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true"/>
3. 临时排查验证(不推荐长期使用)
如果想快速确认是不是编码解析的问题,可以在代码里手动转码测试:
import java.nio.charset.StandardCharsets; // 假设拿到的firstname是乱码,手动反转码 String correctFirstname = new String(firstname.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
这个方法能临时解决,但还是建议从容器层面配置编码,避免每个请求都要手动处理。
4. 确认对方服务器的请求头编码
虽然你说对方服务器数据显示正常,但还是要确认对方发送请求头时是用UTF-8编码的。有些服务器默认会用ISO-8859-1发送请求头,这时候需要对方也配置成UTF-8编码后再发送。
为什么之前的配置没用?
再补充一下:spring.http.encoding的配置针对的是HttpServletRequest的请求体和HttpServletResponse的响应内容,而请求头的解析是Tomcat在创建HttpServletRequest之前就完成的,所以Spring的编码配置管不到这部分。
内容的提问来源于stack exchange,提问作者Mister Lamp

