使用JsonTypeInfo从Jackson序列化中删除基类名称

问题描述 投票:0回答:2

这是我的继承设置:

抽象类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"}}

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

{"breed":"english shepherd"}

有没有办法实现我想要的?

java spring serialization jackson
2个回答
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”:{“品种”:“英国牧羊犬”}}


0
投票

我想你已经遇到了杰克逊的一个弱点,详见此处......

Unwrapped annotation issue

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

Jackson Custom Serializer

© www.soinside.com 2019 - 2024. All rights reserved.