使用JsonTypeInfo

时间:2017-12-18 14:39:00

标签: java spring serialization jackson

这是我的继承设置:

抽象类Animal

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include =JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class)})

public abstract class Animal {
}

具体类狗:

public class Dog extends Animal {

  private final String breed;

  public Dog(String breed) {
      this.breed = breed;
  }

  public String getBreed() {
      return breed;
  }
}

Animal的简单包装类:

public class AnimalWrapper {

  private final Animal animal;

  public AnimalWrapper(Animal animal) {
      this.animal = animal;
  }

  public Animal getAnimal() {
      return animal;
  }
}

序列化代码:

ObjectMapper objectMapper = new ObjectMapper();
Animal myDog = new Dog("english shepherd");
AnimalWrapper animalWrapper = new AnimalWrapper(myDog);
String dogJson = objectMapper.writeValueAsString(animalWrapper);

dogJson的值为:

{"animal":{"Dog":{"breed":"english shepherd"}}}

我想要的是是没有基类名称(动物)的JSON:

{"Dog":{"breed":"english shepherd"}}

我尝试在@JsonUnwrapped animal周围使用AnimalWrapper,在这种情况下animalDog都被删除了(这不是我想要的):

{"breed":"english shepherd"}

有没有办法达到我想要的目的?

2 个答案:

答案 0 :(得分:0)

我认为你遇到了杰克逊的一个弱点,详见此处......

Unwrapped annotation issue

我建议的解决方案是这里描述的自定义序列化器......

Jackson Custom Serializer

答案 1 :(得分:0)

您的JsonSerializer需要自定义AnimalWrapper才能跳过该位。

public class ResponseSerializer extends JsonSerializer<AnimalWrapper> {


    @Override
    public void serialize(AnimalWrapper value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        final Object animal = value.getAnimal();
        Class<?> responseClass = animal.getClass();
        JavaType responseJavaType = serializers.constructType(responseClass);
        gen.writeStartObject();
        gen.writeFieldName(serializers.findTypeSerializer(responseJavaType).getTypeIdResolver().idFromValue(animal));
        serializers.findValueSerializer(responseClass).serialize(animal, gen, serializers);
        /* Here you must manually serialize other properties */
        /* Like gen.writeStringField("property", value.getProperty()); */
        gen.writeEndObject();
    }
}

使用AnimalWrapper注释为@JsonSerialize添加注释,并指定自定义序列化程序。

@JsonSerialize(using = ResponseSerializer.class)
public class AnimalWrapper<T> {

  private final T animal;

  public AnimalWrapper(T animal) {
      this.animal = animal;
  }

  public T getAnimal() {
      return animal;
  }
}

快速测试:

ObjectMapper objectMapper = new ObjectMapper();
Animal myDog = new Dog("english shepherd");
AnimalWrapper animalWrapper = new AnimalWrapper(myDog);
String dogJson = objectMapper.writeValueAsString(animalWrapper);
System.out.println(dogJson);

输出:

  

{“dog”:{“breed”:“english shepherd”}}