Spring Boot WebClient 超类反序列化

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

我有一个 WebClient,它从 API 获取响应,其中它的字段之一是许多其他子类的超类。例如,假设我有一堂课

public class Animal {
  protected String sound;

  public Animal() {
  }

  public String getSound() {
    return sound;
  }

  public void setSound(String sound) {
    this.sound = sound;
  }
}

和几个子类(请,这只是一个例子)

public class Cat extends Animal {
  private String catHouseNumber;

  public Cat() {
    this.sound = "miau";
  }

  public String getCatHouseNumber() {
    return catHouseNumber;
  }

  public void setCatHouseNumber(String catHouseNumber) {
    this.catHouseNumber = catHouseNumber;
  }
}
public class Dog extends Animal {

  private String dogDesc;

  public Dog() {
    this.sound = "guau";
  }

  public String getDogDesc() {
    return dogDesc;
  }

  public void setDogDesc(String dogDesc) {
    this.dogDesc = dogDesc;
  }
}

然后,响应类看起来像这样

public class AnimalData {
  private int id;
  private int age;
  private int name;
  private Animal animalSpec;

  public AnimalData() {
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public int getName() {
    return name;
  }

  public void setName(int name) {
    this.name = name;
  }

  public Animal getAnimalSpec() {
    return animalSpec;
  }

  public void setAnimalSpec(Animal animalSpec) {
    this.animalSpec = animalSpec;
  }
}

当我使用 webclient.get() 进行调用时...我需要将 AnimalData 类中的“animalSpec”反序列化为 Dog 或 Cat 之一

我尝试自定义一个ObjectMapper,但没有成功

java spring-boot jackson webclient spring-webclient
1个回答
0
投票

要在 AnimalData 类中处理 animalSpec 的多态反序列化,您需要向 Jackson 提供有关所使用的子类类型的附加信息。这可以使用注释或自定义反序列化器来实现。

  1. 添加 Jackson 注释:在您的 Animal 类中,添加 @JsonTypeInfo 注释,其中 use = JsonTypeInfo.Id.NAMEinclude = JsonTypeInfo.As.PROPERTY。这将在 JSON 中包含用于反序列化的类型标识符。 (在此示例中,我假设 JSON 中的类型标识符名为“type”。如果实际 JSON 中的名称不同,您可以相应地调整属性属性。)

    public class Animal {
    // ... existing code ...
    
    @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
    protected String sound;
    
    // ... existing code ...}
    
  2. 添加子类型注释:在每个子类(CatDog)中,添加具有唯一名称的 @JsonTypeName 注释。

    @JsonTypeName("dog") 
    public class Dog extends Animal{
    // ... existing code ...}
    
  3. 使用 ObjectMapper 反序列化:当您收到 JSON 响应并需要对其进行反序列化时,请使用 ObjectMapper@JsonTypeInfo 支持:

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    AnimalData animalData = objectMapper.readValue(jsonString, AnimalData.class);
    

enableDefaultTyping方法用于配置ObjectMapper以在序列化的JSON中包含类型信息。

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