Jackson:反序列化抽象类

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

我正在使用 Jackson 反序列化几个共享某些属性的 JSON 对象:

{
  "error": "",
  "result": {
    "RowNumber": "2",
    "Rows": [{
        "Id": "1",
        "Category": "A"
      }, {
        "Id": "2",
        "Category": "A"
      }
    ],
    "__chk": ""
  },
  "request_name": "Method01"
}
{
  "error": "",
  "result": {
    "FileName": "00001.xml",
    "__chk": ""
  },
  "request_name": "Method02"
}

他们共享“顶级”属性(

error
result
request_name
),其中:

  • request_name
    是区分JSON对象的属性
  • result
    是两个 JSON 对象之间的不同对象

我想要做的是有一个具有

AbstractJson
error
属性的抽象类(
result
):

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "request_name")
@JsonSubTypes({
    @Type(value = JsonMethod01.class, name = "Method01"),
    @Type(value = JsonMethod02.class, name = "Method02") }
)
public abstract class AbstractJson {
    @JsonProperty("error")  private String sError;
    @JsonProperty("result") private AbstractJsonResult oResult;
    
    public String getError() {return sError;}
    public void setError(String sError) {this.sError = sError;}
    
    public AbstractJsonResult getResult() {return oResult;}
    public void setResult(AbstractJsonResult oResult) {this.oResult = oResult;}
}
public abstract class AbstractJsonResult {
    @JsonProperty("__chk")  private String sChk;
}
public class JsonMethod01 extends AbstractJson {
    public static class JsonResult extends AbstractJsonResult {
        @JsonProperty("RowNumber")  private int iRowNumber;
        @JsonProperty("Rows")       private List<JsonResultRow> oRows;
        
        public int getRowNumber() {return iRowNumber;}
        public void setRowNumber(int iRowNumber) {this.iRowNumber = iRowNumber;}
        
        public List<JsonResultRow> getRows() {return oRows;}
        public void setRows(List<JsonResultRow> oRows) {this.oRows = oRows;}
    }
    
    public static class JsonResultRow {
        @JsonProperty("Id")         private String sId;
        @JsonProperty("Category")   private String sCategory;
        
        public String getId() {return sId;}
        public void setId(String sId) {this.sId = sId;}
        
        public String getCategory() {return sCategory;}
        public void setCategory(String sCategory) {this.sCategory = sCategory;}
    }
}
public class JsonMethod02 extends AbstractJson {
    public static class JsonResult extends AbstractJsonResult {
        @JsonProperty("FileName") String sFileName;
        
        public String getFileName() {return sFileName;}
        public void setFileName(String sFileName) {this.sFileName = sFileName;}
    }
}
public class Test {
    public static AbstractJson jsonDeserialization(String sJson) throws JsonMappingException, JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(sJson, AbstractJson.class);
    }
    
    public static void main(String[] args) {
        String sMethod01Json = "{\"error\":\"\",\"result\":{\"RowNumber\":\"2\",\"Rows\":[{\"Id\":\"1\",\"Category\":\"A\"},{\"Id\":\"2\",\"Category\":\"A\"}],\"__chk\":\"\"},\"request_name\":\"Method01\"}";
        String sMethod02Json = "{\"error\":\"\",\"result\":{\"FileName\":\"00001.xml\",\"__chk\":\"\"},\"request_name\":\"Method02\"}";
        System.out.println(sMethod01Json);
        System.out.println(sMethod02Json);
        try {
            AbstractJson oJsonMethod01 = jsonDeserialization(sMethod01Json);
            System.out.println(oJsonMethod01);
            AbstractJson oJsonMethod02 = jsonDeserialization(sMethod02Json);
            System.out.println(oJsonMethod02);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在反序列化过程中出现错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `json.deserialize_abstractclass.esempio02.AbstractJsonResult` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information.

我知道反序列化一个抽象类是不可能的,但是在网上搜索我找不到适合我需要的解决方案。

java json jackson abstract-class json-deserialization
1个回答
0
投票

您已经有从抽象类派生的具体类:JsonMethod01 和 JsonMethod02。只需遵循合同并在您的代码中使用这些类即可。像这样:

public class Test {
    private static mapper = new ObjectMapper(); // better to have it as a singleton

    public static void main(String[] args) {
        String sMethod01Json = "{\"error\":\"\",\"result\":{\"RowNumber\":\"2\",\"Rows\":[{\"Id\":\"1\",\"Category\":\"A\"},{\"Id\":\"2\",\"Category\":\"A\"}],\"__chk\":\"\"},\"request_name\":\"Method01\"}";
        String sMethod02Json = "{\"error\":\"\",\"result\":{\"FileName\":\"00001.xml\",\"__chk\":\"\"},\"request_name\":\"Method02\"}";
        System.out.println(sMethod01Json);
        System.out.println(sMethod02Json);
        try {
            JsonMethod01 oJsonMethod01 = mapper.readValue(sMethod01Json, JsonMethod01.class);
            System.out.println(oJsonMethod01);
            JsonMethod02 oJsonMethod02 = mapper.readValue(sMethod02Json, JsonMethod02.class);
            System.out.println(oJsonMethod02);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.