使用GSon反序列化Map <Object,Object>

maa*_*nus 8 java object gson

我有一个包含混合类型的Map,就像这个简单的例子一样

final Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a", 1);
map.put("b", "a");
map.put("c", 2);
final Gson gson = new Gson();
final String string = gson.toJson(map);
final Type type = new TypeToken<LinkedHashMap<String, Object>>(){}.getType();
final Map<Object, Object> map2 = gson.fromJson(string, type);
for (final Entry<Object, Object> entry : map2.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)

我得到的回报是简单Object的,没有Integer,没有String.输出看起来像

a : java.lang.Object@48d19bc8
b : java.lang.Object@394a8cd1
c : java.lang.Object@4d630ab9
Run Code Online (Sandbox Code Playgroud)

我能以某种方式修复它吗?我希望默认情况下会正确处理这些简单的案例.

我知道,关于类型的信息不能总是被保留,并可能1"1"手段在JSON完全相同.但是,返回简单的无内容对象对我来说毫无意义.

更新:序列化版本(即string上面的)看起来很好:

{"a":1,"b":"a","c":2}
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 7

Gson并不那么聪明.而是提供Javabean类风格的清晰和静态数据结构,以便Gson了解应该反序列化的单独属性的类型.

例如

public class Data {
    private Integer a;
    private String b;
    private Integer c;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

与...结合

Data data1 = new Data(1, "a", 2);
String json = gson.toJson(data1);
Data data2 = gson.fromJson(json, Data.class);
Run Code Online (Sandbox Code Playgroud)

更新:根据评论,键集似乎没有修复(虽然您似乎能够事先手动转换它,而不事先知道结构).您可以创建自定义反序列化程序.这是一个快速的例子.

public class ObjectDeserializer implements JsonDeserializer<Object> {

    @Override
    public Object deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
        String value = element.getAsString();
        try {
            return Long.valueOf(value);
        } catch (NumberFormatException e) {
            return value;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

您使用如下:

final Gson gson = new GsonBuilder().registerTypeAdapter(Object.class, new ObjectDeserializer()).create();
// ... 
Run Code Online (Sandbox Code Playgroud)