使用Jackson在多态条件下生成Json

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输入文件,然后从文件里读取。这里为了举栗方便,使用控制台替换文件

项目源码免费获取 个人博客,百度网盘地址+提取码,文件无密~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值