2013-07-17 8 views
7

में जेनेरिक स्ट्रिंग में कनवर्ट करें मेरे पास एक एपीआई है जो जेएसओएन देता है। प्रतिक्रिया कुछ प्रारूप में है जो एपीआरसल्ट नामक ऑब्जेक्ट में फिट हो सकती है और इसमें Context <T> और एक इंट कोड शामिल है।जेएएनए (जेएसओएन के साथ) जेएसओएन स्ट्रिंग को जेएसओएन (जीएसओएन के साथ)

ApiResult को सामान्य तरीके से घोषित किया गया है, उदा। ApiResult<SomeObject>

मैं कैसे GSON ApiResult<T>

को भेजे JSON स्ट्रिंग परिवर्तित करने के लिए प्राप्त करने के लिए जानना चाहते हैं अब तक मेरे पास है:

Type apiResultType = new TypeToken<ApiResult<T>>() { }.getType(); 
ApiResult<T> result = gson.fromJson(json, apiResultType); 

लेकिन यह अभी भी देता है एक LinkedHashMap के संदर्भ के बजाय धर्मान्तरित (जो मुझे लगता है कि जीएसओएन वापस क्या आता है)

उत्तर

1

आपको जीसन को T का प्रकार प्रदान करना होगा। चूंकि जीएसएन नहीं जानता कि एडाप्टर को किस प्रकार लागू किया जाना चाहिए, यह बस एक डेटा संरचना वापस कर देता है।

आपका, जेनेरिक प्रदान करने के लिए की तरह है:

static TypeToken<?> getGenToken(final Class<?> raw, final Class<?> gen) throws Exception { 
    Constructor<ParameterizedTypeImpl> constr = ParameterizedTypeImpl.class.getDeclaredConstructor(Class.class, Type[].class, Type.class); 
    constr.setAccessible(true); 
    ParameterizedTypeImpl paramType = constr.newInstance(raw, new Type[] { gen }, null); 

    return TypeToken.get(paramType); 
    } 

आपका कॉल किया जाएगा (लेकिन String.class की जगह:

Type apiResultType = new TypeToken<ApiResult<String>>() { }.getType(); 

टी के प्रकार के केवल कार्यावधि में जाना जाता है, मैं कुछ मुश्किल का उपयोग एक चर के साथ):

Type apiResultType = getGenToken(ApiResult.class, String.class); 
+0

तो मैं ले कि टी अपने उदाहरण में प्रकार स्ट्रिंग की है:

String data = getJsonString(); ObjectMapper mapper = new ObjectMapper(); List<AndroidPackage> packages = mapper.readValue(data, List.class); 

हो सकता है कि यह आपके मामले में GSON साथ सही तरीका क्या है । लेकिन मेरे पास स्ट्रिंग नहीं है लेकिन टी। आखिरी कथन (असाइनमेंट) कैसे बदल जाएगा? – Yannis

+0

हाँ, मुझे लगता है कि आपके पास 'String.class' (' getGenToken' में) के स्थान पर सेट करने के लिए 'कक्षा 'var है)। लेकिन शायद यह आपके मामले पर लागू नहीं होता है। – PomPom

4

आपको पता होना चाहिए कि टी क्या होने जा रहा है। आने वाले JSON मूल रूप से सिर्फ पाठ है। जीएसओएन को पता नहीं है कि आप किस वस्तु को बनना चाहते हैं। सुराग के बंद अपने टी उदाहरण बनाने के लिए, आप कुछ इस तरह कुछ नहीं कर सकता है कि JSON में कुछ है कि आप कर सकते हैं: मैं क्या मेरी एक्स होने की जरूरत है तय करने के लिए एक क्षेत्र "_class" का उपयोग कर रहा

public static class MyJsonAdapter<X> implements JsonDeserializer<ApiResult<X>> 
{ 
    public ApiResult<X> deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) 
     throws JsonParseException 
    { 
     String className = jsonElement.getAsJsonObject().get("_class").getAsString(); 
     try 
     { 
     X myThing = context.deserialize(jsonElement, Class.forName(className)); 
     return new ApiResult<>(myThing); 
     } 
     catch (ClassNotFoundException e) 
     { 
     throw new RuntimeException(e); 
     } 
    } 
} 

और प्रतिबिंब के माध्यम से इसे तत्काल (PomPom के उदाहरण के समान)। आपके पास शायद इस तरह का एक स्पष्ट क्षेत्र नहीं है, लेकिन आपके लिए जेसन एलेमेंट को देखने और निर्णय लेने के लिए कुछ तरीका होना चाहिए कि यह किस प्रकार का एक्स होना चाहिए। https://github.com/chriskessel/MyHex/blob/master/src/kessel/hex/domain/GameItem.java

+0

मैं कोड की जांच करूंगा और मुझे संदेह है कि मुझे ऐसा कुछ करना था जैसा आपने सुझाया था लेकिन .NET कार्यों में वही (या समान) कोड था। तो इसका मतलब है कि मुझे एक विशिष्ट भाषा को पूरा करने के लिए एक सामान्य एपीआई बदलनी है? .NET रनटाइम पर पा सकता है कि टी बिना किसी जेसन में एक विशेष _ क्लास फ़ील्ड है। – Yannis

+0

.NET कोड को जानने के बिना, मुझे नहीं पता कि यह कैसे काम करेगा। टी में कोई क्लास वैल्यू नहीं है, इसलिए .NET को यह नहीं पता होगा कि किस वर्ग का उपयोग करना है जब तक कि कुछ इसे नहीं बताता। –

0

मैं JacksonJson पुस्तकालय, काफी GSon के लिए इसी तरह का उपयोग करें:

इस कोड को कुछ इसी तरह मैं एक समय पहले GSON के साथ किया था के एक हैक्ड संस्करण है, पर लाइन 184+ देखते हैं। यह कुछ सामान्य प्रकार वस्तु के लिए इस तरह से json स्ट्रिंग परिवर्तित करने के लिए संभव है:

ApiResult<T> result = gson.fromJson(json, ApiResult.class);