首页 > 解决方案 > 匿名类的自定义 Gson 序列化器

问题描述

我正在尝试提供一个通用的“Json Serializer”Gson 实例,我可以在整个代码库中使用它,而 Gson 的“仅序列化自己的属性”功能妨碍了我。

我有一些代码基本上可以归结为:

public static void main(String[] args) {
    final Set<Integer> union = Sets.union(
        ImmutableSet.of(1, 2), 
        ImmutableSet.of(2, 3)
    );

    final Gson gson = new Gson();
    final JsonElement obj = gson.toJsonTree(union);
    System.out.println("is null: " + JsonNull.INSTANCE.equals(obj));
}
is null: true

看起来Sets.union构建了一个匿名 SetView 的实现。我以为我可以注册一个JsonSerializer来处理 SetView 的所有实现,但是 Gson 不使用我的序列化器:

public static void main(String[] args) {
    final Set<Integer> union = Sets.union(
            ImmutableSet.of(1, 2),
            ImmutableSet.of(2, 3)
    );


    final Gson gson = new GsonBuilder()
            .registerTypeAdapter(Sets.SetView.class, new ViewSerializer())
            .create();
    System.out.println("is SetView: " + (union instanceof Sets.SetView));
    final JsonElement obj = gson.toJsonTree(union);
    System.out.println("is null: " + JsonNull.INSTANCE.equals(obj));
}

private static class ViewSerializer implements JsonSerializer<Sets.SetView<?>> {
    @Override
    public JsonElement serialize(final Sets.SetView<?> src, 
                                 final Type typeOfSrc,
                                 final JsonSerializationContext context) {
        System.out.println("I'm being called, hooray!");
        return context.serialize(src.immutableCopy());
    }
}
is SetView: true
is null: true

我的自定义序列化程序永远不会被调用。我应该以其他方式向 Gson 注册吗?

我知道我可以简单地将我的代码更改为

final JsonElement obj = gson.toJsonTree(union.immutableCopy());

但我更愿意更改我的库代码(到处都在使用)。认为我公司的每个人都可以对可能返回 Collections 类的匿名实现的方法保持持续警惕是不现实的。

标签: javajsongson

解决方案


推荐阅读