上周三,实习生小陈差点哭出来:
"小马哥,我接口返回的中文全是
???!前端说是我后端的问题,但我代码里明明写了 UTF-8 啊!"
我瞄了一眼他的代码,笑了:"兄弟,你是不是只在 application.properties 里加了 charset=UTF-8?"
他猛点头。
"那难怪!Spring Boot 的中文乱码,从来不是一行配置能搞定的。今天我就带你一次性根治它,连 Postman 测试都给你安排明白!"
🔥 一、先看乱码长啥样(附模拟截图)
这是你最可能遇到的场景:
场景 1:接口返回中文变问号
{
"name": "???",
"message": "????"
}
场景 2:前端传中文,后端收到 å¼ ä¸‰
// controller 里打印
System.out.println(user.getName()); // 输出:å¼ ä¸‰
场景 3:Postman 测试正常,但浏览器访问乱码
"Postman 能显示中文,为啥浏览器不行?"
🤔 二、为什么会有乱码?------ 本质是"编码不一致"
想象一下:
- 你用 GBK 写了一封信(前端发请求)
- 对方用 UTF-8 去读(后端解析)
- 结果:满篇乱码!
在 Web 开发中,至少有 4 个环节可能出问题:
| 环节 | 默认编码 | 风险点 |
|---|---|---|
| 1. 前端页面(HTML/JS) | UTF-8(现代浏览器) | 但 AJAX 可能没设Content-Type |
| 2. HTTP 请求头 | 无强制编码 | 需显式声明charset=UTF-8 |
| 3. Spring Boot 接收参数 | ISO-8859-1(旧版 Tomcat) | 尤其 GET 请求 |
| 4. Spring Boot 返回 JSON | UTF-8(默认) | 但响应头可能没声明 |
💡 关键结论 :
不是"有没有 UTF-8",而是"每个环节是否一致声明 UTF-8"!
🛠️ 三、终极解决方案:3 步统一编码(亲测有效)
✅ 第 1 步:确保 Spring Boot 全局使用 UTF-8
在 application.yml(或 properties)中添加:
server:
servlet:
encoding:
charset: UTF-8
enabled: true
force: true # 👈 强制所有请求/响应使用 UTF-8!
🔍 解释:
force: true是关键!它会让 Spring Boot 忽略客户端传来的编码,强制按 UTF-8 处理- 这相当于给整个应用上了"编码保险"
⚠️ 注意 :Spring Boot 2.3+ 默认已启用 UTF-8,但显式配置更保险!
✅ 第 2 步:Controller 返回 JSON 时,确保响应头带 charset
虽然 Spring Boot 默认返回 UTF-8,但有些浏览器(尤其是 IE)会忽略 body 编码,只看响应头。
解决方案 :让 @RestController 自动带上 Content-Type: application/json;charset=UTF-8
✅ 无需改代码! Spring Boot 已默认做到。
但你可以验证:
@RestController
public class TestController {
@GetMapping("/hello")
public Map<String, String> hello() {
Map<String, String> res = new HashMap<>();
res.put("msg", "你好,世界!");
return res;
}
}
用 浏览器开发者工具 查看响应头:
Content-Type: application/json;charset=UTF-8 ✅
💡 如果没看到
charset=UTF-8,说明你的 Spring Boot 版本较旧,建议升级或手动配置HttpMessageConverter(文末附方案)。
✅ 第 3 步:前端 & Postman 正确发送请求
前端(Axios 示例):
axios.post('/user', {
name: '张三'
}, {
headers: {
'Content-Type': 'application/json;charset=UTF-8' // 👈 显式声明
}
})
Postman 测试:
- 选择
POST - Body → raw → JSON
- 确保右上角编码是
UTF-8(默认就是) - 发送 → 正常显示中文!
❌ 常见错误 :
在 Postman 里选
x-www-form-urlencoded传中文,却不设 charset → 后端收到乱码!
🔍 四、特殊场景:GET 请求中文参数乱码?
GET 请求的参数在 URL 中,Tomcat 默认用 ISO-8859-1 解码!
现象:
GET /search?keyword=张三
// 后端收到:å¼ ä¸‰
解决方案(二选一):
方案 A:前端 encodeURI 编码(推荐)
const keyword = encodeURIComponent('张三');
axios.get(`/search?keyword=${keyword}`);
后端直接用:
@GetMapping("/search")
public String search(String keyword) {
// keyword 已自动解码,正常显示"张三"
}
方案 B:配置 Tomcat URI 编码(全局)
在 application.yml 中加:
server:
tomcat:
uri-encoding: UTF-8
✅ Spring Boot 2.3+ 已默认 UTF-8,但老项目仍需手动配置!
🧪 五、完整测试流程(Postman + 浏览器)
1. 启动项目(确保配置了 force: true)
2. Postman 测试 POST:
- URL:
http://localhost:8080/user - Body: raw → JSON
- 内容:
{"name": "李四"} - ✅ 返回:
{"name":"李四"}
3. 浏览器测试 GET:
- 访问:
http://localhost:8080/hello - ✅ 页面显示:
{"msg":"你好,世界!"}
4. 查看响应头(F12 → Network):
- ✅
Content-Type: application/json;charset=UTF-8
💬 六、写在最后
中文乱码,不是玄学,而是细节的缺失。
记住这三句话:
- 配置里加
force: true- 前端请求显式声明 charset
- GET 参数用
encodeURIComponent
做到这三点,从此告别 ???!
互动时间 :
你被中文乱码坑过吗?是在什么场景下?