为什么使用Gson反序列化到另一个类后会生成LinkedTreeMap?

时间:2019-02-25 06:40:14

标签: android json kotlin gson

我具有如下的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可以用作键。因此,首先,如上所述,我尝试从JSON中的1获取data并将其转换为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 :(得分:1)

您给错误的json一个闭包“}”,我认为您复制了错误的

创建Gson2Application类

$command.Transaction = $connection.BeginTransaction()
try {
    $command.ExecuteNonQuery()
    $command.Transaction.Commit()
}
catch {
    $command.Transaction.Rollback()
    throw $_
}

我更改为您的模型ClassStatus

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

}