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

时间:2012-05-17 06:59:28

标签: java json gson

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<Player>
{
    @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"}

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

3 个答案:

答案 0 :(得分:52)

我有同样的问题,Gson的2.3.1版本。我通过使用

来实现它
.registerTypeHierarchyAdapter(Player.class, new PlayerTypeAdapter())

而不是

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

答案 1 :(得分:9)

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

gson.toJson(bean, Player.class)

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

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

答案 2 :(得分:-1)

为什么它不起作用:

  1. PlayerTypeAdapter应该实现JsonSerializer。是吗?

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

  3. 在您的测试中,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));
    }