(de)序列化杰克逊的嵌套泛型

时间:2014-06-10 14:20:34

标签: java json serialization jackson deserialization

所以我正在寻求使用Jackson对一个对象进行反序列化和序列化。该对象具有层次结构,并且在层次结构的深处有一个

List<T>

其中T是String或其中一个Java数字类。

反序列化通用列表一直是这些论坛上的常见主题,我知道如何构建一个使用mapper.readValue对列表进行反序列化或序列化的映射器。

我不知道该怎么做是因为当我在最顶层调用mapper时,它并没有明确知道它包含的类的参数化,所以它将知道如何在到达包含参数化列表的底层类时调用自定义反序列化器。

省略了getter / setter / constructors的简单示例:

class A {
    String name;
    B thing;
}

class B {
    String command;
    List<C<?>> conditions;
}

class C<T> {
    String type;
    List<T> parameters
}

我想写一个杰克逊的命令,一次性串行A.我一直在使用附加到A的方法:

public String toJSON() throws JsonProcessingException{
    ObjectMapper mapper = new ObjectMapper();
    mapper.enableDefaultTyping();
    return mapper.writeValueAsString(this);
}

但是这有一个已知问题,即泛型集合会丢失其类型信息而不能被反序列化。

我可以使用建议here使用通用参数对给定类进行反序列化,但我不知道如何组合这些解决方案。我希望杰克逊有一些我为C编写的自定义反序列化器,当它到达那个类类型时它可以使用它,否则它可以使用普通的序列化器,它适用于其他类。

1 个答案:

答案 0 :(得分:3)

当Jackson将您的JSON反序列化为A类型的对象时,在对其B字段进行反序列化时会看到以下内容

List<C<?>> conditions;

你(程序员)和杰克逊都不知道C parameters字段的类型。因此,它没有足够的信息来反序列化,就像你想要的那样。相反,它将使用我认为是LinkedHashMap(或类似的东西)的默认类型。

基本上,你唯一的选择是给它提示。 (自定义)使用String的{​​{1}}值序列化对象层次结构以反序列化为。然后,您可以为自定义反序列化器中的每种类型制定不同的策略。

由于您只有几种类型,Class或其中一个String类,因此为每个类编写一个通用类Number和X非泛型类可能会更好。类型

C

并使用一些polymorphic type handling来序列化/反序列化。