从Gson反序列化嵌套的可变地图到Kotlin

时间:2019-05-09 15:23:23

标签: android json kotlin gson data-class

由于MutableMap对象,我无法使用Gson将JSON转换为Kotlin数据类。数据类

data class MyAction(
    @Key("action") var action: String = "default",
    @Key("data") var data: MutableMap<String, Any> = mutableMapOf()
)
data映射中的

值有几种类型。我尝试使用TypeToken和Generics,如here所示,但没有用。接收到的json的示例:

  1. {“ action”:“ playVideo”,“ data”:{“ media”:{“ id”:15060328,“ url”:“ http://url_to_get_item”,“ name”:“商品名称“,” shortDescription“:”简短说明“}

  2. {“ action”:“ setSpeed”,“ data”:{“ value”:1}}

  3. {“ action”:“ getProperty”,“ data”:{“ value”:“ position”}}

1 个答案:

答案 0 :(得分:1)

以这种方式设计数据不是一个好习惯,但是如果您对后端没有控制权,那么这里是一个如何反序列化此示例的示例

class MyDeserializer : JsonDeserializer<MyAction>{
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): MyAction {
    val myAction = MyAction()
    val action = json.asJsonObject.get("action")
    val data = json.asJsonObject.get("data")

    myAction.action = context.deserialize<String>(action, String::class.java)

    val myMap = mutableMapOf<String, Any>()
    data.asJsonObject.keySet().forEach {
        when (it) {
            is String -> { myMap[it] = context.deserialize(data.asJsonObject.get(it), String::class.java) }
            is MyCustomObject1 -> { myMap[it] = context.deserialize(data.asJsonObject.get(it), MyCustomObject1::class.java) }
            is MyCustomObject2 -> { myMap[it] = context.deserialize(data.asJsonObject.get(it), MyCustomObject2::class.java) }
            else -> myMap[it] = context.deserialize(data.asJsonObject.get(it), Any::class.java)
        }
    }

    myAction.data = myMap
    return myAction
}

}

不要忘记注册反序列化器

fun getSmartGson() = GsonBuilder().registerTypeAdapter(MyAction::class.java, MyDeserializer())