You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

org.json库转换含扩展emoji的JSON字符串异常问题求助

解决org.json解析扩展Emoji显示乱码问题

问题本质

你遇到的乱码是因为Unicode代理对未被正确合并。像🎉、😍这类扩展Emoji属于Unicode补充平面字符,在Java字符串中以代理对(两个UTF-16编码单元,比如\uf389\uf60d对应🎉)存在。org.json库默认解析时不会处理这种代理对,直接将两个编码单元作为独立字符输出,就会显示成乱码或异常符号。


解决方案

方案1:手动修复代理对为完整Emoji字符

写一个工具方法,遍历字符串并合并代理对为完整的Unicode代码点:

public static String fixSurrogatePairs(String input) {
    StringBuilder sb = new StringBuilder();
    int i = 0;
    while (i < input.length()) {
        char c = input.charAt(i);
        // 检测高代理字符(范围:U+D800 至 U+DBFF)
        if (Character.isHighSurrogate(c) && i + 1 < input.length()) {
            char lowSurrogate = input.charAt(i + 1);
            if (Character.isLowSurrogate(lowSurrogate)) {
                // 合并代理对为完整的Unicode代码点
                int codePoint = Character.toCodePoint(c, lowSurrogate);
                sb.appendCodePoint(codePoint);
                i += 2;
                continue;
            }
        }
        sb.append(c);
        i++;
    }
    return sb.toString();
}

使用示例:

String content = "[{  \"message\":\"This year\\u2019s #SexiestManAlive goes to @chrisevans \\uf389\\uf60d \\u2026they did this one for us \\uf979\\n(\\uf4f8: @mschwartzphoto x @people )\"}]";
JSONArray jsonArray = new JSONArray(content);
JSONObject obj = jsonArray.getJSONObject(0);
// 取出原始字符串后修复代理对
String fixedMessage = fixSurrogatePairs(obj.getString("message"));
System.out.println(fixedMessage);

方案2:替换为支持代理对的JSON库

org.json是较老旧的库,对Unicode补充平面支持有限。换用Gson或Jackson这类现代JSON库,它们默认会正确处理代理对,无需手动修复:

用Gson实现
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class EmojiFixDemo {
    public static void main(String[] args) {
        String content = "[{  \"message\":\"This year\\u2019s #SexiestManAlive goes to @chrisevans \\uf389\\uf60d \\u2026they did this one for us \\uf979\\n(\\uf4f8: @mschwartzphoto x @people )\"}]";
        Gson gson = new Gson();
        JsonArray jsonArray = gson.fromJson(content, JsonArray.class);
        JsonObject obj = jsonArray.get(0).getAsJsonObject();
        String message = obj.get("message").getAsString();
        System.out.println(message);
    }
}
用Jackson实现
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class EmojiFixDemo {
    public static void main(String[] args) throws Exception {
        String content = "[{  \"message\":\"This year\\u2019s #SexiestManAlive goes to @chrisevans \\uf389\\uf60d \\u2026they did this one for us \\uf979\\n(\\uf4f8: @mschwartzphoto x @people )\"}]";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonArray = mapper.readTree(content);
        String message = jsonArray.get(0).get("message").asText();
        System.out.println(message);
    }
}

为什么org.json会出现这个问题

org.json库的设计年代较早,对Unicode补充平面的代理对处理逻辑缺失。它在解析\uXXXX转义字符时,仅将其转换为单个UTF-16字符,没有检测并合并代理对(高代理+低代理),导致补充平面的Emoji被拆分为两个独立字符,最终显示乱码。

内容的提问来源于stack exchange,提问作者G SriHAri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:10:22