2012-11-20 20 views
9

मेरे पास एक JSON फ़ाइल है जिसमें एकाधिक प्रकार हो सकते हैं।एक स्ट्रीम/ऑब्जेक्ट दृष्टिकोण का उपयोग कर जैक्सन में जेएसओएन को पार्सिंग

उदाहरण के लिए:

{ 
    "dog": { 
     "owner" : "John Smith", 
     "name" : "Rex", 
     "toys" : { 
      "chewtoy" : "5", 
      "bone" : "1" 
     } 
    }, 
    "person": { 
     "name" : "John Doe", 
     "address" : "23 Somewhere Lane" 
    } 
    // Further examples of dogs and people, and a few other types. 
} 

मैं वस्तुओं में इन पार्स करने के लिए चाहता हूँ। अर्थात। मैं मालिक/नाम/खिलौने विशेषताओं, और नाम/पता विशेषताओं वाले व्यक्ति के साथ एक कुत्ता वस्तु बनाना चाहता हूं, और जैक्सन का उपयोग उन वस्तुओं से पढ़ने और बनाने के लिए करता हूं।

ऑर्डरिंग मायने रखता है - मुझे यह जानने की ज़रूरत है कि रेक्स जॉन डो के सामने आया था, उदाहरण के लिए। मैं दृष्टिकोण जैसे धारा के साथ करना पसंद करूंगा (यानी डॉग ऑब्जेक्ट में रेक्स को पढ़ना और पार्स करना, इसके साथ कुछ करना, फिर इसे छोड़ दें, फिर जॉन डो पर जाएं)। तो मुझे एक धारा आधारित दृष्टिकोण की जरूरत है।

मैं यह समझने के लिए स्ट्रीम स्ट्रीमिंग एपीआई (क्रम में जाने के लिए) और ऑब्जेक्टमैपर इंटरफ़ेस (जेएसओएन से जावा ऑब्जेक्ट्स बनाने के लिए) दोनों का उपयोग करने का तरीका नहीं समझ सकता।

+1

(1) स्ट्रीम या SAX- जैसे पार्सिंग के बारे में आपका प्रश्न पूरी तरह से मान्य है। +1। लेकिन (2) एक शब्दकोश में मामलों का ऑर्डर करने पर आपका डेटा अच्छी तरह से डिज़ाइन नहीं किया गया है। JSON शब्दकोश स्वाभाविक रूप से अनियंत्रित हैं। यदि आपको ऑर्डर की आवश्यकता है, तो एक सरणी का उपयोग करें और प्रकार (कुत्ते/व्यक्ति) जानकारी को एक विशेषता के रूप में भी एन्कोड करें। –

+0

हम्म। डेटा स्रोत संभवतः अपरिवर्तनीय है (मेरे नियंत्रण में नहीं)। जब आप कहते हैं कि एक सरणी का उपयोग करें और जानकारी को एन्कोड करें, तो क्या आपका मतलब यह मैन्युअल रूप से करें? (सभी टोकन के माध्यम से पढ़ें और उपयुक्त सेटर्स को बुलाए जाने योग्य उपयुक्त वस्तुएं बनाएं) या जैक्सन का उपयोग करके ऐसा करने का कोई तरीका है? –

+0

मेरा मतलब है कि जेएसओएन डेटा प्रत्येक ऑब्जेक्ट के साथ एन्कोड किए गए प्रकारों के साथ ऑर्डर के मामले में सरणी के रूप में आना चाहिए। लेकिन यदि आप JSON डेटा को नियंत्रित नहीं करते हैं, तो कभी भी नहीं - आपको सुझाव देते हुए स्ट्रीम पार्सिंग से निपटना होगा। :) मेरे पास आपके वास्तविक प्रश्न का उत्तर नहीं है, हालांकि यहां कोई और निश्चित रूप से होगा। लेकिन पता है कि जो भी इस JSON प्रारूप के साथ आया वह आग से खेल रहा है। एक शब्दकोश में चाबियों के क्रम पर भरोसा करना बहुत नाजुक है, गधे में दर्द के कुछ भी नहीं कहने के लिए यह लोगों (आप) के लिए बनाता है जो इससे निपटने की कोशिश कर रहे हैं - यह ज्यादातर उपकरणों के अनाज के खिलाफ जाता है। –

उत्तर

10

ऐसा करने के लिए, आप तो इनपुट के लिए एक पार्सर बनाने अपने कारखाने

import org.codehaus.jackson.JsonFactory; 
import org.codehaus.jackson.JsonParser; 
import org.codehaus.jackson.JsonProcessingException; 
import org.codehaus.jackson.map.ObjectMapper; 
... 
private static ObjectMapper mapper = new ObjectMapper(); 
private static JsonFactory factory = mapper.getJsonFactory(); 

के साथ एक वस्तु नक्शाकार उपयोग करने के लिए की जरूरत है।

JsonParser parser = factory.createJsonParser(in); 

अब आप parser.nextToken() के लिए कॉल मिश्रण और parser.readValueAs (कक्षा ग) करने के लिए कॉल कर सकते हैं। यहां एक उदाहरण दिया गया है जो मानचित्र से कक्षाएं प्राप्त करता है:

Map<String, Class<?>> classMap = new HashMap<String, Class<?>>(); 
classMap.put("dog", Dog.class); 
classMap.put("person", Person.class); 

InputStream in = null; 
JsonParser parser = null; 
List<Object> results = new ArrayList<Object>(); 
try { 
    in = this.getClass().getResourceAsStream("input.json"); 
    parser = factory.createJsonParser(in); 
    parser.nextToken();// JsonToken.START_OBJECT 
    JsonToken token = null; 
    while((token = parser.nextToken()) == JsonToken.FIELD_NAME) { 
    String name = parser.getText(); 
    parser.nextToken(); // JsonToken.START_OBJECT 
    results.add(parser.readValueAs(classMap.get(name))); 
    } 
    // ASSERT: token = JsonToken.END_OBJECT 
} 
finally { 
    IOUtils.closeQuietly(in); 
    try { 
    parser.close(); 
    } 
    catch(Exception e) {} 
} 
+0

मुझे लगता है कि अब मैं देखता हूं। जब मैं शुरुआत में ऐसा करने की कोशिश कर रहा था, तो मैं संघर्ष कर रहा था क्योंकि मुझे नहीं पता था कि मैं किस वस्तु पर था ("कुत्ता" या "व्यक्ति"), लेकिन यदि डेटा कुत्ते/व्यक्ति मूल्यों के साथ एक सरणी के रूप में स्वरूपित होता है एक "प्रकार" विशेषता में, मैं यह करने में सक्षम होगा। सबको धन्यवाद। –

+0

एक अच्छा जवाब। लेकिन, यदि आप नवीनतम जैक्सन लाइब्रेरी का उपयोग कर अपने कोड स्निपेट को फिर से लिख सकते हैं तो यह बहुत अच्छा होगा। –