使用Gson序列化Map输出JSON时字符串Unicode出现双反斜杠如何解决
问题根源
双反斜杠问题由两个层面的原因叠加导致:
- Java代码中编写的
"\\u53D1"是字符串字面量,编译后实际存储的是\u53D1(单个反斜杠加u53D1的字面组合),并非对应的Unicode字符「发」。只有Java编译期识别的\u前缀会自动转成对应字符,运行期字符串内的\u只会被视为普通字符组合。 - GSON序列化字符串时,会自动将字符串内容中的反斜杠转义为
\\避免JSON语法错误,最终输出就变成了\\u53D1。
另外你提供的代码存在两处语法笔误:create后缺少括号(),FileWriter构造方法末尾的0应为右括号)。
场景1:期望JSON存储实际中文字符(不需要Unicode转义序列)
先将存入Map的Unicode字面量字符串转成实际的Java字符即可,以下是无第三方依赖的转义实现:
// 把字面量\uXXXX格式的字符串转成实际Unicode字符 public static String unescapeUnicode(String input) { StringBuilder sb = new StringBuilder(); int length = input.length(); int i = 0; while (i < length) { char c = input.charAt(i); if (c == '\\' && i + 1 < length && input.charAt(i+1) == 'u') { String hex = input.substring(i+2, i+6); sb.append((char) Integer.parseInt(hex, 16)); i += 6; } else { sb.append(c); i++; } } return sb.toString(); }
修改存入逻辑即可:
resultMap.put("xxxxx", unescapeUnicode("\\u53D1\\u51FA\\u8BE5"));
场景2:期望JSON输出\u53D1\u51FA\u8BE5格式的Unicode转义序列(不直接显示中文)
先完成字符串转义,再自定义GSON的字符串序列化逻辑,强制把非ASCII字符输出为Unicode转义序列即可,完整示例:
LinkedHashMap<String, String> resultMap = new LinkedHashMap<>(); resultMap.put("xxxxx", unescapeUnicode("\\u53D1\\u51FA\\u8BE5")); Gson gson = new GsonBuilder() .setPrettyPrinting() .disableHtmlEscaping() // 自定义字符串序列化逻辑 .registerTypeAdapter(String.class, new TypeAdapter<String>() { @Override public void write(JsonWriter out, String value) throws IOException { if (value == null) { out.nullValue(); return; } StringBuilder escaped = new StringBuilder("\""); for (char c : value.toCharArray()) { if (c < 128) { // 处理ASCII范围内的JSON特殊字符 switch (c) { case '"': escaped.append("\\\""); break; case '\\': escaped.append("\\\\"); break; case '\b': escaped.append("\\b"); break; case '\f': escaped.append("\\f"); break; case '\n': escaped.append("\\n"); break; case '\r': escaped.append("\\r"); break; case '\t': escaped.append("\\t"); break; default: escaped.append(c); } } else { // 非ASCII字符转成\uXXXX格式 escaped.append(String.format("\\u%04x", (int) c)); } } escaped.append("\""); // 直接写入原始内容避免GSON二次转义 out.getDelegate().write(escaped.toString()); } @Override public String read(JsonReader in) throws IOException { return in.nextString(); } }) .create(); try (FileWriter fileWriter = new FileWriter("C:\\Users\\xxxxx\\Desktop\\testGson.json")) { gson.toJson(resultMap, fileWriter); } catch (IOException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Levin Lan
相关产品推荐
相关产品推荐

