34

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

そしてもちろん、私の型アダプターを呼び出すことはありません。

4

3 に答える 3

66

Gsonのバージョン2.3.1でも同じ問題がありました。を使用して動作させました

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

それ以外の

.registerTypeAdapter(Player.class, new PlayerTypeAdapter())
于 2015-03-11T17:49:40.610 に答える
9

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

gson.toJson(bean, Player.class)

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

特定のタイプのすべての拡張クラスにTypeHeirarchyAdapter同じものを使用したい場合があります。TypeAdapter私はこれで運が良かったわけではなく、なぜうまくいかなかったのかを調べるのに時間を費やしていません. 関連する議論は次のとおりです

于 2012-08-23T05:15:49.920 に答える
-3

なぜ機能しないのか:

  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));
}
于 2012-05-17T07:14:44.937 に答える