将换行符中的所有值字符串化 JSON 键

Stringify all values in a newline delimited JSON by keys

我有一个换行符分隔 JSON,我希望使用 Java 将类型映射的值更改为字符串。一个例子是:

{"id": 1, "data": {}}
{"id": 1, "data": {"time": 43}}
{"id": 1, "data": {"class" : {"students" : [{"name" : "Jane"}]}}}

应该改为

{"id": 1, "data": "{}"}
{"id": 1, "data": "{\"time\": 43}"}
{"id": 1, "data": "{\"class\" : {\"students\" : [{\"name\" : \"Jane\"}]}}"}

我希望将所有 data 映射值字符串化。我该怎么做?

这是一个需要 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 class 是 Jackson Databind 库中的主要 class,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 方法 returns 一个 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;
}