2012-10-31 6 views
5

現在Flexjsonを使用してJSON文字列を逆シリアル化して、 Android Appのオブジェクトモデルにマップしようとしています。このアプリケーションは、より多くのカタログ を持ついくつかのカタログを持つことができ、それらの文書を含むことができるいくつかのベンダーのライブラリの一種です。Java/AndroidでFlexjsonを使用してJSONObjectをリストにマッピングする

{ 
    "library":{ 
     "vendor":[ 
      { 
       "id":146, 
       "title":"Vendor1", 
       "catalog":[ 
        { 
         "id":847, 
         "document":[ 
          { 
           "id":1628, 
           "title":"Document", 
       ... 
          }, 
          { 
       ... 
          } 
         ], 
         "title":"Catalog ", 
        }, 
       { 
       ... 
       } 
       ] 
      }, 
      { 
      ... 
      } 
     ] 
    } 
} 

したがって、各ベンダー、カタログ、文書はJSONObjectで表され、すべての子のカタログと文書がJSONArray内にあるさ:JSONは私が影響を及ぼさないと次のようになり、Webサービスから取得されます。 これまでのところ、すべてがFlexjsonと、次のデシリアライゼーションコードで正常に動作します:

LibraryResponse response = new JSONDeserializer<LibraryResponse>() 
        .use(Timestamp.class, new TimestampObjectFactory()) 
        .deserialize(getLocalLibrary(), LibraryResponse.class); 
return response.library; 

私はList<Vendor>を持つライブラリのオブジェクトを持っています。各ベンダーはList<Catalog>List<Document>です。

残念ながら、カタログに単一のドキュメント が含まれている場合、またはカタログにカタログが1つしか含まれていない場合、WebサービスによってJSONArraysが単純なJSONObjectsに分解されます。だから、その場合のJSONは次のようになります。

"document": 
    { 
     "id":1628, 
     "title":"Document", 
     ... 
    } 

今Flexjsonはデシリアライズする方法を知っていないと私はlibrary.vendorX.getDocument()の代わりにList<Document>List<HashMap>ことで終わります。 Flexjsonに明示的にそのようなケースの処理方法を伝えることが考えられますが、どこから始めたらいいか分かりません。別の方法は、最初のJSONを手動で解析し、そのようなJSONObjectを適切なJSONArrayに置き換えることです。しかし、私は、ライブラリがかなり深いことができるので、その方法は本当にいいとは思いません。

ここにいくつかのガイダンスを提供していただければ幸いです。

答えて

1

これはややこしいjsonマッピングです。どのバックエンドコーダーがそれをしましたか? #NotHelping。

コードを見ると、Flexjsonはすぐにこれを処理するようにコードされています。しかし、型情報をバインドに渡していないように見えるので、バインドされている型がわからず、マップを返すだけです。これはおそらく修正されるべきであるバグです。 良いニュースは、を回避することです。

とにかく、私が考えることができる最も簡単なことは、ObjectFactoryをそのリストにインストールすることです。次に、ストリームがデシリアライズされたときにMapまたはListが得られたかどうかを確認して確認できます。それをリストにラップし、それを適切なデコーダに送ることができます。ような何か:次に

LibraryResponse response = new JSONDeserializer<LibraryResponse>() 
       .use(Timestamp.class, new TimestampObjectFactory()) 
       .use("library.vendor.values.catalog.values.document", new ListDocumentFactory()) 
       .deserialize(getLocalLibrary(), LibraryResponse.class); 

public class ListDocumentFactory implements ObjectFactory { 

    public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) { 
     if(value instanceof Collection) { 
      return context.bindIntoCollection((Collection)value, new ArrayList(), targetType); 
     } else { 
      List collection = new ArrayList(); 
      if(targetType instanceof ParameterizedType) { 
       ParameterizedType ptype = (ParameterizedType) targetType; 
       collection.add(context.bind(value, ptype.getActualTypeArguments()[0])); 
      } else { 
       collection.add(context.bind(value)); 
       return collection; 
      } 
     } 
    } 
} 

は、私はそのバグを修正するだろうか大体だと思うが、またあなたの問題を解決する必要があります。

+0

あなたの答えをありがとう!私は自分自身を明らかにしなかったと思いますが、私は常にリストを取得しますが、ドキュメントが1つしかない場合、Listに 'Documents'がありませんが、' HashMaps'は 'List 'を 'catalog.document' 'List '。ハッシュマップオブジェクトには、ドキュメントに接続されたデータが含まれます。私には不思議そうだ。私はすでにドキュメントを持っているかどうかを判断するファクトリが必要か、ハッシュマップがあるかどうかを判断するファクトリが必要だと思います。後者の場合は、ドキュメントオブジェクトを手動でマップします。私の最初の試みは失敗しました。このアプローチは可能だと思いますか? –

+0

私の答えがあなたの問題にどう答えなかったのか分かりません。リストの代わりにリストを取得している理由は、Flexjsonのバグです。 JSONDeserializerはまずJSONをList、Map、String、Number、Booleanのような単純なオブジェクトに変換します。次に、一連のObjectFactoryを使用して、これらの単純なオブジェクトをマッピングしている実際のオブジェクトにマップします。ですから、ObjectFactoryレイヤーは、Documentのような厳密な型指定されたオブジェクトを前にしています。そこで、デフォルトのインスタンスを使用する代わりに、私が示したように、独自のObjectFactoryを記述することでその点にプラグインします。 – chubbsondubs

+0

申し訳ありませんが、私はそこにあなたが間違っていると思います。とにかく、あなたがコード化しようとすると、 'ParameterizedType ptype =(ParameterizedType)targetType;で例外が発生します。' 'java.lang.ClassCastException:java.lang.Classはjava.lang.reflect.ParameterizedType'にキャストできません。もう1つの質問: 'library.vendor.values.catalog.values.document'で使用するFactoryを指定した場合、' library.vendor.values.document'として他のレベルに影響しませんか?ベンダーでさえドキュメントを持つことができるので...他のすべてのスーパークラスである 'LibraryItem.class'で使用するファクトリを指定することは可能でしょうか? –

関連する問題