如何使用gson反序列化JSON Map〈Int,Map〈String,String>>?

crcmnpdw  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(238)

伙计们!
如何使用gson或其他库反序列化JSON Map〈Int,Map〈String,String〉〉?
我想转换这个字符串:

{
    "123": {
        "KEY_ONE": "blablabla",
        "KEY_TWO": "blablabla",
    },
    "456": {
        "KEY_ONE": "blablabla"
        "KEY_TWO": "blablabla"
    }
}

转换为:Map〈Int,Map〈String,String〉〉
我尝试了以下两种选择:
`

var gson = Gson()

// Try 1:
var mapper = gson.fromJson(payload, Map::class.java)

// Try 2:
val mapper = object: TypeToken<Map<Int, Map<String, String>>>(){}.getType()
var xmlBase64 = gson.fromJson(payload, type::class.java) //Map<Int, Map<String, String>>

`
在两次尝试中,我都得到以下错误:java.lang.IllegalStateException:路径$的第1行第1列应为BEGIN_OBJECT,但实际为STRING

g0czyy6m

g0czyy6m1#

使用TypeToken的“Try 2”是正确的方法,但您的用法不正确:调用Gson.fromJson时,只需将type直接作为参数传递(不带::class.java):

val type = object: TypeToken<Map<Int, Map<String, String>>>(){}.type
val xmlBase64: Map<Int, Map<String, String>> = gson.fromJson(payload, type)

使用原始Map的“Try 1”可能也能工作,因为Gson使用基于JSON值类型的默认类型(例如,JSON对象为Map,JSON字符串为String),但它不是类型安全的,当您尝试使用反序列化的数据但JSON数据具有不同的格式或当您的代码假定错误的类型时,您将遇到ClassCastException
使用Gson 2.10或更新版本时,首选带TypeToken参数的fromJson重载(即,省略对TypeToken.type调用),因为它们是类型安全的:

val typeToken = object: TypeToken<Map<Int, Map<String, String>>>(){}
val xmlBase64 = gson.fromJson(payload, typeToken)

但是,您遇到的IllegalStateException也表明您的JSON数据格式不正确。可能它被额外的双引号括起来了(例如,"{...}"而不是{...})?尝试记录JSON数据(或设置断点)并验证它是否具有预期的格式。此外,您提供的示例JSON数据中有一些不正确的逗号;使用https://jsonlint.com/之类工具验证它是否为有效的JSON。

相关问题