JsonNode.Parse解析UTF8格式JSON时特殊字符被转义问题
现象本质
这个不是解析错误,也不存在内容损坏:
- 按照JSON标准规范,Unicode字符既可以直接以原字符形式展示,也可以用
\u+4位十六进制码位的转义形式表示。德文字符ß的Unicode码位是U+00DF,因此Maybachstraße和Maybachstra\u00DFe在JSON语义上是完全等价的,解析后得到的字符串值没有任何差异。 - 你看到的转义效果不是解析阶段产生的,而是你将内存中的JsonNode对象序列化为JSON字符串查看时,序列化工具的输出配置导致的显示差异,JsonNode内部存储的字段值本身是正确的原字符。
常见操作误区
- 把序列化输出的显示形式当成了解析后的实际存储内容:你如果直接调用
jsonNode.get("3").asText()打印字段值,会发现输出的就是正确的Maybachstraße 14,不存在转义序列。大部分人看到转义是因为调用了JsonNode的toString()方法、或者使用默认配置的序列化器输出JsonNode内容时,序列化器开启了非ASCII字符自动转义的开关(最常见的是Jackson的ESCAPE_NON_ASCII配置被开启,很多框架内置的ObjectMapper会默认打开这个配置来适配老旧的不支持非ASCII编码的传输链路)。 - 混淆了解析和序列化两个独立流程:原始JSON在被解析成JsonNode的过程中,不会主动把原字符改成转义序列,转义只发生在把内存对象重新转成JSON字符串的输出环节。
调整方法
如果你希望输出JSON字符串时直接显示原字符、不出现Unicode转义,只需要修改对应JSON库的序列化配置即可,以最常用的Jackson为例:
ObjectMapper mapper = new ObjectMapper(); // 关闭非ASCII字符转义 mapper.disable(JsonGenerator.Feature.ESCAPE_NON_ASCII); // 此时输出的JSON字符串会直接保留ß等非ASCII原字符 String outputJson = mapper.writeValueAsString(jsonNode);
补充说明:无论是否开启这个转义配置,业务层面拿到的字段文本值都是完全一致的,转义只是JSON字符串的表示形式差异,不会引发乱码、内容错误等问题。
内容的提问来源于stack exchange,提问作者Marvin Klein
相关产品推荐
相关产品推荐

