Reputation: 61
I have a HashMap<Picture, String> with Picture being a data-class I created in kotlin. I save the HashMap into the SharedPreferences using gson.toJson(hashmap)
and this works fine. But when I try to deserialize the very same string (I checked) into the HashMap<Picture, String> again, it fails with a weird error.
This is the Exception:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 3 path $.
This is the string for reference:
{
"Picture(image_url\u003dhttps://nftmintapp.infura-ipfs.io/ipfs/QmZnbgRFCvqXeahD37vaRANjPiyF9oCC2aWw1TwHat8SaU, creator_name\u003dmarkus, creator_address\u003d0x0, image_name\u003dethOS3, additional_url\u003dhttps://google.com)":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
The String I save in reference to the String is a Bytearray that I convert to string using Base64.encodeToString(bytes, Base64.NO_WRAP)
.
I assumed that gson would be able to de-serialize anything it serialized itself, has anybody ever encountered this?
Upvotes: 0
Views: 68
Reputation: 6894
The JSON specification only allows strings as property names of JSON objects. Gson works around this by simply calling the toString()
function on Map keys and serializing that as JSON property names. However, for deserialization it uses the standard JSON deserialization logic.
For simple Map keys such as String
or Int
this works just fine, but for complex key types, such as the Picture
class in your case, this leads to undesired behavior.
The solution is to either
Map<String, ...>
and for example stores the picture data as part of the Picture
class as well, or have a data class which contains the picture data and the Picture
objectGsonBuilder.enableComplexMapKeySerialization()
, see also the user guide for additional informationIn case you already have released a version of your app with this faulty JSON serialization logic and you want to preserve backward compatibility, you will have to write a JsonDeserializer
(or TypeAdapterFactory
, but that is a bit more complicated) which tries to deserialize this faulty JSON value.
Upvotes: 1