问题描述
我有动物课
public class Animal {
String type; // Can be dog,cat,elephant
String name;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,property = "type",include = JsonTypeInfo.As.EXTERNAL_PROPERTY,visible = true)
AnimalDetails animalDetails;
}
我有一个AnimalDetails
抽象类,它基于外部属性type
反序列化。
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,visible = true)
public abstract class AnimalDetails {
}
我有一个类DogDetails
,它是类AnimalDetails
的子类
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeName("dog")
public class DogDetails extends AnimalDetails{
String type;
@Builder
public DogDetails(String type){
this.type = type;
}
}
DogDetails还包含一个字段type
,我使用了@JsonTypeName
注释来表示当外部type
是“ dog”时反序列化为DogDetails。
当我尝试序列化DogDetails
类时,我得到两个type
字段。
import com.fasterxml.jackson.databind.ObjectMapper;
import io.harness.ng.remote.NGObjectMapperHelper;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class Scratch {
public static void main(String[] args) {
DogDetails dog = DogDetails.builder().type("GermanShepherd").build();
ObjectMapper objectMapper = new ObjectMapper();
NGObjectMapperHelper.configureNGObjectMapper(objectMapper);
String jsonValue = "";
try {
jsonValue = objectMapper.writeValueAsString(dog);
}catch(Exception ex){
logger.info("Encountered exception ",ex);
}
logger.info(jsonValue);
}
}
输出:{"type":"dog","type":"GermanShepherd"}
ExpectedOutupt:{"type":"GermanShepherd"}
我期望使用一种类型,如何解决此问题?
杰克逊版本:2.7.9
示例(DogDetails
和AnimalDetails
)代表了我正在解决的问题。解决此问题的最佳方法是更改变量名称(类型),但是此架构由我们的产品团队决定,我无法更改此架构。
解决方法
我认为您可以将@JsonIgnoreType
添加到子类中以解决此问题:
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeName("dog")
@JsonIgnoreType
public class Dog extends AnimalDetails{
String type;
@Builder
public Dog(String type){
this.type = type;
}
}