2012-10-31 12 views
5

मैं वर्तमान में एक JSON स्ट्रिंग को deserialize करने के लिए फ्लेक्सनसन का उपयोग करने की कोशिश कर रहा हूं और इसे अपने एंड्रॉइड ऐप के ऑब्जेक्ट मॉडल पर मैप कर रहा हूं। यह एप्लिकेशन कई विक्रेताओं के साथ एक प्रकार की लाइब्रेरी है जिसमें अधिक कैटलॉग और उनमें दस्तावेज़ों के साथ कुछ कैटलॉग हो सकते हैं। json एक वेब सेवा मैं पर कोई असर नहीं है से प्राप्त की है और इस तरह दिखता है:जावा/एंड्रॉइड 0 में फ्लेक्सजॉन के साथ एक सूची में JSONObject मैपिंग

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

तो प्रत्येक विक्रेता, सूची, दस्तावेज़ एक JSONObject और सभी बच्चे कैटलॉग और दस्तावेजों का प्रतिनिधित्व करती है एक JSONArray के भीतर हैं। अब तक सब कुछ Flexjson और निम्नलिखित अक्रमांकन कोड के साथ ठीक काम करता है:

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

मैं एक पुस्तकालय वस्तु एक List<Vendor> है की क्या ज़रूरत है। प्रत्येक विक्रेता के पास List<Catalog> और List<Document> है।

लेकिन दुर्भाग्यवश, वेब सेवा JSONArrays को सरल JSONObjects पर स्ट्रैप्स करती है यदि किसी कैटलॉग में केवल एक दस्तावेज़ होता है या किसी कैटलॉग में केवल एक कैटलॉग होता है। तो उस मामले में json इस तरह दिखता है:

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

अब Flexjson एक List<Document> के बजाय एक List<HashMap> जा रहा है) कैसे deserialize करने के लिए पता नहीं है और मैं एक library.vendorX.getDocument (अंत। एक विचार है कि फ्लेक्ससन को स्पष्ट रूप से ऐसे मामलों को संभालने का तरीका बताएं, लेकिन मुझे नहीं पता कि इस से कहां से शुरुआत करें। एक और तरीका प्रारंभिक जेसन मैन्युअल रूप से पार्स करना और उचित JSONArray के साथ ऐसे JSONObjects को प्रतिस्थापित करना हो सकता है। लेकिन मुझे लगता है कि इस तरह से जाने के लिए वास्तव में अच्छा नहीं है, क्योंकि लाइब्रेरी बहुत गहरी हो सकती है।

मुझे आशा है कि आप यहां कुछ मार्गदर्शन प्रदान कर सकते हैं।

उत्तर

1

यिक्स यह कुछ gnarly json मैपिंग चल रहा है। बैकएंड कोडर ने क्या किया ?! #NotHelping।

अच्छी तरह से कोड को देखने से, फ्लेक्सजसन को बॉक्स के बाहर इसे संभालने के लिए कोड किया गया है। लेकिन ऐसा लगता है कि यह टाइपिंग जानकारी को बाध्य करने के लिए पास नहीं कर रहा है, इसलिए यह नहीं जानता कि यह किस प्रकार बाध्यकारी है ताकि यह सिर्फ एक नक्शा लौटा सके। यह बग है जो शायद तय किया जाना चाहिए। अच्छी खबर यह है कि के आसपास एक काम है।

वैसे भी, सबसे सरल बात यह है कि मैं उस सूची में ऑब्जेक्ट फैक्ट्री स्थापित करना चाहता हूं। फिर आप जांच कर सकते हैं और देख सकते हैं कि स्ट्रीम को deserialized होने पर आपको मानचित्र या सूची मिलती है या नहीं। फिर आप इसे एक सूची में लपेट सकते हैं और उचित डिकोडर पर भेज सकते हैं। कुछ की तरह:

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

आपके उत्तर के लिए धन्यवाद! मुझे लगता है कि मैंने खुद को स्पष्ट नहीं किया है, मुझे हमेशा एक सूची मिलती है, लेकिन यदि केवल एक दस्तावेज़ है तो मेरे पास सूची में 'दस्तावेज़' नहीं है लेकिन 'हैशमैप्स' है, इसलिए 'सूची ' के बजाय 'catalog.document'' 'सूची '। हैश मैप ऑब्जेक्ट्स में दस्तावेज़ से जुड़े डेटा होते हैं। मुझे अजीब लग रहा है। मुझे लगता है कि मुझे एक कारखाने की ज़रूरत है जो तय करता है कि हमारे पास पहले से कोई दस्तावेज़ है या यदि हमारे पास 'हैश मैप' है। यदि उत्तरार्द्ध मैं मैन्युअल रूप से दस्तावेज़ ऑब्जेक्ट को मैप करता हूं।हालांकि, मेरी पहली कोशिश विफल रही। क्या आपको लगता है कि यह दृष्टिकोण संभव है? –

+0

मैं यह देखने में असफल रहा कि मेरे जवाब ने आपकी समस्या का उत्तर कैसे दिया। मुझे लगता है कि सूची की बजाय आपको सूची प्राप्त करने का कारण फ्लेक्सज़न में एक बग है। JSONDeserializer पहले जेएसओएन को सरल वस्तुओं जैसे सूची, मानचित्र, स्ट्रिंग, संख्या, और बूलियन में अनुवाद करता है। फिर यह ऑब्जेक्ट फैक्ट्री की एक श्रृंखला का उपयोग उन साधारण वस्तुओं को उन वास्तविक वस्तुओं में मैप करने के लिए करता है, जिनमें आप मैपिंग कर रहे हैं। तो ऑब्जेक्ट फैक्ट्री परत हमारे पास दस्तावेज़ की तरह कोई मजबूत टाइप की गई वस्तु है। तो आप उस बिंदु पर प्लग करेंगे जो आपके ऑब्जेक्ट फैक्ट्री को लिखते हैं जैसे मैंने डिफ़ॉल्ट उदाहरण का उपयोग करने के बजाय दिखाया। – chubbsondubs

+0

मुझे खेद है, मुझे लगता है कि मैंने आपको वहां गलत समझा। वैसे भी, जब आप कोड को आज़माते हैं तो मुझे 'पैरामीटरेटेड टाइप टाइप/= पैरामीटरेट टाइप टाइप) टाइप अप टाइप पर एक अपवाद मिल रहा है; 'java.lang.ClassCastException: java.lang.Class java.lang.reflect.ParameterizedType' पर नहीं डाला जा सकता है। एक और सवाल: यदि मैं 'library.vendor.values.catalog.values.document' पर उपयोग की जाने वाली फैक्ट्री निर्दिष्ट करता हूं तो यह अन्य स्तरों को' library.vendor.values.document' के रूप में प्रभावित नहीं करेगा? यहां तक ​​कि एक विक्रेता के पास दस्तावेज भी हो सकते हैं ... क्या 'लाइब्रेरीइटम.क्लास' पर इस्तेमाल होने वाले कारखाने को निर्दिष्ट करना संभव होगा जो कि अन्य सभी का सुपरक्लास है? –

संबंधित मुद्दे