java - 如何用不同的继承人反序列化 JSON
问题描述
json有几种类型,我举两个例子:
{
"name": "dataUpdated",
"version": 102,
"eventTime": "2021-06-24",
"payload": {
"id": 158420,
"name": 446970,
"date": "2021-06-16",
"type": "A"
}
{
"name": "dataError",
"version": 102,
"eventTime": "2021-06-25",
"payload": {
"error": 666,
"errorMsg": "forbidden"
}
只有有效载荷的结构发生变化
我有一个类 MessageDto
class MessageDto {
@JsonProperty("name")
String name
@JsonProperty("version")
Integer version
@JsonProperty("eventTime")
String eventTime
@JsonProperty("payload")
Payload payload
}
类 Payload 为空,我只是将其用作标记并从中继承两个类:
DataUpdatedDto extends Payload {
@JsonProperty("id")
BigInteger id
@JsonProperty("name")
String name
@JsonProperty("date")
String date
@JsonProperty("type")
String type
}
DataErrorDto extends Payload {
@JsonProperty("error")
Integer error
@JsonProperty("errorMsg")
String errorMsg
}
如何向反序列化器解释我想反序列化 Payload 的哪个后代?
解决方案
您需要设置以下内容:
@JsonTypeInfo
用于设置机制以应用某些策略来分派到某些实现 类include=JsonTypeInfo.As.EXTERNAL_PROPERTY
因为您要调度的内容不在有效载荷内,而是在地图的同一级别use=JsonTypeInfo.Id.NAME, property="name"
从name
属性中读取值以进行调度
@JsonSubTypes
与@JsonSubTypes.Type
设置 一起使用- 例如
@JsonSubTypes.Type(value=DataUpdatedDto, name="dataUpdated")
,将类与父映射内部的DataUpdatedDto
值 相关联dataUpdated
- 例如
完整示例
@Grab('com.fasterxml.jackson.core:jackson-databind:2.12.4')
import com.fasterxml.jackson.annotation.*
import com.fasterxml.jackson.databind.*
class MessageDto {
@JsonProperty("name")
String name
@JsonProperty("version")
Integer version
@JsonProperty("eventTime")
String eventTime
@JsonProperty("payload")
@JsonTypeInfo(include=JsonTypeInfo.As.EXTERNAL_PROPERTY, use=JsonTypeInfo.Id.NAME, property="name")
@JsonSubTypes([
@JsonSubTypes.Type(value=DataUpdatedDto, name="dataUpdated"),
@JsonSubTypes.Type(value=DataErrorDto, name="dataError")
])
Payload payload
}
interface Payload {}
class DataUpdatedDto implements Payload {
@JsonProperty("id")
BigInteger id
@JsonProperty("name")
String name
@JsonProperty("date")
String date
@JsonProperty("type")
String type
}
class DataErrorDto implements Payload {
@JsonProperty("error")
Integer error
@JsonProperty("errorMsg")
String errorMsg
}
def objectMapper = new ObjectMapper()
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
def updated = objectMapper.readValue("""
{
"name": "dataUpdated",
"version": 102,
"eventTime": "2021-06-24",
"payload": {
"id": 158420,
"name": 446970,
"date": "2021-06-16",
"type": "A"
}
}
""", MessageDto)
assert updated.payload instanceof DataUpdatedDto
def error = objectMapper.readValue("""
{
"name": "dataError",
"version": 102,
"eventTime": "2021-06-25",
"payload": {
"error": 666,
"errorMsg": "forbidden"
}
}
""", MessageDto)
assert error.payload instanceof DataErrorDto
推荐阅读
- angular - 观察反应角度形式的原始状态时的问题
- django - 显示可能不存在的对象的页面?
- reactjs - 如何从 Firebase 获取一份文档以及如何传递 id 来删除它?
- c++ - 在 C++ 中,使用参数包作为初始化列表是不好的做法吗?
- javascript - 仅模拟模块中的一项功能,但保留原始功能
- rest - Apache Camel Route 没有设置正文
- ios - 您可以自定义 SwiftUI 上下文菜单的激活突出显示颜色吗?
- xcode - 在 Xcode 上构建失败
- python - 如何在 django 中获取唯一值
- javascript - javascript中的 Date(d.getTime()) 和 new Date(d.getTime()) 有什么区别?