使用JsonTypeInfo从Jackson序列化中删除基类名称
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用JsonTypeInfo从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
,在这种情况下,animal
和Dog
都被淘汰了(这不是我想要的):
{"breed":"english shepherd"}
有没有办法实现我想要的?
你需要为你的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”:{“品种”:“英国牧羊犬”}}
我想你已经遇到了杰克逊的一个弱点,详见此处......
我建议的解决方案是这里描述的自定义序列化器...
以上是关于使用JsonTypeInfo从Jackson序列化中删除基类名称的主要内容,如果未能解决你的问题,请参考以下文章
JSON Jackson - 使用自定义序列化程序序列化多态类时的异常
使用Jackson As.External_Property和Collection
Jackson 的 @JsonTypeInfo(use = Id.CUSTOM, include = As.PROPERTY, property = "type") 读取 JSON