序列化JSON字符串作为JSON中的值

时间:2019-11-21 02:21:34

标签: java json jackson jackson-databind

我希望在使用Jackson读取序列化的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 :(得分:0)

更新: 答案已替换,因为问题已更改。

问题中的示例不是有效的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!"}

答案 1 :(得分:0)

有效的JSON是“一组名称/值对”,因此您缺少的是名称字段,这就是它被解析的原因。

例如,如果JSON是:

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

data的值将不会被解析。

顺便说一句。有效负载中的JSON包含不带引号的键名(应该为{"id": 123, "version": 456}

答案 2 :(得分:0)

我知道这是一个措辞极高的问题,对此我深表歉意。但是,我无法提供更好的措词方式,因此无法提供代码。对于任何偶然发现此问题并理解我的要求的人,我都找到了解决方法。

我将序列化的JSON字符串编码为base64,因此Jackson将其检测为字符串而不是JSON对象。

上面问题中的示例变为:

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

其中e2lkOiJhbnktZXhlY3V...是字符串"{id:\"some-random-id\",version:554471325}"的base64编码表示形式