【问题标题】:Deserialize a JSON wrapped in an object with an unknown property name using Jackson使用 Jackson 反序列化包装在具有未知属性名称的对象中的 JSON
【发布时间】:2016-06-11 22:24:57
【问题描述】:

我正在使用 Jackson 将 JSON 从 ReST API 反序列化为使用 Jackson 的 Java 对象。

我遇到的问题是一个特定的 ReST 响应返回包装在一个由数字标识符引用的对象中,如下所示:

{
  "1443": [
    /* these are the objects I actually care about */
    {
      "name": "V1",
      "count": 1999,
      "distinctCount": 1999
      /* other properties */
    },
    {
      "name": "V2",
      "count": 1999,
      "distinctCount": 42
      /* other properties */
    },
    ...
  ]
}

到目前为止,我(也许是幼稚的)反序列化 JSON 的方法是创建镜像 POJO,并让 Jackson 简单而自动地映射所有字段,它做得很好。

问题在于,ReST 响应 JSON 具有对我实际需要的 POJO 数组的动态数字引用。我无法创建镜像包装 POJO,因为属性名称本身既是动态的,也是非法的 Java 属性名称。

对于我可以调查的路线的任何和所有建议,我将不胜感激。

【问题讨论】:

  • A) 您的 JSON 无效:缺少 ]。 B)使用对象数组来防止您遇到的问题(如果我对您的示例有足够的了解,因为它有点有限)
  • A) 谢谢;我已经更新了示例 JSON B) 当然,对象数组正是我的目标,但我实际上根本无法访问该数组,因为它被一个在 Java 中既动态又非法的属性名称引用跨度>

标签: java json jackson json-deserialization


【解决方案1】:

我认为最简单的解决方案是使用自定义 JsonDeserializer。它允许您逐步解析输入并仅提取构建对象所需的那些信息。

这是一个如何实现自定义反序列化器的简单示例:custom jackson deserializer

【讨论】:

  • 我担心它会变得丑陋。我会调查一下。
【解决方案2】:

没有自定义反序列化器的最简单的解决方案是使用@JsonAnySetter。 Jackson 将为每个未映射的属性调用带有此注解的方法。

例如:

public class Wrapper {
  public List<Stuff> stuff;

  // this will get called for every key in the root object
  @JsonAnySetter
  public void set(String code, List<Stuff> stuff) {
    // code is "1443", stuff is the list with stuff
    this.stuff = stuff;
  }
}

// simple stuff class with everything public for demonstration only
public class Stuff {
  public String name;
  public int count;
  public int distinctCount;
}

要使用它,你可以这样做:

new ObjectMapper().readValue(myJson, Wrapper.class);

反之,您可以使用@JsonAnyGetter,在这种情况下应该返回Map&lt;String, List&lt;Stuff&gt;)

【讨论】:

    猜你喜欢
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多