Почему LinkedTreeMap генерируется после десериализации в другой класс с помощью Gson? - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть структура JSON, подобная следующей:

{
"status": 0,
"error_message": null,
"data": {
"1": {
  "7": [
    {
      "id": "1",
      "person_id": "3",
      "friend_id": "2"
    }
  ]
 }
}

Как вы заметили, число индексов (1, 7) является динамическим, я имею в виду, что они могут быть больше.Итак, для разбора этого JSON я решил использовать Map.7 может использоваться в качестве ключа, когда id, person_id, friend_id может быть классом с именем, например, Model.Итак, во-первых, я попытался получить 1 из data в JSON и преобразовать его в Map, как я описал выше.Вот как я это сделал:

    val data = myJson.getAsJsonObject("data").get("1")
    val gson = Gson()
    val type = object : TypeToken<Map<String, ArrayList<Model>>>() {

    }.type
    val myMap: Map<String, ArrayList<Model>> = gson.fromJson(data, type)

Все было хорошо, пока я не упомянул какое-то поле моего Model.Вот как я это сделал:

Прежде всего я попытался сослаться на myMap следующим образом:

enter image description here

Как вывидите, вместо получения Model, есть список LinkedTreeMap.Итак, когда я ссылаюсь на поле Model, я получаю CastException.

enter image description here

Итак, как решить эту проблему?Я попробовал это, не используя TypeToken, но это не помогло.

1 Ответ

0 голосов
/ 27 февраля 2019

вы дали неправильный JSON одно закрытие "}" Я думаю, что вы скопировали неправильно

создать класс Gson2Application

class Gson2Application

val jj = "{\n" +
        "\"status\": 0,\n" +
        "\"error_message\": null,\n" +
        "\"data\": {\n" +
        "\"1\": {\n" +
        "  \"7\": [\n" +
        "    {\n" +
        "      \"id\": \"1\",\n" +
        "      \"person_id\": \"3\",\n" +
        "      \"friend_id\": \"2\"\n" +
        "    }\n" +
        "  ]\n" +
        " }\n" +
        "}\n" +
        "}"

data class Model(val id: Long, val person_id: Long, val friend_id: Long)

fun main(args: Array<String>) {

    var myJson = JsonParser().parse(jj).asJsonObject
    val data = myJson.getAsJsonObject("data").get("1")

    val type = object : TypeToken<Map<String, ArrayList<Model>>>() {}.type  // the Map is interfacem then gson get default LinkedTreeMap extedn AbstractMap<K,V> implements Map
    val fromMapDefault = Gson().fromJson<Map<String, List<Model>>>(data, type)

    printResult(fromMapDefault)
//    result
//        {{7=[Model(id=1, person_id=3, friend_id=2)]} class com.google.gson.internal.LinkedTreeMap--> 1}
//        {[Model(id=1, person_id=3, friend_id=2)] class java.util.ArrayList--> 1}
//        {Model(id=1, person_id=3, friend_id=2)  class pl.jac.gson2.Model --> 2}
//        {1 long--> 3}

    val typeHashMap = object : TypeToken<HashMap<String, ArrayList<Model>>>() {}.type // the HashMap is an implementation
    val fromHashMap = Gson().fromJson<Map<String, List<Model>>>(data, typeHashMap)
    printResult(fromHashMap)
//result
//    {{7=[Model(id=1, person_id=3, friend_id=2)]} class java.util.HashMap--> 1}
//    {[Model(id=1, person_id=3, friend_id=2)] class java.util.ArrayList--> 1}
//    {Model(id=1, person_id=3, friend_id=2)  class pl.jac.gson2.Model --> 2}
//    {1 long--> 3}

}

private fun printResult(fromMapDefault: Map<String, List<Model>>) {
    println("""
        result
        {${fromMapDefault} ${fromMapDefault?.javaClass}--> 1}
        {${fromMapDefault["7"]} ${fromMapDefault["7"]?.javaClass}--> 1}
        {${fromMapDefault["7"]?.get(0)}  ${fromMapDefault["7"]?.get(0)?.javaClass} --> 2}
        {${fromMapDefault["7"]?.get(0)?.id} ${fromMapDefault["7"]?.get(0)?.id?.javaClass}--> 3}
    """.trimIndent())

}


}

private fun printResult(fromMapDefault: Map<String, List<Model>>) {
    println("""
        result
        {${fromMapDefault} ${fromMapDefault?.javaClass}--> 1}
        {${fromMapDefault["7"]} ${fromMapDefault["7"]?.javaClass}--> 1}
        {${fromMapDefault["7"]?.get(0)}  ${fromMapDefault["7"]?.get(0)?.javaClass} --> 2}
        {${fromMapDefault["7"]?.get(0)?.id} ${fromMapDefault["7"]?.get(0)?.id?.javaClass}--> 3}
    """.trimIndent())

}

я перехожу на вашу модель ClassStatus

data class ClassStatus(val status: Int, val error_message: String?, val data: Map<String,Map<String, ArrayList<Model>>>)
data class Model(val id: Long, val person_id: Long, val friend_id: Long)

fun main(args: Array<String>) {
    val fromJson = Gson().fromJson<ClassStatus>(jj, ClassStatus::class.java)
    printResult(fromJson)
    //result
    //ClassStatus(status=0, error_message=null, data={1={7=[Model(id=1, person_id=3, friend_id=2)]}}) class pl.jac.gson2.not.ClassStatus--> 1
    //{1={7=[Model(id=1, person_id=3, friend_id=2)]}} class com.google.gson.internal.LinkedTreeMap--> 2
    //{7=[Model(id=1, person_id=3, friend_id=2)]} class com.google.gson.internal.LinkedTreeMap--> 3
    //[Model(id=1, person_id=3, friend_id=2)] class java.util.ArrayList--> 4
    //Model(id=1, person_id=3, friend_id=2) class pl.jac.gson2.not.Model--> 5
    //1 long--> 6
}

private fun printResult(fromMapDefault: ClassStatus) {
    println("""
            result
            ${fromMapDefault} ${fromMapDefault.javaClass}--> 1
            ${fromMapDefault.data} ${fromMapDefault.data.javaClass}--> 2
            ${fromMapDefault.data["1"]} ${fromMapDefault.data["1"]?.javaClass}--> 3
            ${fromMapDefault.data["1"]!!["7"]} ${fromMapDefault.data["1"]!!["7"]!!.javaClass}--> 4
            ${fromMapDefault.data["1"]?.get("7")!![0]} ${fromMapDefault.data["1"]!!["7"]!![0].javaClass}--> 5
            ${fromMapDefault.data["1"]?.get("7")!![0].id} ${fromMapDefault.data["1"]!!["7"]!![0].id!!.javaClass}--> 6
        """.trimIndent())
}

val jj = "{\n" +
        "\"status\": 0,\n" +
        "\"error_message\": null,\n" +
        "\"data\": {\n" +
        "\"1\": {\n" +
        "  \"7\": [\n" +
        "    {\n" +
        "      \"id\": \"1\",\n" +
        "      \"person_id\": \"3\",\n" +
        "      \"friend_id\": \"2\"\n" +
        "    }\n" +
        "  ]\n" +
        " }\n" +
        "}\n" +
        "}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...