【问题标题】:Parsing a json which contains duplicate keys解析包含重复键的 json
【发布时间】:2017-07-23 05:22:00
【问题描述】:

我正在尝试使用 Jackson 库解析具有重复键的无效结构的 json。如果 json 有重复的键,我想将它们提取为 Collection

我要解析的示例(我要解析的实际 json 来自 Wireshark json 导出):

{
    "a": "a",
    "a": {
        "b": {

        },
        "b": true
    }
}

但是,由于这个 json 有重复的键,所以只保留最后一个值:

JsonNode tree = new ObjectMapper().readTree(json);
System.out.println(tree); // {"a":{"b":true}}

我也尝试过支持MultimapGuava 模块,但是它对于嵌套的json 对象不能正常工作。

我之前展示的 json 使用 Guava 模块的示例:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

Multimap read = mapper.readValue(json, Multimap.class);
System.out.println(read); // {a=[a, {b=true}]}

我应该如何使用Jackson 库来解决这个问题?是否有任何其他库可以支持为 java 解析此类 json 结构?

【问题讨论】:

  • 有效的 JSON 没有重复的键,因此解析库不应该按照您的要求工作
  • SyntaxError: Duplicate key 'a' on line 3
  • 重复键是有效的 json。 tools.ietf.org/html/rfc7159 "对象中的名称应该是唯一的",不需要是唯一的。
  • @OneCricketeer 我不知道。 ECMA-404(从 json.org 链接)说:“JSON 语法对用作名称的字符串没有任何限制,不要求名称字符串是唯一的,并且对名称/值的顺序没有任何意义对。这些都是可能由 JSON 处理器或在定义 JSON 用于数据交换的特定用途的规范中定义的语义考虑因素。”

标签: java json jackson


【解决方案1】:

如果你对 json 库很灵活,你可以使用net.sf.json.JSONObject

此库将通过将重复值存储到数组中来保留它们。如果有多个相同的键可用,它将创建一个键,其中所有值都为数组。

而且编码部分也只是一行。使用 net.sf.json.JSONObject 解析 json 后,您可以将其提供给 jackson 库。

JSONObject jsonObject = JSONObject.fromObject( "{ \"a\": \"a\", \"a\": { \"b\": {},\"b\": true}}" );

System.out.println( "net.sf.json.JSONObject: " + jsonObject );

JsonNode jsonNode = new ObjectMapper().readTree( jsonObject.toString() );

System.out.println( "com.fasterxml.jackson.databind.JsonNode" + jsonNode );

输出:

net.sf.json.JSONObject: {"a":["a",{"b":[{},true]}]}
com.fasterxml.jackson.databind.JsonNode{"a":["a",{"b":[{},true]}]}

net.sf.json 的 Maven 依赖

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>

【讨论】:

  • 有没有办法可以删除重复项并将其保留为单个对象而不是数组
  • @AtulSoman 不可能,只要您使用重复的密钥。
【解决方案2】:

您可以使用“jackson”库以流的方式逐个令牌读取json消息令牌,这样它就不会从消息中吃掉任何东西。

【讨论】:

猜你喜欢
  • 2012-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 2020-07-19
相关资源
最近更新 更多