这是一个需要 JSON 处理器的问题,因为这将提供最可靠、最简单的解决方案。 Java 没有内置 JSON 处理,因此需要第三方库。一个常用的 Java JSON 库是Jackson。
由于此特定请求涉及使用任意数据格式,Jackson Databind 库中的杰克逊树模型非常适合。
String delimitedJson = "{\"id\": 1, \"data\": {}}\n"
+ "{\"id\": 1, \"data\": {\"time\": 43}}\n"
+ "{\"id\": 1, \"data\": {\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}}";
StringBuilder output = new StringBuilder();
JsonMapper jsonMapper = JsonMapper.builder().build();
MappingIterator<ObjectNode> i =
jsonMapper.readerFor(ObjectNode.class).readValues(delimitedJson);
i.forEachRemaining((ObjectNode jsonNode) ->
output.append(convertObjectsToString(jsonMapper, jsonNode).toString())
.append("\n"));
System.out.println(output);
// ...
private ObjectNode convertObjectsToString(JsonMapper jsonMapper,
ObjectNode jsonNode) {
ObjectNode copy = jsonMapper.createObjectNode();
jsonNode.fields().forEachRemaining(e -> {
if (e.getValue() instanceof ObjectNode) {
copy.set(e.getKey(), new TextNode(e.getValue().toString()));
} else {
copy.set(e.getKey(), e.getValue());
}
});
return copy;
}
说明
ObjectMapper 类是 Jackson Databind 库中的主要类,JsonMapper 是 JSON 格式的特定实现。
创建实例后(使用JsonMapper.builder().build()),我们使用ObjectReader.readValues(delimitedJson) 遍历换行符分隔列表的每个元素,这会从输入源中读取多个空格分隔的JSON 值。在此示例中,我假设列表中的根级别 JSON 值是对象,而不是例如。字符串或整数。
MappingIterator<ObjectNode> i =
jsonMapper.readerFor(ObjectNode.class).readValues(delimitedJson);
i.forEachRemaining((ObjectNode jsonNode) ->
output.append(convertObjectsToString(jsonMapper, jsonNode).toString())
.append("\n"));
自定义convertObjectsToString 方法返回一个ObjectNode,使用toString() 将其转换为JSON。
convertObjectsToString 方法首先创建一个新的空ObjectNode。对于源节点中的每个属性,如果它不是 JSON 对象类型,则直接将其复制过来。如果是 JSON 对象,则转换为对象的 JSON 字符串表示形式。
private ObjectNode convertObjectsToString(JsonMapper jsonMapper,
ObjectNode jsonNode) {
ObjectNode copy = jsonMapper.createObjectNode();
jsonNode.fields().forEachRemaining(e -> {
if (e.getValue() instanceof ObjectNode) {
copy.set(e.getKey(), new TextNode(e.getValue().toString()));
} else {
copy.set(e.getKey(), e.getValue());
}
});
return copy;
}