我有以下示例类:
class Zoo {
public Collection<? extends Animal> animals;
}
序列化时,我尝试尽可能多地序列化类型信息:
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
我得到以下JSON:
[
"com.bp.samples.json.generics.Zoo",
{
"animals": [
"java.util.ArrayList",
[
[
"com.bp.samples.json.generics.Bird",
{
"name": "bird-1",
"wingSpan": "6 feets",
"preferredFood": "food-1"
}
],
[
"com.bp.samples.json.generics.Cat",
{
"name": "cat-1",
"favoriteToy": "toy-1"
}
],
[
"com.bp.samples.json.generics.Dog",
{
"name": "dog-1",
"breed": "bread-1",
"leashColor": "black"
}
]
]
]
}
]
当涉及反序列化时,尝试:
mapper.readValue(new File("./DataFiles/Zoo-2.json"), Zoo.class);
导致以下异常:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:
Can not deserialize instance of com.bp.samples.json.generics.Zoo out of START_ARRAY toke
并尝试做:
mapper.readValue(new File("./DataFiles/Zoo-2.json"),
new TypeReference<Collection<? extends Animal>>() {});
结果:
Can not construct instance of com.bp.samples.json.generics.Animal,
problem: abstract types either need to be mapped to concrete types, have custom
deserializer, or be instantiated with additional type information
at [Source: ./DataFiles/Zoo-2.json; line: 2, column: 5]
当然,编写自定义反序列化器可以解决问题,但如果没有自定义反序列化器,是否需要反序列化?
谢谢, Behzad
答案 0 :(得分:2)
我的第一次尝试应该尽我所能。我能想到的唯一解释是你试图使用不同配置的ObjectMapper
进行反序列化:两者都必须以相同的方式启用默认类型(因为这是控制是否包含类型信息的因素)。
如果您使用相同的映射器实例(或相同配置),您可能需要提交错误报告,以便诊断和修复问题。
答案 1 :(得分:1)
创建用于反序列化的ObjectMapper实例的类型信息。你想要反序列化到Zoo而不是动物集合,所以第一个代码snipet是正确的。
您可能还想尝试Genson lib。 我刚用它检查了你的例子,一切似乎都运行正常。 要在Genson中启用多态类型支持,您需要配置genson实例:
Genson genson = new Genson.Builder().setWithClassMetadata(true).create();