Как заставить JSONObject.put (..) JSON-lib экранировать строку, содержащую JSON? - PullRequest
7 голосов
/ 27 мая 2011

При использовании JSONObject в JSON-lib, как я могу помешать методу put хранить строку, которая содержит JSON как JSON, а не как экранированную строку?

Дляэкземпляр:

JSONObject obj = new JSONObject();
obj.put("jsonStringValue","{\"hello\":\"world\"}");
obj.put("naturalStringValue", "\"hello world\"");
System.out.println(obj.toString());
System.out.println(obj.getString("jsonStringValue"));
System.out.println(obj.getString("naturalStringValue"));

печатает:

{"jsonStringValue":{"hello":"world"},"naturalStringValue":"\"hello world\""}
{"hello":"world"}
"hello world"

, и я хочу напечатать:

{"jsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""}
{"hello":"world"}
"hello world"

Да, я понимаю, что это противно.Однако это поддерживает конвейер сериализации JSON, для которого, для обеспечения взаимодействия, это ожидаемое поведение.В некоторых случаях мы будем сериализовать пользовательский ввод, который может содержать / содержать действительный JSON.Мы бы не хотели, чтобы пользовательский ввод стал частью объекта JSON, с которым мы сериализуем указанный ввод.

Ручное экранирование не работает, потому что JSON-lib экранирует символы \:

JSONObject obj = new JSONObject();
obj.put("naturalJSONValue","{\"hello\":\"world\"}");
obj.put("escapedJSONValue", "{\\\"hello\\\":\\\"world\\\"}");
System.out.println(obj.toString());
System.out.println(obj.getString("naturalJSONValue"));
System.out.println(obj.getString("escapedJSONValue"));

Вывод:

{"naturalJSONValue":{"hello":"world"},"escapedJSONValue":"{\\\"hello\\\":\\\"world\\\"}"}
{"hello":"world"}
{\"hello\":\"world\"}

На этом этапе любые обходные пути для ручного выборочного экранирования сложного объекта JSON будут полностью сводить на нет значение использования JSON-lib в первомplace.

Также я понимаю, что этот вопрос задавался до , но, к сожалению, я не могу так легко принять его ответ.JSON-lib является широко используемой зависимостью во многих областях моего проекта, и замена ее была бы большой задачей.Мне нужно быть абсолютно уверенным, что с помощью JSON-lib невозможно достичь этой цели, прежде чем я смогу совершить обмен на Джексона, Simple-JSON или Gson.

Ответы [ 2 ]

5 голосов
/ 30 мая 2011

Это сработало для меня с json-lib 2.4:

System.out.println(
    new JSONStringer()
        .object()
            .key("jsonStringValue")
                .value("{\"hello\":\"world\"}")
            .key("naturalStringValue")
                .value("\"hello world\"")
        .endObject()
    .toString());

Вывод:

{"jsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""}

Это возможное решение для вас?

UPDATE:

Пересмотрел мой ответ с возможным решением

2 голосов
/ 03 июня 2011

Используйте одинарные кавычки для цитирования строки. Из документации :

Строки могут быть заключены в кавычки '(одинарные кавычки).

Строки вообще не нужно заключать в кавычки, если они не начинаются с кавычки или одинарной кавычки, и если они не содержат начальных или конечных пробелов и если они не содержат ни одного из этих символов: {} [] знак равно # и если они не похожи на числа и не являются зарезервированными словами true, false или null.

Итак, изменив ваш пример:

net.sf.json.JSONObject obj = new net.sf.json.JSONObject();
obj.put("jsonStringValue","{\"hello\":\"world\"}");
obj.put("quotedJsonStringValue","\'{\"hello\":\"world\"}\'");
obj.put("naturalStringValue", "\"hello world\"");
System.out.println(obj.toString());
System.out.println(obj.getString("jsonStringValue"));
System.out.println(obj.getString("quotedJsonStringValue"));
System.out.println(obj.getString("naturalStringValue"));

Выдает:

{"jsonStringValue":{"hello":"world"},"quotedJsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""}
{"hello":"world"}
{"hello":"world"}
"hello world"

Обратите внимание, что quotedJsonStringValue обрабатывается как строковое значение, а не как JSON, и отображается в кавычках в выходном JSON.

...