Как мне избежать строк в JSON? - PullRequest
142 голосов
/ 11 июня 2010

Как вручную создавать строковые поля при создании данных JSON? Должен ли я использовать что-то вроде Apache Commons Lang StringEscapeUtilities.escapeHtml, StringEscapeUtilities.escapeXml, или я должен использовать java.net.URLEncoder?

Проблема в том, что когда я использую SEU.escapeHtml, он не экранирует кавычки, а когда я обертываю всю строку в пару ' s, генерируется неправильный JSON.

Ответы [ 18 ]

2 голосов
/ 01 мая 2012

Я не потратил время на то, чтобы убедиться на 100%, но он сработал для моих входных данных, достаточных для принятия онлайн-валидаторами JSON:

org.apache.velocity.tools.generic.EscapeTool.EscapeTool().java("input")

, хотя он выглядит не лучше, чем org.codehaus.jettison.json.JSONObject.quote("your string")

Я уже просто использую инструменты скорости в своем проекте - мое "ручное JSON" здание было в шаблоне скорости

2 голосов
/ 09 ноября 2014

Использование класса EscapeUtils в API общего языка.

EscapeUtils.escapeJavaScript("Your JSON string");
1 голос
/ 21 июля 2015

Рассмотрим Моши JsonWriter класс. Он имеет прекрасный API и сводит к минимуму копирование, все может быть красиво передано в файл, OutputStream и т. Д.

OutputStream os = ...;
JsonWriter json = new JsonWriter(Okio.buffer(Okio.sink(os)));
json.beginObject();
json.name("id").value(getId());
json.name("scores");
json.beginArray();
for (Double score : getScores()) {
  json.value(score);
}
json.endArray();
json.endObject();

Если вам нужна строка в руке:

Buffer b = new Buffer(); // okio.Buffer
JsonWriter writer = new JsonWriter(b);
//...
String jsonString = b.readUtf8();
0 голосов
/ 19 июня 2018

Apache commons-text теперь имеет StringEscapeUtils.escapeJson (String) .

0 голосов
/ 28 июня 2017

Я думаю, что лучший ответ в 2017 году - использовать API javax.json.Используйте javax.json.JsonBuilderFactory для создания ваших объектов json, затем запишите объекты, используя javax.json.JsonWriterFactory.Очень хорошая комбинация строитель / писатель.

0 голосов
/ 21 октября 2016

с помощью синтаксиса \ uXXXX может решить эту проблему, Google UTF-16 с именем знака, вы можете найти XXXX, например: двойная кавычка utf-16

0 голосов
/ 16 октября 2016

Если вам нужно экранировать JSON внутри строки JSON, используйте org.json.JSONObject.quote («ваша строка json, которую нужно экранировать»), кажется, работает хорошо

0 голосов
/ 16 сентября 2016

Методы, которые показывают фактическую реализацию, являются ошибочными.У меня нет Java-кода, но для справки, вы можете легко преобразовать этот C # -код:

Предоставлено монопроектом @ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs

public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
    if (string.IsNullOrEmpty(value))
        return addDoubleQuotes ? "\"\"" : string.Empty;

    int len = value.Length;
    bool needEncode = false;
    char c;
    for (int i = 0; i < len; i++)
    {
        c = value[i];

        if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
        {
            needEncode = true;
            break;
        }
    }

    if (!needEncode)
        return addDoubleQuotes ? "\"" + value + "\"" : value;

    var sb = new System.Text.StringBuilder();
    if (addDoubleQuotes)
        sb.Append('"');

    for (int i = 0; i < len; i++)
    {
        c = value[i];
        if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
            sb.AppendFormat("\\u{0:x4}", (int)c);
        else switch ((int)c)
            {
                case 8:
                    sb.Append("\\b");
                    break;

                case 9:
                    sb.Append("\\t");
                    break;

                case 10:
                    sb.Append("\\n");
                    break;

                case 12:
                    sb.Append("\\f");
                    break;

                case 13:
                    sb.Append("\\r");
                    break;

                case 34:
                    sb.Append("\\\"");
                    break;

                case 92:
                    sb.Append("\\\\");
                    break;

                default:
                    sb.Append(c);
                    break;
            }
    }

    if (addDoubleQuotes)
        sb.Append('"');

    return sb.ToString();
}

Это можетбыть сжатым в

    // https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{

    private static  bool NeedEscape(string src, int i)
    {
        char c = src[i];
        return c < 32 || c == '"' || c == '\\'
            // Broken lead surrogate
            || (c >= '\uD800' && c <= '\uDBFF' &&
                (i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
            // Broken tail surrogate
            || (c >= '\uDC00' && c <= '\uDFFF' &&
                (i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
            // To produce valid JavaScript
            || c == '\u2028' || c == '\u2029'
            // Escape "</" for <script> tags
            || (c == '/' && i > 0 && src[i - 1] == '<');
    }



    public static string EscapeString(string src)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        int start = 0;
        for (int i = 0; i < src.Length; i++)
            if (NeedEscape(src, i))
            {
                sb.Append(src, start, i - start);
                switch (src[i])
                {
                    case '\b': sb.Append("\\b"); break;
                    case '\f': sb.Append("\\f"); break;
                    case '\n': sb.Append("\\n"); break;
                    case '\r': sb.Append("\\r"); break;
                    case '\t': sb.Append("\\t"); break;
                    case '\"': sb.Append("\\\""); break;
                    case '\\': sb.Append("\\\\"); break;
                    case '/': sb.Append("\\/"); break;
                    default:
                        sb.Append("\\u");
                        sb.Append(((int)src[i]).ToString("x04"));
                        break;
                }
                start = i + 1;
            }
        sb.Append(src, start, src.Length - start);
        return sb.ToString();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...