2010-12-28 30 views
11

मैं जीएसओएन का उपयोग कर जेएसओएन में नीचे अपनी उदाहरण कक्षा को क्रमबद्ध करना चाहता हूं।जीएसओएन के साथ मानचित्र के मानचित्र को क्रमबद्ध कैसे करें?

{"General":{"Version":"0.1","Range":{"Start_Time":"now","End_Time":"never"}}} 

लेकिन समारोह toJSON() रिटर्न

{"General":{"Version":"0.1","Range":{}}} 

ऐसा लगता है कि GSON मानचित्र General अंदर मानचित्र Range को क्रमानुसार नहीं कर सकते बुला:

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 
import java.util.LinkedHashMap; 

public class Example 
{ 
    private LinkedHashMap<String,Object> General; 

    private static final String VERSION="Version"; 
    private static final String RANGE="Range"; 
    private static final String START_TIME="Start_Time"; 
    private static final String END_TIME="End_Time"; 

    public Example() { 
     General = new LinkedHashMap<String,Object>(); 
     General.put(VERSION, "0.1"); 

     LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>(); 
     Range.put(START_TIME, "now"); 
     Range.put(END_TIME, "never"); 

     General.put(RANGE, Range); 
    } 

    public String toJSON() { 
     Gson gson = new GsonBuilder().serializeNulls().create(); 
     return gson.toJson(this); 
    } 
} 

मैं निम्नलिखित उत्पादन प्राप्त करने के लिए उम्मीद है। क्या यह जीएसओएन की सीमा है या क्या मैं यहां कुछ गलत कर रहा हूं?

+2

तो अन्य उत्तर दिए गए हैं सही और डिफ़ॉल्ट नक्शा धारावाहिक नेस्टेड मानचित्रों को संभाल नहीं पाएगा, मैं जीएसओएन टीम के लिए एक बग रिपोर्ट दर्ज करूंगा। यह मेरे लिए वास्तव में खराब चूक की तरह लगता है; कम से कम इसे चुपचाप सामग्री निगलने के बजाय अपवाद फेंकना चाहिए। – StaxMan

+0

+1 @StaxMan ऐसा लगता है। मैंने इसे पहले देखा है, कुछ काम के साथ आया था। अगर ऐसा करने का कोई तरीका है, तो यह दस्तावेज के लायक है। – Nishant

उत्तर

8

कारण है कि क्योंकि Gson के डिफ़ॉल्ट निर्माता डिफ़ॉल्ट प्रति सामान कि आप अन्यथा मैन्युअल enably GsonBuilder का उपयोग करने के लिए होता है के सभी प्रकार के लिए सक्षम बनाता है Nishant's answer काम करता है।

JavaDocs से:

डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ एक Gson वस्तु निर्माण करती है। डिफ़ॉल्ट कॉन्फ़िगरेशन में निम्न सेटिंग्स हैं:

  • जेसन विधियों द्वारा जेएसओएन जेनरेट किए गए जेएसओएन कॉम्पैक्ट प्रतिनिधित्व में है। इसका मतलब है कि सभी अनियंत्रित सफेद-जगह हटा दी जाती है। आप इस व्यवहार को GsonBuilder.setPrettyPrinting() के साथ बदल सकते हैं।
  • जेनरेट जेएसओएन उन सभी फ़ील्ड को छोड़ देता है जो शून्य हैं। ध्यान दें कि सरणी में नल को रखा जाता है क्योंकि एक सरणी एक आदेशित सूची है। इसके अलावा, यदि कोई क्षेत्र शून्य नहीं है, लेकिन इसका जेनरेट जेएसओएन खाली है, तो फ़ील्ड रखा जाता है। आप GsonBuilder.serializeNulls() को सेट करके शून्य मानों को क्रमबद्ध करने के लिए जीसन को कॉन्फ़िगर कर सकते हैं।
  • जीसन एनम्स, मानचित्र, java.net.URL, java.net.URI, java.util.Locale, java.util.Date, java.math.bigDecimal, और java.math.BigInteger के लिए डिफ़ॉल्ट क्रमिकरण और deserialization प्रदान करता है। कक्षाएं। यदि आप डिफ़ॉल्ट प्रतिनिधित्व को बदलना पसंद करेंगे, तो आप GsonBuilder.registerTypeAdapter (टाइप, ऑब्जेक्ट) के माध्यम से एक प्रकार एडाप्टर पंजीकृत करके ऐसा कर सकते हैं।
  • डिफ़ॉल्ट दिनांक प्रारूप java.text.DateFormat.DEFAULT जैसा ही है। यह प्रारूप serialization के दौरान तिथि के मिलीसेकंद भाग को अनदेखा करता है। आप इसे GsonBuilder.setDateFormat (int) या GsonBuilder.setDateFormat (स्ट्रिंग) का आह्वान करके बदल सकते हैं।
  • डिफ़ॉल्ट रूप से, जीसन com.google.gson.annotations को अनदेखा करता है। एनोटेशन का प्रयोग करें। आप GsonBuilder.excludeFieldsWithoutExposeAnnotation() के माध्यम से इस एनोटेशन के साथ चिह्नित केवल उन फ़ील्ड को क्रमबद्ध/deserialize करने के लिए जीसन सक्षम कर सकते हैं।
  • डिफ़ॉल्ट रूप से, जीसन com.google.gson.annotations को अनदेखा करता है।एनोटेशन के बाद से। आप GsonBuilder.setVersion (डबल) के माध्यम से इस एनोटेशन का उपयोग करने के लिए जीसन को सक्षम कर सकते हैं।
  • आउटपुट जेसन के लिए डिफ़ॉल्ट फ़ील्ड नामकरण नीति जावा में समान है। इसलिए, जावा क्लास फ़ील्ड संस्करण नम्बर जेसन में "वर्जन नम्बर @ quot; के रूप में आउटपुट होगा। जावा नियमों में इनकमिंग जेसन मैपिंग के लिए एक ही नियम लागू किए गए हैं। आप इस नीति को जीसनबिल्डर.सेटफिल्ल्डनामिंग पॉलिसी (फील्ड नामकरण नीति) के माध्यम से बदल सकते हैं।
  • द्वारा डिफ़ॉल्ट, Gson क्रमबद्धता और अक्रमांकन के लिए विचार से क्षणिक या स्थिर क्षेत्रों शामिल नहीं है। आप GsonBuilder.excludeFieldsWithModifiers के माध्यम से (int) इस व्यवहार को बदल सकते हैं।

ठीक है, अब मैं देख रहा हूँ कि समस्या क्या। है डिफ़ॉल्ट मानचित्र सीरिएलाइज़र, जैसा कि आपने अपेक्षा की थी, नेस्टेड मानचित्रों का समर्थन नहीं करता है। जैसा कि आपमें देख सकते हैं(विशेष रूप से यदि आप डीबगर के साथ कदम रखते हैं) परिवर्तनीय childGenericType कुछ रहस्यमय कारणों के लिए java.lang.Object प्रकार पर सेट है, इसलिए मूल्य के रनटाइम प्रकार का कभी विश्लेषण नहीं किया जाता है।

दो समाधान, मुझे लगता है:

  1. Implement your own Map serializer/deserializer
  2. इस तरह से अपनी विधि का एक और अधिक जटिल संस्करण, कुछ का उपयोग करें:

    public String toJSON(){ 
        final Gson gson = new Gson(); 
        final JsonElement jsonTree = gson.toJsonTree(General, Map.class); 
        final JsonObject jsonObject = new JsonObject(); 
        jsonObject.add("General", jsonTree); 
        return jsonObject.toString(); 
    } 
    
+0

क्षमा करें, निशांत के उत्तर पर मेरी पहली टिप्पणी गलत थी। उनका सुझाव मेरे लिए पूरी तरह से काम नहीं करता है। – asmaier

+0

@asmaier ठीक है, मेरे जवाब –

+0

