Spring Boot中文乱码需四步解决:①检查Response Headers中Content-Type是否含charset=UTF-8;②application.yml中配置server.servlet.encoding和spring.http.encoding的charset、enabled、force均为UTF-8和true;③添加server.tomcat.uri-encoding: UTF-8解决GET参数乱码;④拦截器中手动设置response.setCharacterEncoding("UTF-8")和setContentType。

Spring Boot接口返回中文变成???、饼饿,Postman里看着正常但浏览器一访问就乱码,改完配置发现拦截器里还是乱码,再加个produces又忘了其他接口——这不是配置漏了,是没抓住Spring Boot编码决策链的根节点。
先锁定乱码发生的真正环节
打开浏览器开发者工具→Network→点开一个乱码接口→看Response Headers里的Content-Type字段。如果显示text/html;charset=ISO-8859-1或application/json后面没带;charset=UTF-8,说明响应头根本没声明UTF-8;如果显示application/json;charset=UTF-8但内容仍是乱码,问题出在Tomcat底层解码环节。
这一步必须做,否则所有后续配置都是蒙眼调试。
全局强制UTF-8(覆盖所有路径)
在application.yml中添加以下四行,缺一不可:
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
【force: true 是关键】它让Spring Boot彻底忽略客户端Accept头和请求参数编码,强制所有请求/响应走UTF-8管道。没有它,浏览器发Accept: text/html时依然会 fallback 到 ISO-8859-1。
如果你用的是application.properties,写成:
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
补全Tomcat URI解码(专治GET乱码)
仅靠上面配置,GET请求带中文参数(如/api/user?name=张三)仍可能乱码,因为Tomcat默认用ISO-8859-1解码URI。
在application.yml追加:
server:
tomcat:
uri-encoding: UTF-8
这行直接告诉嵌入式Tomcat:收到的所有URL路径和查询参数,一律按UTF-8解码。不加这句,前端传%E5%BC%A0%E4%B8%89过来,后端拿到的还是å¼ ä¸‰。
拦截器中手动设编码(最后一道保险)
当拦截器里直接调用response.getWriter().write()返回JSON字符串时,Spring的全局编码配置不生效——它只管Controller层返回值,不管Servlet API原生输出。
在拦截器的preHandle或afterCompletion中,写这两行:
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
注意:这两行必须写在getWriter().write()之前,顺序错了无效。
验证是否真正生效
① 启动应用,用curl模拟浏览器最典型的乱码场景:curl -H "Accept: text/html" http://localhost:8080/api/test
② 查看返回头是否有Content-Type: application/json;charset=UTF-8
③ 查看响应体中文是否正常显示
④ 再用Postman发Accept: application/json,对比两者响应头是否一致
⑤ 在浏览器地址栏直接访问该接口,确认不再出现???或饼
全部通过,说明从Tomcat底层到HTTP响应头再到字符流输出,整条链路已统一为UTF-8。


















