使用Jackson ObjectMapper将子类名称序列化为JSON,而不是超类

sea*_*and 10 java serialization json jackson

在下面将对象序列化为JSON的Jackson/Java代码中,我得到了这个:

{"animal":{"x":"x"}}
Run Code Online (Sandbox Code Playgroud)

但是,我真正想要得到的是:

{"dog":{"x":"x"}}
Run Code Online (Sandbox Code Playgroud)

我可以对AnimalContainer做些什么,以便获得对象的运行时类型("dog","cat"),而不是"animal")? (编辑: .我知道地图名称来源于getter-和setter-方法名),我能想到的这样做是内AnimalContainer有每种动物的属性,唯一的方法,有getter和setter方法为所有这些,并强制一次只评估一个.但这违背了拥有动物超类的目的而且似乎错了.在我的真实代码中,我实际上有十几个子类,而不仅仅是"狗"和"猫".有没有更好的方法来做到这一点(也许以某种方式使用注释)?我也需要一个反序列化的解决方案.

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 {} 
}
Run Code Online (Sandbox Code Playgroud)

Sta*_*Man 10

根据这个公告,Jackson 1.5实现了完整的多态类型处理,而trunk现在已经集成了该代码.

有两种简单的方法可以完成这项工作:

  • 在超类型(动物在这里)中添加@JsonTypeInfo注释,或者
  • 通过调用ObjectMapper.enableDefaultTyping()来配置对象映射器(但如果是这样,Animal需要是抽象类型)