我正在尝试提供Gson的通用“ Json Serializer”实例,我可以在我的整个代码库中使用它,而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类的匿名实现的方法保持警惕是不现实的。