9

インターフェイスでGsonを使用しようとしています:

public interface Photo {
    public int getWidth();
}

public class DinosaurPhoto implements Photo {
    ...
}

public class Wrapper {
    private Photo mPhoto; // <- problematic
}

... 

Wrapper wrapper = new Wrapper();
wrapper.setPhoto(new DinosaurPhoto());
Gson gson = new Gson();
String raw = gson.toJson(wrapper);  

// Throws an error since "Photo" can't be deserialized as expected.
Wrapper deserialized = gson.fromJson(raw, Wrapper.class);

Wrapper クラスには Photo 型のメンバー変数があるため、Gson を使用してそれをデシリアライズするにはどうすればよいですか?

ありがとう

4

3 に答える 3

8

カスタムの逆シリアル化が必要です。

解決するより大きな問題に応じて、[「型アダプター」] 1または「型階層アダプター」のいずれかを使用する必要があります。型階層アダプターは、「型のすべてのサブタイプに同じ表現が必要な場合に対応するためのものです」 。

于 2012-06-29T18:39:11.220 に答える
5

簡単に言えば、GSON ではそれができません。

ジャクソンに出くわしたとき、私は同じ問題に悩まされました。それを使えばとても簡単です:

ObjectMapper mapper = new ObjectMapper();  
mapper.enableDefaultTyping(); 

そして、追加のカスタム デシリアライザ、アノテーション、追加コードをまったく作成することなく、Java オブジェクトとインターフェイスをデシリアライズ/シリアライズすることができます。

これは質問の一部ではありませんでしたが、Gson から Jackson に移植することにした場合に役立つ可能性があります。Gson はデフォルトでプライベート フィールドをサポートしていますが、Jackson の場合はこれをコードに含める必要があります。

mapper.setVisibilityChecker(g.getVisibilityChecker().with(Visibility.ANY));

main のコードの実装例:

ObjectMapper mapper = new ObjectMapper();  
mapper.enableDefaultTyping();
mapper.setVisibilityChecker(g.getVisibilityChecker().with(Visibility.ANY));
Wrapper wrapper = new Wrapper();
wrapper.setPhoto(new DinosaurPhoto());
String wrapper_json = mapper.writeValueAsString(wrapper);
Wrapper wrapper_from_json = mapper.readValue(wrapper_json,Wrapper.class);

Gson は、将来のバージョンでこの問題に取り組むことを約束しましたが、今のところ解決していません。これがアプリケーションにとって非常に重要である場合は、Jackson に移植することをお勧めします。

于 2012-08-06T10:50:20.700 に答える