【问题标题】:How to deserialize a JSON when having a dynamic root key具有动态根键时如何反序列化 JSON
【发布时间】:2017-01-24 03:52:59
【问题描述】:

我遇到了这个 json 的问题。

{"1234345": [{
   "queue": "XXX",
   "name": "XXXXX",
   "entries": [{
   "points": 54,
   "isInactive": false,
   }],
   "tier": "ASDF"
}]}

但它也可以是这个形状:

{
 "1234345": [{
  "queue": "XXX",
   "name": "XXXXX",
   "entries": [{
   "points": 54,
   "isInactive": false,
   }],
   "tier": "ASDF"
}],
 "22683144": [{
  "queue": "XXX",
   "name": "XXXXX",
   "entries": [{
   "points": 54,
   "isInactive": false,
   }],
   "tier": "ASDF"
  }]
}

根键是一个数组,它可以在每次调用服务时更改。因此它是动态的。

我对此很生气。我听说使用动态键的最佳选择是使用 Map。但在这种情况下,我如何命名将包含该地图的属性?在这种情况下,作为一个数组,我不知道它是否应该是一个地图或如何创建相应的 POJO。有什么帮助吗?

首先我要做的是为条目创建一个类。

public class myEntry {
   public String points;
   public String isInactive;
}

然后是它的容器类。

public class myObject {
   public String queue;
   public String name,
   public myEntry[] entries;
   public String tier;
}

但我卡在这里,我不知道如何继续。

【问题讨论】:

  • 伊克。确实有人搞砸了他们的 JSON 设计。
  • 好的,你能举例说明你打算如何使用输出吗?虽然我大力提倡强静态类型,但这听起来像是 Groovy 动态遍历可能是最不痛苦的选择。
  • "1234345", "22683144" 这些东西应该存储在一个数组中。我同意@chrylis 的观点,即这种 JSON 设计不好。
  • 根号不重要,我可以避免使用它。我真的不需要那个号码。也许我应该重做 json 擦除这些键并正确读取它。是的,设计很糟糕,我真的不知道他们为什么这样做。
  • yehe,但是我如何命名该数组。它不会与任何定义的属性匹配。我不能创建一个名为 1234345 的变量,这个值会在每次调用中改变。

标签: java json dynamic


【解决方案1】:

您总是可以使用Map。考虑一下您在问题中发布的 JSON:

{
  "1234345": [
    {
      "queue": "XXX",
      "name": "XXXXX",
      "entries": [
        {
          "points": 54,
          "isInactive": false
        }
      ],
      "tier": "ASDF"
    }
  ],
  "22683144": [
    {
      "queue": "XXX",
      "name": "XXXXX",
      "entries": [
        {
          "points": 54,
          "isInactive": false
        }
      ],
      "tier": "ASDF"
    }
  ]
}

使用Jackson,一种流行的Java JSON 解析器,它可以被解析成Map<String,Object> 对象:

String json = "{\"1234345\":[{\"queue\":\"XXX\",\"name\":\"XXXXX\",\"entries\":["
            + "{\"points\":54,\"isInactive\":false}],\"tier\":\"ASDF\"}],"
            + "\"22683144\":[{\"queue\":\"XXX\",\"name\":\"XXXXX\",\"entries\":["
            + "{\"points\":54,\"isInactive\":false}],\"tier\":\"ASDF\"}]}";

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = 
    mapper.readValue(json, new TypeReference<Map<String, Object>>() {});

您可以使用 POJO,而不是 Object

public class Foo {

    private String queue;
    private String name;
    private String tier;
    private List<Bar> entries;

    // Getters and setters omitted
}
public class Bar {

    private Integer points;
    private Boolean isInactive;

    // Getters and setters omitted
}

使用 Jackson,您的代码将类似于:

String json = "{\"1234345\":[{\"queue\":\"XXX\",\"name\":\"XXXXX\",\"entries\":["
            + "{\"points\":54,\"isInactive\":false}],\"tier\":\"ASDF\"}],"
            + "\"22683144\":[{\"queue\":\"XXX\",\"name\":\"XXXXX\",\"entries\":["
            + "{\"points\":54,\"isInactive\":false}],\"tier\":\"ASDF\"}]}";

ObjectMapper mapper = new ObjectMapper();
Map<String, List<Foo>> map = 
    mapper.readValue(json, new TypeReference<Map<String, List<Foo>>>() {});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 2022-01-01
    • 2023-01-17
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    相关资源
    最近更新 更多