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"}
そしてもちろん、私のタイプアダプターを呼び出さないでください。これにより、他の動作を取得できなくなるようです。
Gsonのバージョン2.3.1でも同じ問題が発生しました。私はそれを使用して動作させました
.registerTypeHierarchyAdapter(Player.class, new PlayerTypeAdapter())
の代わりに
.registerTypeAdapter(Player.class, new PlayerTypeAdapter())
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