1

次のような JSON 構造を解析しようとしています。

    {
 "cars": {
  "112": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1998"
  },
  "642": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "1990"
  },
  "9242": {
   "make": "Cadillac",
   "model": "Eldorado",
   "year": "2001"
  }
 }}

私は、セッター/ゲッターを介して定義され、アクセス可能なmakeName、model、year属性で定義されたCarEntityクラスを持っています。

この JSON を次のように逆シリアル化しようとしています。

    Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json);

そしてそれは機能しません:(それはそれをデシリアライズしますが、Map<String, CarEntity>ディープマップにはデシリアライズしません(のようなものMap<String, Map<String, Map<String, String>>>)

私は何を間違っていますか?

4

3 に答える 3

2

問題は、json に 2 つのマップがあることです。「cars」キーを含むものと、実際の CarEntity を含むものです。残念ながら、現時点では Map 内の単一のキーを参照して、そのキーだけに型を割り当てることはできません。通常、コレクションの値に型を設定すると、コレクション内のすべての値が参照されます。「cars」キーを含む最初の Map のタイプを指定する必要はありません。これは、デフォルトで逆シリアル化されるためです。

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String,Map<String, CarEntity>>>()
    .use("values.values", CarEntity.class )
    .deserialize(json).get("cars");

パス「values.values」は外側のマップの値を参照し、次のマップの値をトラバースすると、すべて CarEntity インスタンスになります。

パス式をより表現力豊かに変更して、コレクション内の単一の値を対象にできるようにすることを検討しましたが、これにより、それらを評価するオーバーヘッドが増加し、後方互換性を維持することが課題になります。

于 2010-11-02T18:07:58.647 に答える
1

Java型消去に噛まれている可能性があります。問題のJSONライブラリは必要な型を認識していません。表示されるのはMapと同等です。したがって、少なくとも値型を何らかの方法で指定する必要があります。うまくいけば、FlexJSONのドキュメントでその方法が指摘されています。

あるいは、HashMapを独自のタイプにサブクラス化できる場合があります(MyEntityMapはHashMapを拡張します)。これにより、タイプ情報を汎用スーパータイプから推測できるようになります。MyEntityMap.classを渡すと、ほとんどのJSONライブラリ(少なくともJacksonとGSON)が使用できる型情報が得られます。

これらが機能しない場合、JacksonおよびGSONライブラリはこのユースケースを簡単に処理できます。どちらにも、逆シリアル化のジェネリック型を指定するメソッドがあります。

于 2010-11-02T16:31:22.567 に答える
0

get("cars")likeの呼び出しをもう 1 つ追加するだけです。

Map<String, CarEntity> deserialized = new JSONDeserializer<Map<String, CarEntity>>()
   .use("cars.values", Map.class)
   .deserialize(json).get("cars");

jSon 文字列は、次のようにcars型指定された変数からシリアル化された可能性があります。Map<String, CarEntity>

于 2010-11-02T14:02:54.693 に答える