【问题标题】:How to write flattening List deserializer with Jackson?如何用 Jackson 编写扁平化列表反序列化器?
【发布时间】:2019-06-27 13:56:34
【问题描述】:

我正在尝试使用 Jackson 将特定结构的 JSON 反序列化为 Java 类。 我有几个这样的课程:

class A {
  private int number1;
  private List<X> list1;
  private int number2;
}

class X {
  private String field1;
  private double value1;
}


class B {
  private String name2;
  private List<Y> list2;
}

class Y {
  private String field2;
}

我从如下外部系统获取 JSON:

{
  "number1": 1,
  "list1": {
    "elements": [{
      "field1": "Field 1 value 1",
      "value1": 2.2
    }, {
      "field1": "Field 1 value 2"
    }]
  },
  "number2": 2,
}


{
  "name2": "Name 2",
  "list2": {
    "elements": [{
      "field2": "Field 2 value 1"
    }]
  }
}

我想要的只是编写一个自定义反序列化器,它可以以一种通用的方式摆脱这个 元素 级别(我的意思是为所有类都有一个反序列化器)。 是否有任何简单的方法可以扩展 StdDeserializer 来实现这一点,或者我必须使用我的自定义算法编写一个全新的反序列化器?

【问题讨论】:

  • 你知道name1有多少别名吗?
  • 我不明白,它有什么变化?这只是一个技术问题。
  • 我们可以通过自定义反序列化器以外的简单方式来实现
  • 一般来说,这些 JSON 可以有任何结构,我更新了上面的示例。有一件事是肯定的,集合将像这样发送: "collection_name": { "elements": [{ ... }] } 我正试图摆脱这个 elements 级别。

标签: java spring jackson


【解决方案1】:

你可以看看这个问题:Jackson - deserialize inner list of objects to list of one higher level 非常相似。我在那里实现了自定义反序列化器,可用于具有内部列表的许多不同类型。您的示例 POJO 可能如下所示:

class A {
    private int number1;

    @JsonDeserialize(using = InnerListDeserializer.class)
    private List<X> list1;
    private int number2;

    // getters, setters
}

编辑
如果您不想使用任何注释或自定义反序列化,您需要创建适合给定JSONPOJO 结构。你需要创建中间POJO

class ListWrapper<T> {

    private List<T> elements;

    // getter, setter, toString, etc
}

现在,您需要以这种方式更新 AB 类:

class A {
    private int number1;
    private ListWrapper<X> list1;
    private int number2;

    // getters, setters, toString
}

class B {

    private String name2;
    private ListWrapper<Y> list2;

    // getters, setters, toString
}

【讨论】:

  • 抱歉迟到的答案。我想更普遍地解决这个问题并且没有杰克逊注释(我想公开没有元数据的纯 POJO 类)。我可以假设外部系统总是像 JSON 示例一样为集合提供服务(具有元素级别)。
  • 引用您的问题:“我想要的只是编写一个自定义反序列化器,它可以以通用方式摆脱这个元素级别”。所以,现在,您不想实现自定义反序列化器并创建一组适合给定JSONPOJO 类?
  • 有点误会。我想在 Jackson 中注册全局反序列化器,以通用方式反序列化所有列表(具有元素级别),这对我来说意味着:模型上没有额外的注释。
  • 我现在明白了。这是一个有点棘手的问题。如您所见,我来自其他问题的自定义反序列化器使用Jsckson 默认反序列化器作为列表。正确扩展它并通过自定义反序列化器反序列化列表并非易事。您需要知道项目的类型并阅读那里使用的所有注释。您可以尝试扩展com.fasterxml.jackson.databind.deser.std.CollectionDeserializer,但更容易使用我的InnerListDeserializer。如果您无法更改课程,请使用MixIn 功能。如果您认为我的回答对您没有帮助,我可以将其删除。
猜你喜欢
  • 1970-01-01
  • 2016-05-17
  • 2011-12-16
  • 2013-08-21
  • 1970-01-01
  • 2019-07-28
  • 2016-01-14
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多