问题描述
我使用 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?
解决方法
有几种方法可以做到这一点。
- 使用 JsonNode
- 使用地图
- 使用@JsonAnySetter
- 创建自定义反序列化器
对于您的情况,创建自定义解串器将是更好的选择。
自定义解串器:
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{
}