【问题标题】:Stringify all values in a newline delimited JSON by keys通过键将换行符分隔的 JSON 中的所有值字符串化
【发布时间】:2021-12-23 07:11:30
【问题描述】:

我有一个换行符分隔的 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 映射值字符串化。我该怎么做?

【问题讨论】:

  • 您是要转义引号中的数据,还是真的打算不转义? "{"time": 43}" => "{\"time\": 43}"?
  • 对不起,我已经改成逃跑了。感谢您的评论!

标签: java json amazon-s3 delimiter


【解决方案1】:

这是一个需要 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2018-07-19
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    相关资源
    最近更新 更多