使用Jackson ObjectMapper将子类名称序列化为JSON,而不是超类 [英] Using Jackson ObjectMapper to serialize the subclass name into JSON, not the superclass

查看:1481
本文介绍了使用Jackson ObjectMapper将子类名称序列化为JSON,而不是超类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the following Jackson/Java code that serializes objects into JSON, I am getting this:

{"animal":{"x":"x"}}

但是,我真正希望获得的是:

However, what I actually want to get is this:

{"dog":{"x":"x"}}

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

Is there something I can do to AnimalContainer so that I get the runtime type ("dog", "cat") of the object, instead of "animal")? ( I am aware that the map name comes from the getter- and setter- method names.) The only way I can think of to do it is within AnimalContainer to have an attribute of each type of Animal, have setters and getters for all of them, and enforce that only one is valued at a time. But this defeats the purpose of having the Animal superclass and just seems wrong. And in my real code I actually have a dozen subclasses, not just "dog" and "cat". Is there a better way to do this (perhaps using annotations somehow)? I need a solution for deserializing, as well.

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 {} 
}


推荐答案

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

As per this announement, Jackson 1.5 implements full polymorphic type handling, and trunk now has that code integrated.

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

There are two simple ways to make this work:


  • 在超类型中添加@JsonTypeInfo注释(动物在这里),或者

  • 通过调用ObjectMapper.enableDefaultTyping()来配置对象映射器(但如果是这样,Animal需要是抽象类型)

这篇关于使用Jackson ObjectMapper将子类名称序列化为JSON,而不是超类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