web-dev-qa-db-ja.com

GSONがインターフェイスであるタイプのTypeAdapterを呼び出さない

GSONは、公的にアクセス可能なプロパティ情報を使用する代わりに、JavaBeansの内部フィールドを調べるというある種のトリックを行っているようです。残念ながら、魔法のように作成されたBeanには、保存したくないプライベートフィールドがたくさんあるため、これはうまくいきません。

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

そしてもちろん、私のタイプアダプターを呼び出さないでください。これにより、他の動作を取得できなくなるようです。

31
Trejkaz

Gsonのバージョン2.3.1でも同じ問題が発生しました。私はそれを使用して動作させました

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

の代わりに

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

GSONの現在のリリースはこのようには機能しません。これにより、アダプターを使用してタイプがシリアル化されます。

gson.toJson(bean, Player.class)

または、PlayerTypeAdapterMagicPlayer.classに登録すると、既存のコードが機能します。 GSONは、具象(または最上位)タイプのみでTypeAdapterを検索します。したがって、遭遇する可能性のあるすべての具体的なタイプに対してカスタムタイプアダプタを登録する必要があります。

特定のタイプのすべての拡張クラスに同じTypeHeirarchyAdapterを使用する場合はTypeAdapterがあります。しかし、私はこれに幸運がなかったし、なぜそれがうまくいかなかったのかを調べるのに本当に時間を費やしていません。関連するディスカッションは次のとおりです。 https://groups.google.com/forum/?fromgroups=#!searchin/google-gson/interface/google-gson/0ebOxifqwb0/OXSCNTiLpBQJ

9
Eric Schoonover