は、私たちが、このJSONがあるとします。モシで汎用タイプをデシリアライズする方法は?
[
{
"__typename": "Car",
"id": "123",
"name": "Toyota Prius",
"numDoors": 4
},
{
"__typename": "Boat",
"id": "4567",
"name": "U.S.S. Constitution",
"propulsion": "SAIL"
}
]
(リストへのより多くの要素があるかもしれないが、これは2つだけ表示されます)
を私は共通のためVehicle
基本クラスを使用しCar
とBoat
POJOを持っていますフィールド:
public abstract class Vehicle {
public final String id;
public final String name;
}
public class Car extends Vehicle {
public final Integer numDoors;
}
public class Boat extends Vehicle {
public final String propulsion;
}
List<Vehicle>
する必要があります。このJSONを解析した結果。問題は、__typename
がBoat
をCar
から区別する方法であることをJSONパーサが知っていることはないことです。 Gsonで
、私は適切な型に特定のJSONオブジェクトを解析するために供給さJsonDeserializationContext
にdeserialize()
を使用し、次いで、これはCar
又はBoat
であるか否かを識別し、__typename
フィールドを調べることができるJsonDeserializer<Vehicle>
を作成することができます。これは正常に動作します。
しかし、私が構築しようとしていることは、差し替え可能なJSONパーサをサポートしなければならないことです。代替パーサとしてMoshiを試してみると思いました。しかし、現時点では、この特定の問題はMoshiの文書ではうまくカバーされておらず、どのように対処するのが最善かを理解するのが難しいです。
JsonDeserializer<T>
is JsonAdapter<T>
と最も類似しています。ただし、fromJson()
は、破壊的なAPIを持つJsonReader
を渡します。 __typename
が何であるかを知るには、私はJsonReader
イベントから手作業ですべてを解析できる必要があります。私はadapter()
on the Moshi
instanceと呼んで、いったん適切な具体的な型を知ったら、既存のMoshi構文解析ロジックを呼び出すことができましたが、私はJsonReader
のデータを消費し、完全なオブジェクト記述を提供できなくなります。
JsonDeserializer<Vehicle>
の別のアナログはで、Vehicle
を返します。しかし、私はこのメソッドに渡す簡単なことを特定することはできません。私はMoshi
と型アダプタとして登録クラスに@FromJson Vehicle rideLikeTheWind(SemiParsedKindOfVehicle rawVehicle)
を持っている場合、理論的には、
public class SemiParsedKindOfVehicle {
public final String id;
public final String name;
public final Integer numDoors;
public final String propulsion;
public final String __typename;
}
その後:私は考えることができる唯一のことは、すべての可能なフィールドの和集合を表すさらに別のPOJOを作成することですMoshiはJSONオブジェクトをSemiParsedKindOfVehicle
インスタンスに解析し、rideLikeTheWind()
を呼び出すことができます。そこで、私は__typename
を探し、タイプを特定して、Car
またはBoat
を完全に構築し、そのオブジェクトを返します。
実行可能ですが、これはGsonのアプローチよりもかなり複雑です。Car
/Boat
シナリオは、対処する必要がある可能なデータ構造の簡単な終わりです。
Moshiでこれを処理する別の方法がありますか?
次のバージョンのMoshiでは、多態性の逆シリアル化がよりうまくサポートされるようになりました。 (すべての詳細へのリンクについては、https://github.com/square/moshi/issues/89を参照してください)。私は今、モシのタグに従っているので、任意のすべての質問を撃つ! –
@EricCochran:情報ありがとう!しかし、私が問題を誤読していない限り、その問題は多態的な直列化に関係していないようです。 – CommonsWare
おそらく最も重要なことに、 'JsonAdapter.fromJsonValue(Object)'(https://github.com/square/moshi/pull/234/files)は、Mapsなどからこれらの値を作成するのに役立ちます。 –