java - API 类型的通用 Gson 序列化
问题描述
我正在使用一个 API,它的属性可以有不同的类型
属性可以是 Ids 或 Objects
我想构建一个通用类型,通过 Gson 序列化为我处理这个问题。
例子:
"platforms": [
6
]
"platforms": [
{
"id": 6,
"name": "PC (Microsoft Windows)",
"slug": "win",
"url": "https://www.igdb.com/platforms/win",
"created_at": 1297639288000,
"updated_at": 1470063140518,
"website": "http://windows.microsoft.com/",
"alternative_name": "mswin"
}
]
我正在使用 Kotlin 并已开始构建我的 Generalizable 课程
data class ObjectType<T>(
var Id: Long? = null,
var expand: T? = null
)
我目前正忙于构建我的 JsonDeserializer,因为它需要返回 T 类型,在我的情况下,它既可以是 Int 也可以是 Object。我试图用“更好”的 ObjectType 替换 T,但无法处理 JSON 是数组时的情况。
我目前正在尝试使其仅与通用类型 T 一起使用,因为我可以将类型设置为 List> 。
当前实施:
class ObjectDeserializer<T> : JsonDeserializer<T> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): T {
if (json != null) {
if (json.isJsonArray) {
val struct: T = Gson().fromJson(json, T::class.java) as T
return struct
} else {
val id = Gson().fromJson(json, Long::class.java)
//return ObjectType(id, null)
}
}
return T as T
}
}
我很想就如何解决这个问题提供一些意见。
解决方案
您的实施存在一些问题和不一致之处。首先,您必须确保反序列化ObjectType<T>
. 因此,您必须将类声明为:
class ObjectDeserializer<T> : JsonDeserializer<ObjectType<T>>
假设所有参数都不为空也会更容易:
override fun deserialize(json: JsonElement, typeOfT: Type,
context: JsonDeserializationContext): ObjectType<T>
现在您可以使用typeOfT
which 实际上是T
in的类型JsonDeserializer
,而不是 in ObjectDeserializer
。因此,它是ObjectType<T>
您需要反序列化的类型。要进入下一步,您需要找到 T 的实际类型:
val objectTypeType = typeOfT as ParameterizedType
val actualTypeOfT = objectTypeType.getActualTypeArguments()[0]
作为下一步,您需要弄清楚json
. 在你的情况下,你永远不会找到一个数组,而是一个对象或一个长:
return if (json.isJsonObject()) {
val struct: T = context.deserialize(json, actualTypeOfT)
ObjectType(expand = struct)
} else {
val id = json.getAsLong()
ObjectType(Id = id)
}
在这里,您返回ObjectType
没有任何错误处理的实例,您可能还需要添加这些错误处理。
然后你应该通过以下方式向Gson提供这个反序列化器:
registerTypeAdapter(ObjectType::class.java, ObjectDeserializer<Any>())
每当Gson需要反序列化一个ObjectType<TheType>
时,它都会找到 的实例并ObjectDeserializer
提供ObjectType<TheType>
给。typeOfT
deserialize
推荐阅读
- javascript - 动态生成的 href 无法正确显示
- python - 如何在不使用内循环或 if-else 的情况下计算 sin(x) 的泰勒级数的总和?
- ios - 加载带有标题的图像并将其缓存 - Objective-C(macOS 应用程序)
- python - 为什么我收到错误:OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: 错误:
- android - 无法在 android studio 3.6 中进行 git push 或 pull
- node.js - SyntaxError:意外的令牌'<' SystemJs(0.21.5v)
- javascript - process.env.UV_THREADPOOL_SIZE 在 macos 上总是显示 undefined
- java - 如何在 Spring 应用程序中为 Java Melody Monitor URL 添加安全性
- ssrs-2008 - SSRS 报告需要根据数据集行显示 n 次
- c# - 在 UWP 中应用 TranslateTransform 时,外部渲染的折线段不显示