首页 > 解决方案 > 使用jackson反序列化json以更正子类类型

问题描述

将字符串反序列化为对象..

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
System.out.println(json); // Output is below
Status status = new ObjectMapper().readValue(json, Status.class);

ProcessingStage s = (ProcessingStage) status.getStages().get(0);
// or
DataStage s = (DataStage) status.getStages().get(0);

产生这些错误..

java.lang.ClassCastException: Stage cannot be cast to ProcessingStage
java.lang.ClassCastException: Stage cannot be cast to DataStage

如何使用 Jackson 将 的子类反序列Stage化为正确的实例类型?

我期待status.stages包含:[DataStage, DataStage, ProcessingStage],但看起来它包含:[Stage, Stage, Stage]

上面的输出System.out.println(json);..

{
  "stages":
  [
    {
      "name":"Pre",
      "order":1,
      "data":
      [
        {
          "id":"0688709c-17be-472a-bf5e-7d7b11bd8ccf"
        }
      ],
    },
    {
      "name":"Processing",
      "order":2,
      "data":
      [
        {
          "id":"ac3ecbb5-2aa6-4faf-b443-391472065219"
        }
      ],
    },
    {
      "name":"Post",
      "order":3,
      "status":"not-started"
    }
  ]
}

Status.java

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Status {
    @JsonProperty("stages")
    private List<Stage> stages;

    public Status() {}

    public List<Stage> getStages() {
        return stages;
    }

    public void setStages(List<Stage> stages) {
        this.stages = stages;
    }
}

Stage.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSubTypes({
    @JsonSubTypes.Type(value = ProcessingStage.class, name = "ProcessingStage"),
    @JsonSubTypes.Type(value = DataStage.class, name = "DataStage") }
)
public class Stage {
    @JsonProperty("name")
    private String name;
    @JsonProperty("order")
    private int order;

    public Stage() {}

    public Stage(final String name, final int order) {
        this.name = name;
        this.order = order;
    }

    public String getName() {
        return name;
    }

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

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }
}

ProcessingStage.java

import com.fasterxml.jackson.annotation.JsonProperty;

public class ProcessingStage extends Stage {
    @JsonProperty("status")
    private String status = Constants.NOT_STARTED;

    public ProcessingStage(final String name, final int order) {
        super(name, order);
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

DataStage.java

import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

public class DataStage extends Stage {
    @JsonProperty("data")
    private List<Data> data;

    public DataStage(final String name, final int order, List<Data> data) {
        super(name, order);
        this.data = data;
    }

    public List<Data> getData() {
        return data;
    }

    public void setData(List<Data> data) {
        this.data = data;
    }
}

Data.java

import com.fasterxml.jackson.annotation.JsonProperty;

public class DataFlow {
    @JsonProperty("id")
    private String id;

    public Data(final String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

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

标签: javajsonjacksondeserialization

解决方案


您可以尝试首先使用 instanceOf 评估对象的类

 if(status.getStages().get(0) instanceOf ProcessingStage) {
  ProcessingStage s = (ProcessingStage) status.getStages().get(0);
 }

或评估其他类

DataStage

推荐阅读