I have used Gson to serialize Map<String,Object> to json, but I encountered some problems, can you tell me why this happens?
Code:
HashMap<String,Object> map = new HashMap<String, Object>(){{
this.put("test",1);
}};
HashMap<String,Object> map2 = new HashMap<>();
map2.put("test",1);
System.out.println(new Gson().toJson(map));
System.out.println(new Gson().toJson(map2));
Output:
null
{"test":1}
CodePudding user response:
The way you have declared it, map
is not a HashMap, but an anonymous class. Gson is not designed to handle anonymous and inner classes.
You can check this issue, which asks about serialization of anonymous class, but it's closed, so probably there are no plans to add support for this. As you can see in the discussion, possible workaround is providing the type.
System.out.println(new Gson().toJson(map, new TypeToken<HashMap<String, Object>>(){}.getType()));
Another related discussion.
CodePudding user response:
If you debug the code, you will see that map.getClass()
will not return a "HashMap" as you might expect, but an anonymous class (if you run the code in a class named Main, then the map.getClass()
will be something like Main$1).
map2.getClass()
will return HashMap as expected.
If you check Gson method toJson Javadocs:
This method serializes the specified object into its equivalent Json representation. This method should be used when the specified object is not a generic type. This method uses Object.getClass() to get the type for the specified object, but the getClass() loses the generic type information because of the Type Erasure feature of Java. Note that this method works fine if the any of the object fields are of generic type, just the object itself should not be of a generic type. If the object is of generic type, use toJson(Object, Type) instead. If you want to write out the object to a Writer, use toJson(Object, Appendable) instead.
To solve your "problem" you must specify map
type.
Example:
Map<String,Object> map = new HashMap<String, Object>(){{
this.put("test",1);
}};
Map<String,Object> map2 = new HashMap<>();
map2.put("test",1);
final Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
System.out.println(new Gson().toJson(map, type));
System.out.println(new Gson().toJson(map2));