Json Polymorphism
Jackson提供了一种在序列化java对象时维护子类信息的方式。这使得重新创建子类成为可能。类别信息可以作为Json属性被存储。在下面的例子里,我们会创建一个Zoo,拥有一个动物列表。动物可能是大象或者狮子,并且它们都是Animal抽象类的子类。当反序列化时,我们希望创建的是确切的子类。我们也展示了@JsonTypeInfo以及@JsonSubType注解的用法。
数据序列化以及多态栗子
//反序列化,数据来自序列化结果
public static void main(String[] args) throws IOException {
String content="{\n" +
" \"name\" : \"Samba Wild Park\",\n" +
" \"city\" : \"Paz\",\n" +
" \"animals\" : [ {\n" +
" \"@class\" : \"com.xiaomo.util.json.example.list_serialization.Lion\",\n" +
" \"name\" : \"Simba\",\n" +
" \"sound\" : null,\n" +
" \"type\" : null,\n" +
" \"endangered\" : false\n" +
" }, {\n" +
" \"@class\" : \"com.xiaomo.util.json.example.list_serialization.Elephant\",\n" +
" \"name\" : \"Manny\",\n" +
" \"sound\" : null,\n" +
" \"type\" : null,\n" +
" \"endangered\" : false\n" +
" } ]\n" +
"}";
ObjectMapper mapper = new ObjectMapper();
Zoo zoo = mapper.readValue(content, Zoo.class);
System.out.println(zoo);
}
//序列化
public static void main(String[] args) throws IOException {
// let start creating the zoo
Zoo zoo = new Zoo("Samba Wild Park", "Paz");
Lion lion = new Lion("Simba");
Elephant elephant = new Elephant("Manny");
List<Animal> animals = new ArrayList<>();
animals.add(lion);
animals.add(elephant);
zoo.setAnimals(animals);
ObjectMapper mapper = new ObjectMapper();
mapper.writerWithDefaultPrettyPrinter().writeValue(System.out, zoo);
}
@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
public class Zoo {
public String name;
public String city;
public List<Animal> animals;
@JsonCreator
public Zoo(@JsonProperty("name") String name, @JsonProperty("city") String city) {
this.name = name;
this.city = city;
}
public void setAnimals(List<animal> animals) {
this.animals = animals;
}
@Override
public String toString() {
return "Zoo [name=" + name + ", city=" + city + ", animals=" + animals + "]";
}
}
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class")
@JsonSubTypes({ @Type(value = Lion.class, name = "lion"), @Type(value = Elephant.class, name = "elephant") })
public abstract class Animal {
@JsonProperty("name")
String name;
@JsonProperty("sound")
String sound;
@JsonProperty("type")
String type;
@JsonProperty("endangered")
boolean endangered;
}
public class Lion extends Animal {
private String name;
@JsonCreator
public Lion(@JsonProperty("name") String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getSound() {
return "Roar";
}
public String getType() {
return "carnivorous";
}
public boolean isEndangered() {
return true;
}
@Override
public String toString() {
return "Lion [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType() + ", isEndangered()="
+ isEndangered() + "]";
}
}
public class Elephant extends Animal {
@JsonProperty
private String name;
@JsonCreator
public Elephant(@JsonProperty("name") String name) {
this.name = name;
}
public String getName() {
return name;
}
public String getSound() {
return "trumpet";
}
public String getType() {
return "herbivorous";
}
public boolean isEndangered() {
return false;
}
@Override
public String toString() {
return "Elephant [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType()
+ ", isEndangered()=" + isEndangered() + "]";
}
}
译者注:原文栗子中使用的是将json输入文件,然后从文件里读取。这里为了举栗方便,使用控制台替换文件
项目源码免费获取 个人博客,百度网盘地址+提取码,文件无密~