Gson FromJson 返回 null。我错过了什么?

Gson FromJson returns null. What am i missing?

提问人:Ryder Williams 提问时间:10/11/2023 更新时间:10/11/2023 访问量:64

问:

我尝试使用来自Json的gson,但是每次都打印=> Countries(countries=null)。我错过了什么?

法典

data class Countries(val countries: Map<String, List<String>>)

val jsonString = """
    {
      "Afghanistan": [
        "Herat",
        "Kabul",
        "Kandahar",
        "Molah",
        "Rana",
        "Shar",
        "Sharif",
        "Wazir Akbar Khan"
      ],
      "Albania": [
        "Elbasan",
        "Petran",
        "Pogradec",
        "Shkoder",
        "Tirana",
        "Ura Vajgurore"
      ]
    }
""".trimIndent()

        val countries = Gson().fromJson(jsonString, Countries::class.java)
        println(countries)

json kotlin gson

评论

0赞 Jorn 10/11/2023
JSON 不包含“countries”键。你期待什么?您需要将 POJO 与 JSON 结构相匹配。

答:

0赞 Vlad Guriev 10/11/2023 #1

它找不到钥匙。这里基本上有 3 个选项。countries

  1. 您可以修改 json 本身:
val jsonString = """
{
  "countries": {
    "Afghanistan": [
      "Herat",
      "Kabul",
      "Kandahar",
      "Molah",
      "Rana",
      "Shar",
      "Sharif",
      "Wazir Akbar Khan"
    ],
    "Albania": [
      "Elbasan",
      "Petran",
      "Pogradec",
      "Shkoder",
      "Tirana",
      "Ura Vajgurore"
    ]
  }
}
""".trimIndent()
  1. 或者,您可以更改反序列化为的实体(例如,用作第二个参数)。object : TypeToken<Map<String, List<String>>>() {}.type

  2. 另一种选择是为现有 json 和类创建自定义反序列化程序,如下所示:Countries

val countriesDeserializer =
    JsonDeserializer { json, _, context ->
        Countries(
            context.deserialize(json, object : TypeToken<Map<String, List<String>>>() {}.type)
        )
    }

并使用而不是简单地GsonBuilder().registerTypeAdapter(Countries::class.java, countriesDeserializer).create()Gson()

评论

0赞 Jorn 10/11/2023
输入不太可能改变。改变 POJO 本身不是更好吗?
0赞 Vlad Guriev 10/11/2023
@Jorn更新了答案
0赞 Marcono1234 10/12/2023
关于 2:从 Gson 2.10 开始,可以省略调用,直接将 to 传递给 ;这提供了更好的类型安全性。(也有点跑题了,但我不明白为什么你的答案被否决了;这是一个很好的答案,特别是因为它提供了多种可能的解决方案。.typeTypeTokenGson.fromJson
0赞 Vlad Guriev 10/12/2023
@Marcono1234我想答案的旧版本可能被否决了,因为我最初只建议解决方案 1,后来对其进行了编辑。
0赞 ΓDΛ 10/11/2023 #2

确定类型

val countryCityType = object : TypeToken<Map<String, List<String>>>() {}.type

Gson 解析

val countryCityData: Map<String, List<String>> = Gson().fromJson(jsonString, countryCityType)

println(countryCityData)