Десериализовать вложенную изменяемую карту из Gson в Kotlin - PullRequest
0 голосов
/ 09 мая 2019

Я не могу преобразовать JSON в класс данных Kotlin, используя Gson из-за объекта MutableMap.Значения класса данных

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

на карте data бывают нескольких типов. Я пытался использовать TypeToken и Generics, как в здесь , но не работал.Примеры полученных json:

  1. {"action": "playVideo", "data": {"media": {"id": 15060328, "url": "http://url_to_get_item","name":"item name "," shortDescription ":" short desc "}

  2. {" action ":" setSpeed ​​"," data ": {" value ": 1}}

  3. {"action": "getProperty", "data": {"value": "position"}}

1 Ответ

1 голос
/ 21 мая 2019

Не рекомендуется создавать данные таким образом, но если у вас нет контроля над бэкэндом, вот пример, как десериализовать это

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())
...