type
フィールドの値に基づいて、jsonオブジェクトを特定のタイプのオブジェクト(Gsonライブラリを使用)に逆シリアル化したい、たとえば:
[
{
"type": "type1",
"id": "131481204101",
"url": "http://something.com",
"name": "BLAH BLAH",
"icon": "SOME_STRING",
"price": "FREE",
"backgroundUrl": "SOME_STRING"
},
{
....
}
]
したがって、type
フィールドは異なる(ただし既知の)値になります。その値に基づいて、jsonオブジェクトを適切なモデルオブジェクト(たとえば、Type1Model、Type2Modelなど)に逆シリアル化する必要があります。逆変換する前に、JSONArray
に変換することで簡単に実行できます。これを繰り返し、逆シリアル化する必要がある型を解決します。に。しかし、私はそれが醜いアプローチだと思います、そして私はより良い方法を探しています。助言がありますか?
JsonDeserializer
を実装して、Json値をJavaインスタンスに解析するときに使用できます。アイデアを提供するコードで表示してみます:
1)着信json値のidプロパティによってクラスの異なるインスタンスを作成するカスタムJsonDeserializer
クラスを定義します。
class MyTypeModelDeserializer implements JsonDeserializer<MyBaseTypeModel> {
@Override
public MyBaseTypeModel deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
JsonElement jsonType = jsonObject.get("type");
String type = jsonType.getAsString();
MyBaseTypeModel typeModel = null;
if("type1".equals(type)) {
typeModel = new Type1Model();
} else if("type2".equals(type)) {
typeModel = new Type2Model();
}
// TODO : set properties of type model
return typeModel;
}
}
2)Javaオブジェクトの異なるインスタンスの基本クラスを定義します:
class MyBaseTypeModel {
private String type;
// TODO : add other shared fields here
}
3)Javaオブジェクトのクラスの異なるインスタンスを定義して、基本クラスを拡張します:
class Type1Model extends MyBaseTypeModel {
// TODO: add specific fields for this class
}
class Type2Model extends MyBaseTypeModel {
// TODO: add specific fields for this class
}
4)これらのクラスを使用して、json値をBeanに解析します。
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MyBaseTypeModel.class, new MyTypeModelDeserializer());
Gson gson = gsonBuilder.create();
MyBaseTypeModel myTypeModel = gson.fromJson(myJsonString, MyBaseTypeModel.class);
私は今それをテストすることはできませんが、あなたがアイデアを得ることを望みます。また このリンク は非常に役立ちます。
@ stephane-kの回答は機能しますが、少し混乱し、改善される可能性があります(彼の回答へのコメントを参照)
https://github.com/google/gson/blob/master/extras/src/main/Java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.Java をプロジェクトにコピーします。 (問題ありません。これらのクラスはコピー/貼り付けできるように設計されています https://github.com/google/gson/issues/845#issuecomment-217231315 )
セットアップモデルの継承:
// abstract is optional
abstract class BaseClass {
}
class Type1Model extends BaseClass {
}
class Type2Model extends BaseClass {
}
GSONをセットアップするか、既存のGSONを更新します。
RuntimeTypeAdapterFactory<BaseClass> typeAdapterFactory = RuntimeTypeAdapterFactory
.of(BaseClass.class, "type")
.registerSubtype(Type1Model.class, "type1")
.registerSubtype(Type2Model.class, "type2");
Gson gson = new GsonBuilder().registerTypeAdapterFactory(typeAdapterFactory)
.create();
JSONを基本クラスに逆シリアル化します。
String jsonString = ...
BaseClass baseInstance = gson.fromJson(jsonString, BaseClass.class);
baseInstance
はどちらかのinstanceofになりますType1Model
またはType2Model
。
ここから、インターフェースにコーディングするか、instanceofをチェックしてキャストできます。
次にそれを設定します
_public static final class JsonAdapterFactory extends
RuntimeTypeAdapterFactory<MediumSummaryInfo> {
public JsonAdapterFactory() {
super(MyBaseType.class, "type");
registerSubtype(MySubtype1.class, "type1");
registerSubtype(MySubtype2.class, "type2");
}
}
_
そして注釈を追加します:
@JsonAdapter(MyBaseType.JsonAdapterFactory.class)
myBaseType
ずっといい。