在Java中与Jackson一起序列化异构集合



我正在使用杰克逊来序列化异构列表。我的列表声明如下:

   List<Base> myList = new LinkedList<>();

我有AggregateSource的课程:

    myList.add(new Aggregate("count"));
    myList.add(new Aggregate("group"));
    myList.add(new Source("reader"));

这些类都实现Base接口。每个类只有一个带有 get/set 方法的属性:Aggregate 有"类型",Source有"name"。

我使用此代码尝试序列化列表:

    ObjectMapper om = new ObjectMapper();
    om.configure(SerializationFeature.INDENT_OUTPUT, true);
    StringWriter c = new StringWriter();
    om.writeValue(c, myList);
    System.out.println(c);

但我发现输出 JSON 没有任何指示序列化的对象类型:

[ {
  "type" : "count"
}, {
  "type" : "group"
}, {
  "name" : "reader"
} ]

因此,我认为我不可能反序列化流并让它按预期工作。如何包含有关异类集合中每个对象的序列化表示形式的类信息,以便可以正确反序列化集合?

在 http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 中有确切的描述。阅读它,但这是最相关的部分。

要包含元素的类型信息,请参阅第 1 节。有两种选择:

  1. om.enableDefaultTyping()将存储存储为Object或抽象类型(包括接口)的元素的类名。有关重载,请参阅文档。这将自动处理集合。

  2. @JsonTypeInfo注释Base(例如 @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class") )。要使这适用于集合,您还需要告诉 Jackson 您想要存储List<Base>(请参阅第 5 节):

    om.writerWithType(new TypeReference<List<Base>>() {}).writeValue(...); 
    

    JavaType listBase = objectMapper.constructCollectionType(List.class, Base.class);
    om.writerWithType(listBase).writeValue(...);
    
我已经让我

的代码工作了。

起初,我以为我可以使用WRAP_ROOT_VALUE来获取类信息:

   om.writer().with(SerializationFeature.WRAP_ROOT_VALUE).writeValue(c, myList);

这不起作用,因为它只使根项具有类信息,而没有其他信息。我曾希望它会递归地应用。

所以我不得不直接停止使用 List<>,并将我的 List<> 对象包装在它自己的类中。 然后,基接口需要一个修饰来告诉它编写类信息:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="class")
public interface Base {
}

这会让序列化程序编写一个包含类值的"class"属性。

最新更新