Java API类型的通用Gson序列化

Java API类型的通用Gson序列化,java,json,kotlin,gson,generalization,Java,Json,Kotlin,Gson,Generalization,我正在使用一个API,它的属性可以有不同的类型 属性可以是ID或对象 我想构建一个通用类型,用Gson序列化为我处理这个问题 例如: "platforms": [ 6 ] "platforms": [ { "id": 6, "name": "PC (Microsoft Windows)", "slug": "win", "url": "https://www.igdb.com/platforms/w

我正在使用一个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合作,并已开始构建我的通用类

data class ObjectType<T>(
        var Id: Long? = null,
        var expand: T? = null
) 
数据类ObjectType(
变量Id:Long?=null,
变量扩展: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
    }
}
类对象反序列化器:JsonDeserializer{
重写有趣的反序列化(json:JsonElement?、typeOfT:Type?、context:JsonDeserializationContext?):T{
if(json!=null){
if(json.isJsonArray){
val struct:T=Gson().fromJson(json,T::class.java)作为T
返回结构
}否则{
val id=Gson().fromJson(json,Long::class.java)
//返回ObjectType(id,null)
}
}
返回T作为T
}
}

我很想知道如何解决这个问题。

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

class ObjectDeserializer<T> : JsonDeserializer<ObjectType<T>>
作为下一步,您需要了解
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())

当Gson需要反序列化一个
ObjectType
时,它会找到
ObjectDeserializer
的实例,并将
ObjectType
作为
typeOfT
提供给
反序列化

您对该API有控制权吗?因为我觉得这是一个糟糕的设计选择。嘿,很抱歉回复太晚,我只能在周末处理这个。。我尝试了您的解决方案,但使用ParameterizedType似乎不起作用,因为我得到了类强制转换异常
java.lang.ClassCastException:java.lang.class不能强制转换为java.lang.reflect.ParameterizedType
,但是如果我正确理解了这一点,那么我应该从actualTypeOfT返回一个类型。为什么不只使用typeOfT呢?
typeOfT
的类型应该是
ObjectType
。如何调用
Gson
来转换输入Json?如何注册反序列化程序?typeOfT不是ObjectType,而是主要的对象游戏
数据类游戏(val-id:Long?=null,val-name:String?=null,…val-developers:List?=null,val-publisher:List?=null,
val-gson=GsonBuilder()。registerTypeAdapter(com.igdb.igdbmainapp.kotlin.Game::class.java,ObjectDeserializer()).create()
但这应该是什么样子呢?我以为我就是这么做的。ObjectType需要一个类型,但我不确定我是否遵循了它。
val objectTypeType = typeOfT as ParameterizedType
val actualTypeOfT = objectTypeType.getActualTypeArguments()[0]
return if (json.isJsonObject()) {
    val struct: T = context.deserialize(json, actualTypeOfT)
    ObjectType(expand = struct)
} else {
    val id = json.getAsLong()
    ObjectType(Id = id)
}
registerTypeAdapter(ObjectType::class.java, ObjectDeserializer<Any>())