使用GSon反序列化Map

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

final Map map = new LinkedHashMap(); 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>(){}.getType(); final Map map2 = gson.fromJson(string, type); for (final Entry entry : map2.entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); } 

我得到的是普通的Object ,没有Integer ,没有String 。 输出看起来像

 a : java.lang.Object@48d19bc8 b : java.lang.Object@394a8cd1 c : java.lang.Object@4d630ab9 

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

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

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

 {"a":1,"b":"a","c":2} 

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

例如

 public class Data { private Integer a; private String b; private Integer c; // ... } 

与…结合

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

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

 public class ObjectDeserializer implements JsonDeserializer { @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; } } } 

您使用如下:

 final Gson gson = new GsonBuilder().registerTypeAdapter(Object.class, new ObjectDeserializer()).create(); // ... 
 Gson gson = new GsonBuilder() .registerTypeAdapter(Object.class, new JsonDeserializer() { @Override public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonPrimitive value = json.getAsJsonPrimitive(); if (value.isBoolean()) { return value.getAsBoolean(); } else if (value.isNumber()) { return value.getAsNumber(); } else { return value.getAsString(); } } }).create(); 

升级到Gson 2.1 。 它打印这个:

 a : 1.0 b : a c : 2.0 

您将数据存储在Map中。 看起来您需要将对象转换为您需要的类型。

如果你想要一个来自Map的JSON字符串,我认为json-simple是比Gson更好的选择。

这是http://code.google.com/p/json-simple/wiki/EncodingExamples的简短示例:

 //import java.util.LinkedHashMap; //import java.util.Map; //import org.json.simple.JSONValue; Map obj=new LinkedHashMap(); obj.put("name","foo"); obj.put("num",new Integer(100)); obj.put("balance",new Double(1000.21)); obj.put("is_vip",new Boolean(true)); obj.put("nickname",null); String jsonText = JSONValue.toJSONString(obj); System.out.print(jsonText); 

结果: {"name":"foo","num":100,"balance":1000.21,"is_vip":true,"nickname":null}

有关解码,请参阅http://code.google.com/p/json-simple/wiki/DecodingExamples 。