使用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
您使用如下:
final Gson gson = new GsonBuilder().registerTypeAdapter(Object.class, new ObjectDeserializer()).create(); // ...
Gson gson = new GsonBuilder() .registerTypeAdapter(Object.class, new JsonDeserializer
升级到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 。