我应该如何转义 JSON 中的字符串?

2022-08-31 06:55:31

手动创建 JSON 数据时,应如何转义字符串字段?我应该使用像Apache Commons Lang那样的东西,还是应该使用?StringEscapeUtilities.escapeHtmlStringEscapeUtilities.escapeXmljava.net.URLEncoder

问题是,当我使用 时,它不会转义引号,当我将整个字符串包装在一对s中时,将生成格式错误的JSON。SEU.escapeHtml'


答案 1

理想情况下,找到一个你的语言的JSON库,你可以向它提供一些适当的数据结构,并让它担心如何转义。它会让你更加理智。如果由于某种原因,你没有你的语言库,你不想使用一个(我不会建议这个¹),或者你正在编写一个JSON库,请继续阅读。

根据 RFC 对其进行转义。JSON 非常自由:您必须转义的唯一字符是 、 和 控件代码(小于 U+0020)。\"

这种转义结构特定于 JSON。您将需要一个特定于 JSON 的函数。所有转义都可以写成该字符的 UTF-16 代码单元¹ 的位置。有一些快捷方式,例如 ,它们也有效。(它们导致更小、更清晰的输出。\uXXXXXXXX\\

有关完整的详细信息,请参阅 RFC

¹JSON 的转义建立在 JS 之上,因此它使用 ,其中 是 UTF-16 代码单元。对于 BMP 之外的码位,这意味着对代理项对进行编码,这可能会有点毛茸茸的。(或者,您可以直接输出字符,因为 JSON 的编码是 Unicode 文本,并且允许这些特定字符。\uXXXXXXXX


答案 2

摘自《抛弃》

 public static String quote(String string) {
         if (string == null || string.length() == 0) {
             return "\"\"";
         }

         char         c = 0;
         int          i;
         int          len = string.length();
         StringBuilder sb = new StringBuilder(len + 4);
         String       t;

         sb.append('"');
         for (i = 0; i < len; i += 1) {
             c = string.charAt(i);
             switch (c) {
             case '\\':
             case '"':
                 sb.append('\\');
                 sb.append(c);
                 break;
             case '/':
 //                if (b == '<') {
                     sb.append('\\');
 //                }
                 sb.append(c);
                 break;
             case '\b':
                 sb.append("\\b");
                 break;
             case '\t':
                 sb.append("\\t");
                 break;
             case '\n':
                 sb.append("\\n");
                 break;
             case '\f':
                 sb.append("\\f");
                 break;
             case '\r':
                sb.append("\\r");
                break;
             default:
                 if (c < ' ') {
                     t = "000" + Integer.toHexString(c);
                     sb.append("\\u" + t.substring(t.length() - 4));
                 } else {
                     sb.append(c);
                 }
             }
         }
         sb.append('"');
         return sb.toString();
     }