2013-06-09 5 views
12

जीसन में जेसनराइटर एक महान पुस्तकालय है - यह अच्छी तरह से काम करता है। कभी-कभी मेरे पास कस्टम आवश्यकताएं होती हैं, और TypeAdapters और TypeAdaptorFactories को पंजीकृत और पंजीकृत कर सकती हैं - और यह भी अच्छी तरह से काम करती है।कस्टम टाइपैडाप्टर का उपयोग करके ऑब्जेक्ट जोड़ना, जीएसएन

हालांकि मुझे क्या भ्रमित करता है, जेसन सीरियलाइजेशन में वापस कैसे प्रतिनिधि करना है ... अधिकांश समय मुझे संग्रह के लिए इसकी आवश्यकता होती है, लेकिन बिंदु को स्पष्ट करने के लिए - मान लीजिए कि मेरे पास एक जोड़ी कक्षा थी, जो जीसन स्पष्ट रूप से खुशी से क्रमबद्ध होगा, लेकिन किसी कारण से मुझे अपने स्वयं के कस्टम धारावाहिक की आवश्यकता थी। खैर ... मेरी जोड़ी

public class Pair 
{ 
    public final Object First; 
    public final Object Second; 
    public Pair(Object first, Object second) {this.first = first; this.second = second}; 
} 

अगर मैं इस के लिए एक प्रकार एडाप्टर लिखा है अगर - आप चाहेगा लिखने समारोह की तरह लग रहे करने के लिए:

public void write(JsonWriter out, Pair pair) 
{ 
    out.beginObject(); 
    out.name("first"); 
    out.value(pair.first);   // can't do this 
    out.name("second"); 
    out.value(pair.second);   // or this 
    out.endObject(); 
} 

तो तुम समस्या देख सकते हैं - मेरे पास कोई विचार नहीं है पहला और दूसरा प्रकार, न ही वे क्रमबद्ध कैसे हैं। मैं gson.toJson का उपयोग पहले और दूसरे क्रमबद्ध करने के लिए कर सकता हूं - लेकिन अगर मैं उन्हें लेखक के लिए एक स्ट्रिंग के रूप में जोड़ता हूं, तो वे बच जाएंगे। एक gson.tojson फ़ंक्शन है जो एक मूल्य और लेखक लेता है - लेकिन यह एक टाइपेटोकन भी लेता है - जो मेरे पास नहीं है। मैं इंप्रेशन प्राप्त करता हूं जिसका मतलब है कि मेरा कहीं और प्रकार एडाप्टर है - लेकिन जब मेरे पास ऑब्जेक्ट्स की एक सूची है ... मुझे यह कहां मिल सकता है? क्या मुझे ऑब्जेक्ट के लिए एडाप्टर मिल गया है?

मैं थोड़ा उलझन में हूँ? निश्चित रूप से यह सबसे आम उपयोग मामला है? अधिकांश कस्टम धारावाहिक टी या कुछ टी के पेड़ की एक अजीब सूची के लिए होंगे, और आप वास्तव में नहीं जानते कि सूची में क्या है, इससे परे कि यह टी से विरासत में है ... इसलिए आपको वापस प्रतिनिधि को सक्षम करने की आवश्यकता है serialization किसी तरह से?

वैसे भी - अगर कोई मुझे बता सकता है कि उपर्युक्त फ़ंक्शन कैसे लिखना है, तो मैं वास्तव में इसकी सराहना करता हूं!

उत्तर

22

इस मामले में अपनी बेहतर उनकी क्रमबद्धता संदर्भ के लिए एक JsonSerializer उपयोग करने के लिए के रूप में एक TypeAdapter करने का विरोध किया, सरल कारण के लिए है कि serializers उपयोग कर सकते है:

public class PairSerializer implements JsonSerializer<Pair> { 

    public PairSerializer() { 
     super(); 
    } 

    @Override 
    public JsonElement serialize(final Pair value, final Type type, 
      final JsonSerializationContext context) { 
     final JsonObject jsonObj = new JsonObject(); 
     jsonObj.add("first", context.serialize(value.getFirst())); 
     jsonObj.add("second", context.serialize(value.getSecond())); 

     return jsonObj; 
    } 
} 

ऊपर नमूना कोड को दिखाता है लक्ष्य की क्रमबद्धता को सौंपने के लिए कैसे वस्तुओं को मुख्य मार्शलर पर वापस ले जाएं। इसका मुख्य लाभ (जटिल कामकाज से बचने के अलावा) यह है कि आप अभी भी अन्य प्रकार के एडेप्टर और कस्टम धारावाहिकों का लाभ उठा सकते हैं जो मुख्य संदर्भ में पंजीकृत हो सकते हैं। नोट serializers की कि पंजीकरण और एडेप्टर ठीक उसी कोड का उपयोग करें:

// With adapter 
final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class, 
     new PairAdapter()).create(); 

// With serializer 
final Gson gson = new GsonBuilder().registerTypeAdapter(Pair.class, 
     new PairSerializer()).create(); 

आप पाते हैं कि आप एक एडाप्टर के साथ छड़ी की जरूरत है, तो आप के साथ, आप के लिए जोड़ी गुण क्रमानुसार करने एक एम्बेडेड Gson प्रॉक्सी का उपयोग कर सकते हैं नुकसान यह है कि आप माता-पिता जीसन प्रॉक्सी पर किए गए कस्टम पंजीकरण तक पहुंच खो देते हैं:

public class PairAdapter extends TypeAdapter<Pair> { 
    final Gson embedded = new Gson(); 

    public PairAdapter() { 
     super(); 
    } 

    @Override 
    public void write(final JsonWriter out, final Pair value) 
      throws IOException { 
     out.beginObject(); 

     out.name("first"); 
     embedded.toJson(embedded.toJsonTree(value.getFirst()), out); 

     out.name("second"); 
     embedded.toJson(embedded.toJsonTree(value.getSecond()), out); 

     out.endObject(); 
    } 

    @Override 
    public Pair read(JsonReader in) throws IOException { 
     throw new UnsupportedOperationException(); 
    } 
} 
+0

धन्यवाद - यह आपको जाने देगा –

3

वास्तव में काम करना प्रतीत होता है - ऑब्जेक्ट के लिए एडाप्टर प्राप्त करना - ऑब्जेक्ट पर "जेसन" विधि खोजने के लिए टाइपडैप्टोफोरेट्री का उपयोग करके, और उस स्टोर को एडाप्टर ऑब्जेक्ट को दूर करना। इस तरह के एक स्पष्ट उपयोग मामले के लिए आश्चर्यजनक रूप से जटिल लगता है?

जैसे:

public static @Nullable 
TypeAdapter<ImmutableStack<?>> json(final Gson gson) 
{ 
    final TypeAdapter<Object> adaptor = gson.getAdapter(Object.class); 
    return new TypeAdapter<ImmutableStack<?>>() 
    { 
     @Override 
     public ImmutableStack<?> read(@Nullable final JsonReader in) throws IOException 
     { 
      throw ProgramError.notImplementedYet(); 
     } 
     @Override 
     public void write(final JsonWriter out, final ImmutableStack<?> value) throws IOException 
     { 
      out.beginArray(); 
      for (final Object inner : value) 
       adaptor.write(out, inner); 
      out.endArray(); 
     } 
    }; 
} 

किसी को भी यह करने के लिए एक बेहतर तरीका पता है?

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