我有两个简单的类-Cat和Dog,它们每个都实现了Pet接口。
我的目标是序列化和反序列化Pets列表。
我已经阅读了有关Jackson的多态特征以及其他SO线程的手册: http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html https://www.baeldung.com/jackson-inheritance
显然,我错过了其中的一些重要部分。
虽然序列化工作正常:
Serialized pets:
[{"type":"cat","name":"Oscar"},{"type":"dog","name":"Spot"}]
反序列化引发异常:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `testProj.Cat` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
我的SSCCE:
public class Main {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
//-------------------
//---serialize-------
//-------------------
List<Pet> pets = new ArrayList<Pet>();
pets.add(new Cat("Oscar"));
pets.add(new Dog("Spot"));
String json = null;
try {
json = mapper.writeValueAsString(pets);
} catch (JsonProcessingException e) {
e.printStackTrace();
return;
}
System.out.println("Serialized pets: ");
System.out.println(json);
//-------------------
//----deserialize----
//-------------------
List<Pet> deserializedPets = null;
try {
deserializedPets = mapper.readValue(json, new TypeReference<List<Pet>>() {});
} catch (JsonParseException e) {
e.printStackTrace();
return;
} catch (JsonMappingException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
for (Pet pet : deserializedPets) {
System.out.println(pet);
}
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@Type(value = Cat.class, name = "cat"),
@Type(value = Dog.class, name = "dog")
})
interface Pet {
}
class Cat implements Pet {
private String type;
private String name;
public Cat(String name) {
this.name = name;
this.type = "cat";
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Cat [type=" + type + ", name=" + name + "]";
}
}
class Dog implements Pet {
private String type;
private String name;
public Dog(String name) {
this.name = name;
this.type = "dog";
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog [type=" + type + ", name=" + name + "]";
}
}