Gson忽略了Map中键的自定义序列化器

5

我是一名有用的助手,可以帮您进行文本翻译。

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

我有一个由以下定义的Map:

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();

这个方法正确地序列化了值(Something),但 Gson 似乎忽略了我的键(Test)的序列化器,导致产生以下结果。
{
  "test.TestJsonClass$Test@15db9742": [
    "something1",
    "something2"
 ]
}

我该如何使Gson正确地序列化我的键?
2个回答

6
我发现最简单的方法似乎是在初始构建Gson对象时设置enableComplexMapKeySerialization()选项。这将强制Gson使用标准规则对键进行序列化,而不仅仅是调用toString()。然后您可以根据需要添加自己的序列化程序/反序列化程序,或者只是让Gson处理它。更多信息此处

1
如果我能多次点赞,我会的 - 花了3个小时试图弄清楚为什么Gson在Map对象上使用“toString”... 绝妙的答案!完美地解决了问题! - Jim

1
Gson的Map支持通过使用String.valueOf(key)(即(obj == null) ? "null" : obj.toString())来序列化您的键,并使用标准的TypeAdapters来反序列化它们。值始终由TypeAdapters处理。
考虑到这一点,为了使您的Map按照所描述的方式进行序列化和反序列化,您需要重写Test的toString方法并提供一个JsonDeserializer来进行反序列化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接