Java Jackson 反序列化同名但 class 类型不同的对象

Java Jackson deserialize objects of the same name but different class types

我有 POJO 在 REST API 中用作请求和响应对象(我知道重复的 @JsonProperty 在语法上不正确,见下文):

public class Request {

    @JsonProperty("patient")
    PatientObjectA patientA;

    @JsonProperty("patient")
    PatientObjectB patientB;
}

public class PatientObjectA {
    @JsonProperty("identifier")
    Private Identifier identifier

    @JsonProperty("system")
    Private String system;

    @JsonProperty("value")
    Private String value;
}

public class PatientObjectA {
    @JsonProperty("identifier")
    Private List<Identifier> identifier

    @JsonProperty("system")
    Private String system;

    @JsonProperty("value")
    Private String value;
}

我希望能够使用的基数存在细微差别,即 "Patient" 对象有时会是(请求中的 PatientObjectA class):

"patient": {
  "identifier": {
    "type": {
      "coding": {
        "system": "NA",
        "code": "Patient"
      },
      "text": "Patient"
    },
    "system": "Patient",
    "value": "000000000"
  }
}

或这种情况(注意标识符对象的基数差异,在这种情况下标识符可以有一个或多个项目)(请求中的 PatientBObject class):

    "patient": {
      "identifier": [{
         "type": {
          "coding": {
            "system": "NA",
            "code": "Patient"
          },
          "text": "Patient"
        },
        "system": "Patient",
        "value": "3018572032"
      }]
    }

我想实现将请求映射到正确对象的功能。有没有一种方法(自定义解串器除外)可以通过 type/cardinality 将请求映射到适当的对象?任何见解将不胜感激!

Jackson 通过 @JsonTypeInfo 注释支持这一点。

我建议在 属性(json 字段)中指定类型信息并使用完整的 class 名称(而不是短名称)以提供更好的保证唯一性:

@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.CLASS, property = "jsonType") public class PatientObjectA { ..

输出 A 看起来像: "patient": { "jsonType": "com.company.PatientAObject" "identifier": { "type": { "coding": { "system": "NA", "code": "Patient" }, "text": "Patient" }, "system": "Patient", "value": "000000000" } } 输出 B 看起来像: "patient": { "jsonType": "com.company.PatientBObject" "identifier": { "type": { "coding": { "system": "NA", "code": "Patient" }, "text": "Patient" }, "system": "Patient", "value": "000000000" } }

注意:另外,请查看@JsonRootName,因为它将使您能够创建 'rooted' json 对象,而无需拥有您​​拥有的包装对象。

@JsonRootName("Patient") @JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.CLASS, property = "jsonType") public class PatientObjectA { ..

..和..

@JsonRootName("Patient") @JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.CLASS, property = "jsonType") public class PatientObjectB { ..

有助于进行更多研究的相关术语:

  • json
  • 中的多态性
  • json 相当于 xml 命名空间。