GSON没有为我的TypeAdapter调用接口类型

GSON似乎在做某种技巧,它查看我的JavaBeans的内部字段,而不是使用可公开访问的属性信息。 不幸的是,这不会为我们飞行,因为我们神奇创造的豆子充满了私人田地,我不希望它存储。

@Test public void testJson() throws Exception { Player player = new MagicPlayer(); //BeanUtils.createDefault(Player.class); player.setName("Alice"); Gson gson = new GsonBuilder() .registerTypeAdapter(Player.class, new PlayerTypeAdapter()) .create(); System.out.println(gson.toJson(bean)); } private static class PlayerTypeAdapter implements JsonSerializer { @Override public JsonElement serialize(Player player, Type type, JsonSerializationContext context) { throw new RuntimeException("I got called, woohoo"); } } public static interface Player //extends SupportsPropertyChanges { public String getName(); public void setName(String name); } // Simple implementation simulating what we're doing. public static class MagicPlayer implements Player { private final String privateStuff = "secret"; private String name; @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } } 

这给出了:

 {"privateStuff":"secret","name":"Alice"} 

当然,永远不要调用我的类型适配器,这似乎使得无法获得任何其他行为。

我有同样的问题,使用当前版本的gson(2.3.1)并使用它

 .registerTypeHierarchyAdapter(Player.class, new PlayerTypeAdapter()) 

代替

 .registerTypeAdapter(Player.class, new PlayerTypeAdapter()) 

当前版本的GSON不能以这种方式工作。 这将使用适配器序列化您的类型。

gson.toJson(bean, Player.class)

或者,您可以为MagicPlayer.class注册MagicPlayer.class ,您的现有代码也可以使用。 GSON TypeAdapter通过具体(或顶级)类型查找TypeAdapter 。 因此,您必须为可能遇到的每种具体类型注册自定义类型适配器。

当您希望将相同的TypeAdapter用于给定类型的所有扩展类时,可以使用TypeAdapter 。 我虽然没有好运,但并没有真正花时间研究为什么它对我不起作用。 以下是一些相关讨论: https : //groups.google.com/forum/?fromgroups =#! searchin / google-gson / interface / google-gson/ 0ebOxifqwb0 / OXSCNTiLpBQJ

为什么它不起作用:

  1. PlayerTypeAdapter应该实现JsonSerializer。 可以?

  2. 如果它确实 – 应该工作。 它对我来说很完美,所以不要理解它为什么不适合你。 在调试中启动应用程序,放置断点和结帐。 应该有一些原因。

在您的测试中Gson构建器与适配器在哪里? 你应该改变它:

 public void testJson() throws Exception { Player player = new MagicPlayer(); //BeanUtils.createDefault(Player.class); player.setName("Alice"); // this is wrong if you want adapter /* Gson gson = new Gson(); */ // this is what you nead Gson gson = new GsonBuilder() .registerTypeAdapter(Player.class, new PlayerTypeAdapter()) .create(); System.out.println(gson.toJson(bean)); }