Gson忽略了Map中Key的自定义Serializer

时间:2014-07-28 21:10:15

标签: java json serialization map gson

我正在尝试使用GSON将Map序列化/反序列化为JSON

我有一张由

定义的地图
HashMap<Test, List<Something>> map = 
  new HashMap<>();

其中包括两个像这样定义的简单类

class Test {
 public Test(){}
 public Test(String str){test = str;}
 String test;
}

class Something {
 public Something(){}
 public Something(String str){something = str;}
 String something;
}

和一些像这样的测试代码

List<Something> somelist = new ArrayList<Something>();

somelist.add(new Something("something1"));
somelist.add(new Something("something2"));

map.put(new Test("test1"), somelist);

Gson默认情况下无法将其序列化,并产生以下结果

{
  "test.TestJsonClass$Test@15db9742": [
    {
      "string": "something1"
    },
    {
     "string": "something2"
    }
  ]
}

然而,在某种程度上,我会尝试为此类

创建一个自定义序列化程序
Gson gson = new GsonBuilder().setPrettyPrinting()
    .registerTypeAdapter(Test.class, new JsonSerializer<Test>() {
      public JsonElement serialize(Test arg0, Type arg1,
          JsonSerializationContext arg2) {
        return new JsonPrimitive(arg0.test);
      }
    }).registerTypeAdapter(Something.class, new JsonSerializer<Something>() {

      @Override
      public JsonElement serialize(Something arg0, Type arg1,
          JsonSerializationContext arg2) {
        return new JsonPrimitive(arg0.something);
      }
    }).create();

这正确地序列化了Value(Something),但是Gson似乎忽略了我的Key(Test)序列化器并产生了以下结果

{
  "test.TestJsonClass$Test@15db9742": [
    "something1",
    "something2"
 ]
}

如何让Gson正确序列化我的密钥?

2 个答案:

答案 0 :(得分:2)

我发现最简单的方法似乎是在最初构建Gson对象时设置enableComplexMapKeySerialization()选项。

这迫使Gson使用标准规则序列化密钥,而不是仅在其上调用toString()。然后,您可以根据需要添加自己的序列化器/反序列化器,或者让Gson处理它。

更多信息here

答案 1 :(得分:1)

Gson的地图支持通过使用String.valueOf(key)(仅(obj == null) ? "null" : obj.toString())来序列化您的密钥和标准的TypeAdapter来反序列化它们。值始终由TypeAdapters处理。

考虑到这一点,为了让Map根据你所描述的内容进行序列化和反序列化,你需要在Test上覆盖toString方法并提供一个JsonDeserializer来反序列化它。