2016-09-29 12 views
6

मैं एक ऐप पर काम कर रहा हूं जो जीएसओएन का उपयोग जेसन deserializer के रूप में कर रहा है और आरईएसटी एपीआई से polymorphic जेसन deserialize करने की जरूरत है। मील इश्यू नोट को समझाने से पहले कि मैं पहले से ही जीएसओएन के साथ पॉलिमॉर्फिक deserialization के आसपास देख रहा है और इसे कई मामलों में सफलतापूर्वक लागू किया है। तो यह एक विशिष्ट मुद्दा है जो मैं कर रहा हूं। इसके अलावा मैंने यह पूछने से पहले this great post और this stackoverflow discussion पढ़ा है। मैं रास्ते से polymorphic वस्तुओं deserialize करने के लिए RuntimeTypeAdapterFactory का उपयोग कर रहा हूँ।जीएसओएन फेंकने के अपवाद के साथ पॉलिमॉर्फिक जेएसओएन deserializing

समस्या मैं आ रही है जाहिरा तौर पर GSON के RuntimeTypeAdapterFactory शामिल नहीं है कि क्षेत्र है जो पदानुक्रम संरचना के भीतर वस्तु के प्रकार को निर्दिष्ट घोषित करने के लिए अनुमति देते हैं। मैं कुछ कोड के साथ आगे समझाऊंगा।

public abstract class BaseUser { 
    @Expose 
    protected EnumMobileUserType userType; 
} 


public class User extends BaseUser { 
    @Expose 
    private String name; 
    @Expose 
    private String email;  
} 

public class RegularUser extends User { 
    @Expose 
    private String address;  
} 

public class SpecialUser extends User { 
    @Expose 
    private String promoCode; 
} 

अब इस कोड मैं कहाँ उपयोगकर्ता पदानुक्रम के लिए runtimeTypeAdapterFactory परिभाषित किया गया है: मैं निम्नलिखित POJOs संरचना (POJOs सरलता के लिए कम हो गया था) है।

public static RuntimeTypeAdapterFactory<BaseUser> getUserTypeAdapter() { 
    return RuntimeTypeAdapterFactory 
     .of(BaseUser.class, "userType") 
     .registerSubtype(User.class, EnumMobileUserType.USER.toString()) 
     .registerSubtype(RegularUser.class, EnumMobileUserType.REGULAR.toString()) 
     .registerSubtype(SpecialUser.class, EnumMobileUserType.SPECIAL.toString()); 
} 

public static Gson getGsonWithTypeAdapters() { 
    GsonBuilder builder = new GsonBuilder(); 
    builder.registerTypeAdapterFactory(getUserTypeAdapter()); 
    return builder.create(); 
} 

अब जब मैं एक json deserialize करने की कोशिश:

{ 
    "user":{ 
     "userType":"USER", 
     "email":"[email protected]", 
     "name":"Albert" 
    } 
} 

मैं इस अपवाद

com.google.gson.JsonParseException: cannot serialize com.mobile.model.entities.v2.common.User because it already defines a field named userType 

लेकिन अगर मैं अपने BaseUser कक्षा में संपत्ति "प्रयोक्ता प्रकार" का नाम बदलने उदाहरण के लिए "टाइप करें" और मैं वही जेसन सब कुछ ठीक से deserialize। मुझे नहीं पता कि जीएसओएन रनटिम टाइप टाइप एडाप्टर फैक्ट्री में यह प्रतिबंध क्यों है। वास्तव में this blog post में जाहिर है यह कोई मुद्दा नहीं है।

क्या कोई यह बता सकता है कि यहां क्या हो रहा है, इस प्रकार को परिभाषित करने वाले संपत्ति का नाम pojos पदानुक्रम के अंदर परिभाषित नहीं किया जा सकता है?

EDIT समस्या तब निराशाजनक नहीं होती है जब ऊपर वर्णित कोड का उपयोग करके क्रमबद्ध किया जाता है। उत्तर में और स्पष्टीकरण प्राप्त करें।

+0

त्रुटि के अनुसार करना होगा क्या आप वाकई 'User' में क्षेत्र' userType' घोषित नहीं किया है वर्ग भी? इसे पहले से ही 'बेसयूसर' कक्षा में घोषित किया गया है, इसलिए इसे फिर से शुरू करने की आवश्यकता नहीं है। –

+0

हाय ज्योतिमैन। नहीं, मैंने यह सुनिश्चित कर लिया है कि मैं दो बार फ़ील्ड usertype घोषित नहीं कर रहा हूं। यह केवल मूल उपयोगकर्ता पर घोषित किया गया है।इसके अलावा मैंने प्रश्न के अंत में कहा था कि deserialization बेस यूज़र क्लास से फ़ील्ड उपयोगकर्ता टाइप का नाम बदलकर ठीक काम कर रहा है जो जेसन और रनटाइम टाइप एडाप्टर फैक्ट्री पर घोषित किए गए कुछ से अलग है। लेकिन सुझाव के लिए धन्यवाद! – JorgeMuci

उत्तर

4

ठीक है, कुछ समय बाद खुदाई के बाद मुझे पता चला कि समस्या वास्तव में deserializing नहीं है, समस्या तब आती है जब serializing और एक runtimeTypeFactory सवाल में वर्णित के रूप में पंजीकृत है। यदि आप एक runtimeTypeAdapterFactory रजिस्टर और वर्ग प्रकार, POJO serializing से उत्पन्न json एक SpecialUser के लिए RuntimeTypeAdapterFactory साथ GSON का उपयोग कर JSON करने के लिए कारखाने में और अपने POJO में परिभाषित करने के लिए एक ही फ़ील्ड नाम का उपयोग करते हैं, उदाहरण के लिए होगा:

{ 
    "user":{ 
     "userType":"SPECIAL", 
     "email":"[email protected]", 
     "name":"Albert" 
     "userType":"SPECIAL" 
    } 
} 

यह अपवाद वर्णित में परिणाम होगा: डी क्षेत्र प्रयोक्ता प्रकार GSON serializer, के रूप में वर्ग BaseUser के लिए पंजीकृत RuntimeTypeAdapterFactory में घोषित जो स्वत: एक क्षेत्र जोड़ देगा के कारण json में दोहराया है

com.google.gson.JsonParseException: cannot serialize com.mobile.model.entities.v2.common.User because it already defines a field named userType 

क्योंकि।

1

मैं, लगता है कि @Expose एनोटेशन बिना अपने स्वयं के प्रयोक्ता प्रकार का उपयोग कर चाल

regads

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