我使用Jackson来序列化异构列表。我的列表声明如下:
List<Base> myList = new LinkedList<>();
我在那里有课程Aggregate
和Source
:
myList.add(new Aggregate("count"));
myList.add(new Aggregate("group"));
myList.add(new Source("reader"));
这些类都实现了Base
接口。每个类只有一个带get / set方法的属性:Aggregate
有&#34; type&#34;,Source
有&#34; name&#34;。
我使用此代码尝试序列化列表:
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"
} ]
因此,我不认为我可以对流进行反序列化并使其按预期工作。如何在异构集合中包含每个对象的序列化表示的类信息,以便可以正确地反序列化集合?
答案 0 :(得分:0)
这在http://wiki.fasterxml.com/JacksonPolymorphicDeserialization中有详细描述。阅读它,但这里是最相关的部分。
要包含元素的类型信息,请参阅第1节。有两种选择:
om.enableDefaultTyping()
将存储存储为Object
或抽象类型(包括接口)的元素的类名。请参阅过载文档。这将自动与集合一起使用。
使用Base
注释@JsonTypeInfo
(例如@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
)。要使这个与集合一起使用,您还需要告诉杰克逊您想要存储List<Base>
(并参见第5节):
om.writerWithType(new TypeReference<List<Base>>() {}).writeValue(...);
或
JavaType listBase = objectMapper.constructCollectionType(List.class, Base.class);
om.writerWithType(listBase).writeValue(...);
答案 1 :(得分:0)
我的代码工作正常。
起初,我以为我可以使用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 {
}
这使序列化程序编写了一个&#34;类&#34;具有类值的属性。