Сериализованная строка JSON как значение в JSON - PullRequest
0 голосов
/ 21 ноября 2019

Я хочу, чтобы сериализованная строка JSON при чтении с использованием Джексона рассматривалась просто как строка в моем JSON. Когда я просто экранирую сериализованную строку JSON и использую ее как значение, сериализованная строка обрабатывается как часть JSON и анализируется. Любые идеи о том, как это сделать?

Например:

 "{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"

Я бы хотел, чтобы это читалось в памяти как-то так:

{ payload: "{id:\"some-random-id\",version:554471325}" }

Однако парсер пытается прочитать сериализованную строку как JSON и преобразовать ее в следующее:

{ payload: {id:"some-random-id", version:554471325} }

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

Ответы [ 3 ]

0 голосов
/ 21 ноября 2019

Допустимый JSON - это «набор пар имя / значение», поэтому вам не хватает поля имени и причины его анализа.

Например, если JSON:

{"data": "{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"}

значение data не будет анализироваться.

Кстати. JSON в полезной нагрузке содержит имена ключей без кавычек (вероятно, должно быть {"id": 123, "version": 456})

0 голосов
/ 21 ноября 2019

Я знаю, что это ужасно сформулированный вопрос, и я прошу прощения за это. Тем не менее, я не могу придумать лучший способ сформулировать это, и я не могу предоставить код. Для тех, кто спотыкается об этом и понимает, о чем я спрашиваю, я нашел обходной путь.

Я закодировал сериализованную строку JSON в base64, поэтому Джексон обнаружил ее как строку, а не как объект JSON.

Пример в приведенном выше вопросе выглядит следующим образом:

 "{\"payload\":\"e2lkOiJhbnktZXhlY3V...\"}"

, где e2lkOiJhbnktZXhlY3V... - это представление строки в кодировке base64 "{id:\"some-random-id\",version:554471325}"

0 голосов
/ 21 ноября 2019

ОБНОВЛЕНИЕ: Ответ заменен, поскольку вопрос изменен.

Примеры в вопросе не являются допустимыми в формате JSON. Чтобы увидеть, что это должно быть, давайте сгенерируем его как вложенные строки JSON:

ObjectMapper objectMapper = new ObjectMapper();

Map<String, Object> payloadObj = Map.of("id", "some-random-id", "version", 554471325);
String payloadJson = objectMapper.writeValueAsString(payloadObj);
System.out.println(payloadJson);

Map<String, Object> rootObj = Map.of("payload", payloadJson);
String rootJson = objectMapper.writeValueAsString(rootObj);
System.out.println(rootJson);

String rootString = objectMapper.writeValueAsString(rootJson);
System.out.println(rootString);

Вывод

{"id":"some-random-id","version":554471325}

{"payload":"{\"id\":\"some-random-id\",\"version\":554471325}"}

"{\"payload\":\"{\\\"id\\\":\\\"some-random-id\\\",\\\"version\\\":554471325}\"}"

Третья строка вывода - это то, что должно было бытьтекст первого блока в вопросе.

"{\"payload\":\"{id:\"some-random-id\",version:554471325}\"}"

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

Анализаторы JSON часто снисходительны и в любом случае сделают все возможное, чтобы проанализировать его, но не вините синтаксический анализатор, если он ошибается. Обвините исходный текст и исправьте это, вместо того, чтобы пытаться разобрать плохой JSON.


Оригинальный ответ

Ключи должны быть именами или числами, а нецелые сложные объекты, но если вам нужен JSON в качестве ключа в другом JSON, просто дважды вызовите сериализатор JSON.

Пример

ObjectMapper objectMapper = new ObjectMapper();

Map<String, Object> data1 = Map.of("foo", 42, "bar", List.of(1, 1, 2, 3, 5, 8));
String json1 = objectMapper.writeValueAsString(data1);
System.out.println(json1);

Map<String, Object> data2 = Map.of("Test", "Hello World", json1, 3.14, "End", "Now!");
String json2 = objectMapper.writeValueAsString(data2);
System.out.println(json2);

Примечание: Map.of() и List.of() - это Java 9 +

Выход

{"foo":42,"bar":[1,1,2,3,5,8]}
{"{\"foo\":42,\"bar\":[1,1,2,3,5,8]}":3.14,"Test":"Hello World","End":"Now!"}
...