首页 > 解决方案 > 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
    }
}

我很想就如何解决这个问题提供一些意见。

标签: javajsonkotlingsongeneralization

解决方案


您的实施存在一些问题和不一致之处。首先,您必须确保反序列化ObjectType<T>. 因此,您必须将类声明为:

class ObjectDeserializer<T> : JsonDeserializer<ObjectType<T>>

假设所有参数都不为空也会更容易:

override fun deserialize(json: JsonElement, typeOfT: Type,
                         context: JsonDeserializationContext): ObjectType<T>

现在您可以使用typeOfTwhich 实际上是Tin的类型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>给。typeOfTdeserialize


推荐阅读