guys!
How can I deserialize a JSON Map<Int, Map<String, String>> using gson or any other library?
I want to convert this string:
{
"123": {
"KEY_ONE": "blablabla",
"KEY_TWO": "blablabla",
},
"456": {
"KEY_ONE": "blablabla"
"KEY_TWO": "blablabla"
}
}
Into this: Map<Int, Map<String, String>>
I tried these two options:
`
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>>
`
On both attempts, I get the following error: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
CodePudding user response:
"Try 2" using TypeToken
is the correct approach but you are using it incorrectly: When calling Gson.fromJson
just pass type
directly as argument (without ::class.java
):
val type = object: TypeToken<Map<Int, Map<String, String>>>(){}.type
val xmlBase64: Map<Int, Map<String, String>> = gson.fromJson(payload, type)
"Try 1" using a raw Map
might also work because Gson uses default types based on the JSON value types (e.g. JSON object as Map
, JSON string as String
), but it is not type safe and you will encounter ClassCastException
s when you try to use the deserialized data but the JSON data had a different format or when your code assumes the wrong types.
When using Gson 2.10 or newer, prefer the fromJson
overloads with TypeToken
parameter (that is, omit the .type
call on the TypeToken
) because they are type-safe:
val typeToken = object: TypeToken<Map<Int, Map<String, String>>>(){}
val xmlBase64 = gson.fromJson(payload, typeToken)
However, the IllegalStateException
you are experiencing also indicates that your JSON data is in an incorrect format. Possibly it is wrapped inside extra double quotes (e.g. "{...}"
instead of {...}
)? Try to log the JSON data (or set a breakpoint) and verify that is has the expected format. Besides that the sample JSON data you provided has some incorrect commas; use a tool such as https://jsonlint.com/ to verify that it is valid JSON.