基于数组索引或键值的 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;
}
解释:
@JsonTypeInfo
- 使用此注解根据现有的属性确定subclass。在我们的例子中 path
。有关详细信息,请参阅 here.
@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'}]
我有一个 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;
}
解释:
@JsonTypeInfo
- 使用此注解根据现有的属性确定subclass。在我们的例子中path
。有关详细信息,请参阅 here.@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'}]