Postman发送含表情JSON报400或乱码,主因是HTTP未显式声明UTF-8编码,服务端误按ISO-8859-1解析;需在Postman设Body编码为UTF-8、Header加Content-Type: application/json; charset=utf-8,并确保后端容器、JSON解析器、数据库均支持UTF-8。

Postman 发送含表情符号的 JSON 时返回 400 或乱码
直接在 Postman 的 raw JSON 中输入 ?、?、?? 等表情,后端收到的可能是 ??、\uFFFD 或直接报 400 Bad Request。根本原因不是 Postman 不支持,而是 HTTP 协议默认不强制 UTF-8 编码,服务端未显式声明字符集时容易按 ISO-8859-1 解析。
实操建议:
- 确保 Postman 的 Body 编码为 UTF-8:粘贴表情前,右键编辑框 → “Encoding” → 选
UTF-8(部分旧版需手动确认) - 在
Headers中显式设置:Content-Type: application/json; charset=utf-8(注意不是只写application/json) - 避免用 Windows 记事本编辑 JSON 再复制——它默认保存为 ANSI/GBK,会悄悄损坏表情字符
- Spring Boot 用户注意:
@RequestBody默认能正确解析 UTF-8,但若用了自定义StringHttpMessageConverter且未设setSupportedMediaTypes包含application/json;charset=utf-8,就会失败
JSON 字符串里写 Unicode 转义序列(如 \uD83D\uDE00)为什么无效
Postman 的 raw + JSON 模式会把 \uD83D\uDE00 当作普通字符串字面量,不会自动转成 ?。这是因为 JSON 规范本身支持 Unicode 转义,但 Postman 并不执行运行时解码——它只是把原始文本发出去,解码责任在服务端 JSON 解析器。
实操建议:
- 想用转义写法,必须确保后端解析库(如 Jackson、Fastjson)开启 Unicode 解码(Jackson 默认开启;Fastjson 1.2.51+ 默认也支持)
- 更稳妥的做法是直接输入原生表情:Postman 本身完全支持 UTF-8 输入,比手写转义更直观、不易出错
- 如果必须用转义(比如从日志里复制),请确认是合法的 UTF-16 代理对(surrogate pair),单个
\uD83D无效,必须成对出现,例如"\uD83D\uDE00"
Spring Boot 接收含表情的 JSON 报错:HttpMessageNotReadableException
典型错误信息:JSON parse error: Invalid UTF-8 start byte 0xf0 或 Could not write JSON: Invalid surrogate pair。这说明 Spring MVC 的消息转换器在读或写阶段遇到了非法字节序列。
常见原因与修复:
Postman 12.27.7 Windows x64 官方安装包,适用于 API 设计、调试、测试与协作。该系列包含 Enterprise 云端性能测试静态 IP 出口能力,以及接口规范标签管理改进,适合受限网络测试与规范资源组织场景。
- Tomcat 嵌入式容器默认未启用 URI 编码统一处理:在
application.properties加server.tomcat.uri-encoding=UTF-8 - 使用
@RequestBody接收String后手动解析(如new JSONObject(jsonStr)),却忘了指定编码:应改用new String(jsonBytes, StandardCharsets.UTF_8) - 反序列化到实体类字段时,数据库字段类型不支持 UTF-8(如 MySQL 的
utf8实际只支持 BMP 字符,需改用utf8mb4) - Fastjson 用户注意:
JSON.parseObject(str, clazz)在低版本中对四字节 emoji 支持不稳定,建议升级到1.2.83+或切换 Jackson
用 Pre-request Script 自动注入表情用于批量测试
需要对同一接口反复发送不同表情组合(比如测试昵称、评论、标签字段),手动改 JSON 效率低还易错。Postman 的 Pre-request Script 可动态生成含表情的 JSON。
示例脚本(插入到请求的 Pre-request Script 标签页):
const emojis = ["?", "?", "?", "?"];
const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)];
const payload = {
"content": `测试内容 ${randomEmoji}`,
"timestamp": new Date().toISOString()
};
pm.variables.set("json_payload", JSON.stringify(payload));
然后在 Body → raw 中写:{{json_payload}},并确保 Header 仍设为 Content-Type: application/json; charset=utf-8。
关键提醒:
-
JSON.stringify()生成的字符串天然是 UTF-8 安全的,无需额外编码 - 不要在脚本里用
unescape()或decodeURIComponent()处理表情,它们不适用于 UTF-8 字节流 - 若需固定表情而非随机,直接赋值字符串即可,如
const payload = {"tag": "✅ 已完成"};
表情符号看似小问题,但涉及编码链路多个环节:Postman 编辑器、HTTP 协议头、Web 容器解码、JSON 解析器、JVM 字符集、数据库字段类型。漏掉任意一环,都可能让 ? 变成 。最省心的做法,是全程坚持 UTF-8 显式声明,少依赖“默认”。










