基于数组索引或键值的 Jackson 反序列化

Jackson Deserialization based on array index or key value

我有一个 API,其中 return 是一个包含 2 个对象的数组。我的问题是每个对象都有不同的类型。如果每个元素有 1 个元素,我可以反序列化它,但是当它 return 具有不同类型的多个元素时,我正在努力寻找如何做到这一点。 JSON 的示例如下。反序列化的一种可能方法是基于数组索引,因为我们可以保证顺序并因此强制类型。另一个是基于路径键的结果,它总是 return 每个元素的相同值。

[
  {
    "path": "matter",
    "result": {
      "criticalDates.dateClosed": {
        "id": "-2",
        "name": "Date Closed",
        "confirmed": false,
        "confirmStatus": "Complete",
        "order": 2,
        "status": "Complete",
        "isConfirmable": true,
        "displayName": "Date Closed",
        "autoCalc": false,
        "__id": "e9d-4329-bb4a-03e644afdfda",
        "__className": "CriticalDate",
        "__tableId": "-24",
        "__classes": [
          "CriticalDate"
        ],
        "date": null
      },
      "matterType": "Family",
      "personActing.fullName": "Michael"
    },
    "status": "ok"
  },
  {
    "path": "matter.cardList",
    "result": [
      {
        "person.firstNames": "Daniel Testing",
        "person.lastName": "Lastname"
      },
      {
        "person.firstNames": "Daniel Testing",
        "person.lastName": "Lastname"
      }
    ],
    "status": "ok"
  }
]

反序列化的合适方法是什么?是否有仅注释方法?

一个选项是使用JsonTypeInfo来确定目标class。

示例 DTO:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "path")
@JsonSubTypes({@JsonSubTypes.Type(value = MatterPath.class, name = "matter"),
        @JsonSubTypes.Type(value = CardListPath.class, name = "matter.cardList")})
public abstract class AbstractPath {
    private String path;

   // Getters and Setters
}

//------------------------------
public class MatterPath extends AbstractPath {
    private String matterType;
    // Other fields, getter and setters
}
//---------------------------------
public class CardListPath extends AbstractPath{
    private String cardListType;
}

解释:

  1. @JsonTypeInfo - 使用此注解根据现有的属性确定subclass。在我们的例子中 path。有关详细信息,请参阅 here.
  2. @JsonSubTypes - 使用此注释映射 path 字段中的值和要使用的目标 class。详情参考JsonSubTypes.

测试:

String json = "[\n" +
        "  {\n" +
        "    \"path\": \"matter\",\n" +
        "      \"matterType\": \"Family\"\n" +
        "  },\n" +
        "  {\n" +
        "    \"path\": \"matter.cardList\",\n" +
        "    \"cardListType\": \"ok\"\n" +
        "  }\n" +
        "]\n";
AbstractPath[] abstractPaths = objectMapper.readValue(json, AbstractPath[].class);
System.out.println(Arrays.toString(abstractPaths));

输出:

[MatterPath{matterType='Family'}, CardListPath{cardListType='ok'}]