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,它实际上是 JsonDeserializerT 的类型,而不是 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> 作为 typeOfTdeserialize.