Deserialize Map <String, List <? >> using Gson
I am serializing data on the server:
Gson gson = new Gson();
Map<String, List<?>> resultMap = BackendUpdateManager.getInstance()
.getUpdates(timeHolder, shopIdInt, buyerIdInt);
gson.toJson(resultMap);
and deserialize:
Gson gson = new Gson();
Map<String, List<?>> resultMap = gson.fromJson(json,
new TypeToken<Map<String, List<?>>>() {
}.getType());
However, when I try to use elements from Map
:
List<ProductCategory> productCategoryList = (List<ProductCategory>)updateMap.get(key);
for(ProductCategory productCategory : productCategoryList) {
}
I get an error:
Caused by:
java.lang.ClassCastException
:com.google.gson.internal.LinkedTreeMap
it can not be added to thecom.example.model.entity.ProductCategory
How can I fix this error or otherwise create Map
with List<different classes>
?
I've tried creating classes with getters and setters that contain List
different classes instead Map<String, List<?>>
and use it for serialization and deserialization. But I'm looking for a better way.
source to share
How is Gson supposed to know what a particular Json string is ProductCategory
? For example, if the definition ProductCategory
is as follows:
package com.stackoverflow.vitvetal;
public class ProductCategory {
String name;
String type;
}
And this is Json:
{
"name":"bananas",
"type":"go-go"
}
Where is the link that tells Gson to create an instance com.stackoverflow.vitvetal.ProductCategory
?
This link doesn't exist because you haven't reported it to Gson.
So what gson does instead is it creates Map<String, String>
which looks like
"name" -> "bananas"
"type" -> "go-go"
If you want to do something different, the simplest - but also the least powerful - is to fully specify the parameterized type on creation TypeToken
; no template <?>
.
If you need to do something more powerful, such as creating maps with a wide variety of objects, you need to create a custom deserializer using TypeAdapter<T>
that teaches Gson how to handle your particular kind of object.
source to share