在下面将对象序列化为JSON的Jackson / Java代码中,我得到了这个:
{"animal":{"x":"x"}}
然而,我真正想要的是:
{"dog":{"x":"x"}}
我可以对AnimalContainer做些什么,以便获得对象的运行时类型(“dog”,“cat”),而不是“animal”)? (编辑:我知道地图名称来自getter和setter方法名称。)我能想到的唯一方法就是在AnimalContainer中拥有每种类型的动物的属性,拥有所有动物的制定者和吸气剂,并强制一次只评估一种动物。但这违背了拥有动物超类的目的而且似乎错了。在我的真实代码中,我实际上有十几个子类,而不仅仅是“狗”和“猫”。有没有更好的方法来做到这一点(也许以某种方式使用注释)?我也需要一个反序列化的解决方案。
public class Test
{
public static void main(String[] args) throws Exception
{
AnimalContainer animalContainer = new AnimalContainer();
animalContainer.setAnimal(new Dog());
StringWriter sw = new StringWriter(); // serialize
ObjectMapper mapper = new ObjectMapper();
MappingJsonFactory jsonFactory = new MappingJsonFactory();
JsonGenerator jsonGenerator = jsonFactory.createJsonGenerator(sw);
mapper.writeValue(jsonGenerator, animalContainer);
sw.close();
System.out.println(sw.getBuffer().toString());
}
public static class AnimalContainer
{
private Animal animal;
public Animal getAnimal() {return animal;}
public void setAnimal(Animal animal) {this.animal = animal;}
}
public abstract static class Animal
{
String x = "x";
public String getX() {return x;}
}
public static class Dog extends Animal {}
public static class Cat extends Animal {}
}
答案 0 :(得分:10)
根据this announement,Jackson 1.5实现了完整的多态类型处理,而trunk现在已经集成了该代码。
有两种简单的方法可以完成这项工作:
答案 1 :(得分:2)
这可能不是您正在寻找的答案,但有计划实施适当的“多态反序列化”(以及对其进行序列化的必要支持),对于Jackson版本1.4左右(即不是下一个,1.3,但之后一个。)
对于当前版本,您必须实现自定义序列化器/反序列化器:我可能只是为反序列化定义工厂方法,并为序列化器键入getter(将'getAnimalType'或抽象基类中的任何内容定义为抽象,在子类中重写 - 甚至只是在基类中实现,实例类的输出类名?)。
无论如何,以防万一重要,这里是使用JSON实现子类处理的基本问题,并且没有模式语言(因为json实际上并没有广泛使用它):
这些是可以解决的问题,但并不容易解决。 : - )
答案 2 :(得分:0)
这是我能想到的唯一方法,而且很难看。还有更好的方法吗?
@JsonWriteNullProperties(false)
public static class AnimalContainer
{
private Animal animal;
public Animal getCat()
{
return animal instanceof Cat ? animal : null;
}
public void setCat(Cat cat)
{
this.animal = cat;
}
public Animal getDog()
{
return animal instanceof Dog ? animal : null;
}
public void setDog(Dog dog)
{
this.animal = dog;
}
public Animal getFish()
{
return animal instanceof Fish ? animal : null;
}
public void setFish(Fish fish)
{
this.animal = fish;
}
}