API 类型的通用 Gson 序列化
General Gson Serialization of API types
我正在使用一个 API,它的属性可以有不同的类型
属性可以是 ID 或对象
我想构建一个通用类型,用 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 class
data class ObjectType<T>(
var Id: Long? = null,
var expand: T? = null
)
我目前正在构建我的 JsonDeserializer,因为它需要一个 return 类型的 T,在我的例子中,它可以是 Int 或 Object。我试图用 ObjectType 替换 T ,它可以工作 'better' 但无法处理 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 声明为:
class ObjectDeserializer<T> : JsonDeserializer<ObjectType<T>>
假设所有参数都是非空的也会更容易:
override fun deserialize(json: JsonElement, typeOfT: Type,
context: JsonDeserializationContext): ObjectType<T>
现在你可以使用 typeOfT
,它实际上是 JsonDeserializer
中 T
的类型,而不是 ObjectDeserializer
中的类型。因此,它是您需要反序列化的 ObjectType<T>
类型。要进行下一步,您需要找到 T 的实际类型:
val objectTypeType = typeOfT as ParameterizedType
val actualTypeOfT = objectTypeType.getActualTypeArguments()[0]
下一步你需要弄清楚json
的内容。在你的情况下,你永远不会找到一个数组,而是一个对象或一个 long:
return if (json.isJsonObject()) {
val struct: T = context.deserialize(json, actualTypeOfT)
ObjectType(expand = struct)
} else {
val id = json.getAsLong()
ObjectType(Id = id)
}
这里是 return ObjectType
个没有任何错误处理的实例,您可能还需要添加这些实例。
那么您应该通过以下方式将此反序列化器提供给 Gson:
registerTypeAdapter(ObjectType::class.java, ObjectDeserializer<Any>())
每当 Gson 需要反序列化一个 ObjectType<TheType>
时,它会找到 ObjectDeserializer
的实例并提供 ObjectType<TheType>
作为 typeOfT
至 deserialize
.
我正在使用一个 API,它的属性可以有不同的类型
属性可以是 ID 或对象
我想构建一个通用类型,用 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 class
data class ObjectType<T>(
var Id: Long? = null,
var expand: T? = null
)
我目前正在构建我的 JsonDeserializer,因为它需要一个 return 类型的 T,在我的例子中,它可以是 Int 或 Object。我试图用 ObjectType 替换 T ,它可以工作 'better' 但无法处理 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 声明为:
class ObjectDeserializer<T> : JsonDeserializer<ObjectType<T>>
假设所有参数都是非空的也会更容易:
override fun deserialize(json: JsonElement, typeOfT: Type,
context: JsonDeserializationContext): ObjectType<T>
现在你可以使用 typeOfT
,它实际上是 JsonDeserializer
中 T
的类型,而不是 ObjectDeserializer
中的类型。因此,它是您需要反序列化的 ObjectType<T>
类型。要进行下一步,您需要找到 T 的实际类型:
val objectTypeType = typeOfT as ParameterizedType
val actualTypeOfT = objectTypeType.getActualTypeArguments()[0]
下一步你需要弄清楚json
的内容。在你的情况下,你永远不会找到一个数组,而是一个对象或一个 long:
return if (json.isJsonObject()) {
val struct: T = context.deserialize(json, actualTypeOfT)
ObjectType(expand = struct)
} else {
val id = json.getAsLong()
ObjectType(Id = id)
}
这里是 return ObjectType
个没有任何错误处理的实例,您可能还需要添加这些实例。
那么您应该通过以下方式将此反序列化器提供给 Gson:
registerTypeAdapter(ObjectType::class.java, ObjectDeserializer<Any>())
每当 Gson 需要反序列化一个 ObjectType<TheType>
时,它会找到 ObjectDeserializer
的实例并提供 ObjectType<TheType>
作为 typeOfT
至 deserialize
.