杰克逊反序列化父对象

问题描述

我使用 jackson 反序列化一个 Java 对象 LivingBeing,其中包含 Animal 类。到目前为止,我直接传递了 Animal 的对象。

class LivingBeing {
@JsonProperty('animal')
Animal animal;
}
class Animal {
@JsonProperty('color')
String color;
}

但是现在,我们已经用类 Cat、Dog 扩展了 Animal 类。

class Cat extends Animal {
@JsonProperty('cat_specific_feature')
String catFeature;
}
class Dog extends Animal {
@JsonProperty('dog_specific_feature')
String dogFeature;
@JsonProperty('dog_special_power')
String dogPower;
}

示例 json:

livingbeing: {animal :{color :”black”}}

livingbeing: {animal :{color :”black”,cat_specific_feature :”someCatFeature”}}

livingbeing: {animal :{color :”black”,dog_specific_feature :”someDogFeature”,dog_special_power:”power”}}

我还不知道什么样的物体会降临到生物身上。我唯一的想法是在 LivingBeing 中使用一些额外的标志,如标志:猫、狗等作为枚举,但不觉得这是一个好的设计。 目前, if(livingbeing.getanimal() instanceOf Cat) 是假的,因为 livingbeing 只知道 Animal 类型。 注意:猫和狗代表差异用例。而且我不能在 Animal 中添加功能”。这只是代表不同用例的示例代码结构。由于函数擦除,Animal 的构造函数重载是不可能的。 如何反序列化 LivingBeing?

解决方法

有几种方法可以做到这一点。

  1. 使用 JsonNode
  2. 使用地图
  3. 使用@JsonAnySetter
  4. 创建自定义反序列化器

Details here

对于您的情况,创建自定义解串器将是更好的选择。

自定义解串器:

public class DogDeserializer extends StdDeserializer<Item> { 

    public DogDeserializer() { 
        this(null); 
    } 

    public DogDeserializer(Class<?> vc) { 
        super(vc); 
    }

    @Override
    public Dog deserialize(JsonParser jp,DeserializationContext ctxt) 
      throws IOException,JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String dogFeature = node.get("dogFeature").asText();
        String dogPower = node.get("dogPower").asText();
      

        return new Dog(dogFeature,dogPower);
    }
}
@JsonDeserialize(using = DogDeserializer.class)
class Dog extends Animal{
}

Details here