抽象类使用Jackson序列化

        当java对象中含List<Object>时,如果Object一个抽象类或接口,这里就会出现java多态的现象,比如List<Animal>, 如果Animal是个抽象类,并且有多个子类时,由于List中保存的Animal没有明确指向具体的子类或实现类,json反序列化java对象时就会抛出提示:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:Can not construct instance of Animal, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

        可以使用@JsonTypeInfo与@JsonSubTypes来解决此类问题,通过注解,可以在序列化时,保存具体的类型信息到json中,当json反序列到java对象时,就可以根据具体类型信息创建正确的java对象。

@JsonTypeInfo – indicates details of what type information to include in serialization 指出序列化包含的类型信息细节
@JsonSubTypes – indicates sub-types of the annotated type 指出被注解类型的子类
@JsonTypeName – defines a logical type name to use for annotated class 定义被注解类使用的逻辑名称

      

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Dog.class, name = "dog"),
        @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public class Animal {
    public String name;

    public Animal(String name) {
    }
}

@JsonTypeName("dog")
// 这里在子类中指定的type name必须和抽象类中注解@JsonSubTypes中name属性指定的值保持一致
public class Dog extends Animal {
    public double barkVolume;

    public Dog(String name) {
        super(name);
        barkVolume = 0.5;
    }
}

@JsonTypeName("cat")
public class Cat extends Animal {
    boolean likesCream;
    public int lives;

    public Cat(String name) {
        super(name);
        likesCream = true;
        lives = 10;
    }
}
  
    @Test
    public void whenSerializingPolymorphic_thenCorrect()
            throws JsonProcessingException {
        Zoo.Dog dog = new Zoo.Dog("lacy");
        Zoo zoo = new Zoo(dog);

        String result = new ObjectMapper()
                .writeValueAsString(zoo);

        assertThat(result, containsString("type"));
        assertThat(result, containsString("dog"));
    }

    序列化zoo对象,结果如下:
        {
         "type":"dog",
         "name":"lacy",
         "barkVolume":0
        }

    @Test
    public void whenDeserializingPolymorphic_thenCorrect()
            throws IOException {
        String json = "{\"name\":\"lacy\",\"type\":\"cat\"}";

        Animal animal =
                new ObjectMapper().readerFor(Animal.class).readValue(json);

        assertEquals("lacy", animal.name);
        assertEquals(Cat.class, animal.getClass());
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值