पर कुछ और सामग्री जोड़ा गया है, अगर आप ImmutableMap के साथ LinkedHashMap को प्रतिस्थापित करते हैं तो यह ठीक काम करता है। – Nishant

4

इस प्रयास करें:

Gson gson = new Gson(); 
System.out.println(gson.toJson(General)); 

सुनिश्चित नहीं हैं कि अगर आप अभी भी एक समाधान के लिए देख रहे हैं, यह मेरे लिए काम करता है:

import java.util.LinkedHashMap; 

import com.google.common.collect.ImmutableMap; 
import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

public class Example { 
// private static LinkedHashMap<String,Object> General; 
    private ImmutableMap General; 

    private static final String VERSION="Version"; 
    private static final String RANGE="Range"; 
    private static final String START_TIME="Start_Time"; 
    private static final String END_TIME="End_Time"; 

    public Example() { 

     LinkedHashMap<String,String> Range = new LinkedHashMap<String, String>(); 
     Range.put(START_TIME, "now"); 
     Range.put(END_TIME, "never"); 

//  General.put(RANGE, Range); 
     General = ImmutableMap.of(VERSION, "0.1", RANGE, Range); 
    } 

    public String toJSON() { 
//  Gson gson = new GsonBuilder().serializeNulls().create(); 
      Gson gson = new Gson(); 
      return gson.toJson(this); 
    } 

} 

रिटर्न: { "जनरल": { " संस्करण ":" 0.1 "," रेंज ": {" स्टार्ट_Time ":" अब "," एंडटाइम ":" कभी नहीं "}}}


जाहिर है आप इस्तेमाल कर सकते हैं ImmutableMap.copyOf(your_hashmap)here बजाय

+1

यह काम करता है, लेकिन क्यों? यह भी थोड़ा असुविधाजनक है। अगर मैं अपने वर्ग उदाहरण में और नक्शे जोड़ना चाहता हूं, तो मुझे अपने फ़ंक्शन में जेएसओएन() कुछ लिखना होगा जैसे 'स्ट्रिंग आउट = gson.toJson (this.General); बाहर + = gson.toJson (this.Map2); बाहर + = gson.toJson (this.map3); ... वापस लौटें; ' – asmaier

+0

दोस्त को यकीन नहीं है। मुझे यह मुद्दा था, मैं इस मार्ग से नीचे चला गया। मुझे यह माना जाता है कि यह http://sites.google.com/site/gson/gson-user-guide#TOC-Nested-Classes-cluding-Inner-Clas – Nishant

+0

क्षमा करें, मेरी पहली टिप्पणी गलत थी और मैं संपादित नहीं कर सकता अब और 'Gson.toJson (सामान्य) 'रिटर्न' {" संस्करण ":" 0.1 "," रेंज ": {" स्टार्ट_Time ":" ब्लै "," एंडटाइम ":" ब्लू "}," चेकसम ":" + 1 "का उपयोग करना } '। लेकिन मैं '{" सामान्य "होना चाहता हूं: {" संस्करण ":" 0.1 ", ....'। तो आपका समाधान मेरे लिए पूरी तरह से काम नहीं करता है। – asmaier

1

एक आसान विकल्प होगा जीएसओएन के बजाए जैक्सन का प्रयोग करें, बॉक्स के बाहर एक नेस्टेड मानचित्र का क्रमबद्धीकरण कार्य करता है:

LinkedHashMap<String, Object> general; 
    general = new LinkedHashMap<String, Object>(); 
    general.put("Version", "0.1"); 

    LinkedHashMap<String, String> Range = new LinkedHashMap<String, String>(); 
    Range.put("Start_Time", "now"); 
    Range.put("End_Time", "never"); 

    general.put("Range", Range); 

    // Serialize the map to json using Jackson 
    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    new org.codehaus.jackson.map.ObjectMapper().writer().writeValue(os, 
      general);  
    String json = os.toString(); 
    os.close(); 

    System.out.println(json); 

आउटपुट:

{ "संस्करण": "0.1", "सीमा": { "START_TIME": "अब", "end_time": "कभी नहीं"}}

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