Java 将外部_属性与@JsonTypeName一起使用时,序列化字符串中的两个类型字段

Java 将外部_属性与@JsonTypeName一起使用时,序列化字符串中的两个类型字段,java,jackson,json-deserialization,Java,Jackson,Json Deserialization,我有一类动物 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 ani

我有一类动物

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, property = "type", include = JsonTypeInfo.As.EXTERNAL_PROPERTY, 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”}

预期输出:
{“类型”:“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;
    }
}

您将如何再次将预期输出反序列化回Java对象?字段名冲突。我认为您应该选择另一个字段名,例如“类型”的insead中的“animalType”。是的,更改字段名可以解决此问题,但在这种情况下,我无法更改字段名。我为外部属性添加了
JsonTyneName
,我认为对预期输出的反序列化应该可以工作,因为类包含
type
字段,它可以忽略上面的注释。我为此创建了一个bug。该问题可能在某些版本中得到修复。我的代码
include=JsonTypeInfo.As.EXTERNAL_属性
中也存在一个问题,该属性只能在字段上使用,不能在类上使用。这写在财产的文档中。嘿@Felix,谢谢你的回答
JsonIgnoreType
无法解决问题。我读到在类上添加它会在反序列化和序列化期间忽略整个类。但是我们不希望在序列化/反序列化时忽略
Dog
类。