JSON ORDER_MAP_ENTRIES_BY_KEYS 无法一致工作

问题描述 投票:0回答:2

我正在尝试 ORDER_MAP_ENTRIES_BY_KEYS,按照我在这个问题中读到的内容:

[Jackson JsonNode 到带有排序键的字符串

但打印 JsonNode 对象时似乎不起作用。

例如以下代码:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

HashMap<String,String> personHashMap = new HashMap<String,String>();
personHashMap.put("First", "Joe");
personHashMap.put("Last", "Bloe");
personHashMap.put("Age",  "32");
System.out.println("-- Printing personHashMap         gives:\n"+mapper.writeValueAsString(personHashMap));

String personJsonNode =
    "{\"Last\": \"Bloe\", \"First\": \"Joe\", \"Age\": \"32\"}";
JsonNode personJsonObj = mapper.readTree(personJsonNode);
System.out.println("-- Printing personJsonNode     gives:\n"+mapper.writeValueAsString(personJsonObj));

打印以下输出:

-- Printing personHashMap gives:

{
  "Age" : "32",
  "First" : "Joe",
  "Last" : "Bloe"
}
-- Printing personJsonNode gives:

{
  "Last" : "Bloe",
  "First" : "Joe",
  "Age" : "32"
}

注意 person personHashMap 是如何按键排序的,而不是 personJsonNode 对象。

我做错了什么?谢谢。

java json
2个回答
12
投票

这是因为

ORDER_MAP_ENTRIES_BY_KEYS
仅适用于
Maps
,而不适用于
JsonNodes
(这是一个奇怪的设计决策,但是......)。这就是为什么您引用的答案在字符串化之前将
JsonNode
树转换为
Object
。您需要在代码中执行相同的操作。


0
投票

调整nodeFactory以使用排序

TreeMap
而不是默认的
LinkedHashMap
对我来说是成功的。我在 @cowtowncoder 媒体博客中找到了这个解决方案。

static class SortingNodeFactory extends JsonNodeFactory {
    @Override
    public ObjectNode objectNode() {
      return new ObjectNode(this, new TreeMap<String, JsonNode>());
    }
}
ObjectMapper mapper = JsonMapper.builder()
    .nodeFactory(new SortingNodeFactory())
    .build();
JsonNode root = mapper.readTree("{\"b\":1,\"a\":2}");
// assertEquals("{\"a\":2,\"b\":1}", mapper.writeValueAsString(root));

如果您使用 Kotlin,您可以这样构建映射器:

private val jacksonMapper: ObjectMapper = JsonMapper
    .builder()
    .nodeFactory(object : JsonNodeFactory(true) {
        override fun objectNode(): ObjectNode {
            return ObjectNode(this, sortedMapOf<String, JsonNode>())
        }
    })
    .build()
    .apply {
        configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
        configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true)
        ...
    }
© www.soinside.com 2019 - 2024. All rights reserved.