我正在尝试使用Jackson来反序列化一些多态对象,但是我不想在JSON中公开类型信息。因此,假设我们有“经典”动物场景:
public interface Animal {
String talk();
}
public class Dog implements Animal {
public String talk() { return "Woof!"; }
}
public class Cat implements Animal {
public String talk() { return "Meow!"; }
}
我还有一个Factory接口和多个Factory实现:
public interface AnimalFactory {
Animal newAnimal();
}
public class DogFactory implements AnimalFactory {
public Animal newAnimal() { return new Dog(); }
}
public class CatFactory implements AnimalFactory {
public Animal newAnimal() { return new Cat(); }
}
由于我不想通过在JSON中使用@JsonTypeInfo
和type
参数来污染实现细节的JSON,所以我只知道两种选择:
@JsonDeserialize(as = Dog.class)
上使用Animal
,但这将需要从API到实现类的显式依赖关系;此外,它总是将JSON反序列化为Dog,而我只想在运行时找到合适的具体实现,因为我不知道哪种具体实现可用; StdDeserializer
子类:public class AnimalDeserializer extends StdDeserializer<Animal> {
// Obtain through dependency injection or other mechanism
private AnimalFactory animalFactory;
public AnimalDeserializer() {
this(null);
}
public AnimalDeserializer(Class<Animal> vc) {
super(vc);
}
@Override
public Animal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return animalFactory.newAnimal();
}
这种方法将允许我在运行时定位实现,但它还需要我手动设置和获取任何字段,而不是依赖数据绑定(当然,在这种特定情况下,这是微不足道的,但是我的对象非常复杂而且我还有很多不同的接口,所以我真的需要依赖数据绑定。
所以,我的问题是:我是否有另一种手动提供具体的Animal
实例的方法,然后让Jackson进行数据绑定魔术而不是手动实现所有方法?作为参考,如果有人对JAXB有一定的经验,那么像@XmlRegistry
这样的地方,我可以为给定的接口指定工厂,真是太棒了。
谢谢!
编辑:可能还不清楚,但是我不想在JSON中放置一个type
属性以进行反序列化,因为我不想在那里公开实现细节,所以{{1 }}不幸的是不是一个选择。
答案 0 :(得分:0)
您可以使用@JsonTypeInfo
和@JsonSubtypes
来自动支持多态。
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")
})
public interface Animal {
String talk();
}