2013-01-08 39 views
10

मैं एक नमूना वर्ग मिल गया है:EclipseLink MOXY JSON क्रमबद्धता

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

जब धारावाहिक MOXY के साथ, मैं हो रही है:

{ 
    "bird": [ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    ], 
    "cat": [ 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    ], 
    "dog": [ 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
    ] 
} 

यह सरणी संकेतक क्यों उपयोग कर रहा है "[]" है, जबकि पक्षी , बिल्ली, और कुत्ते सरणी नहीं हैं? दूसरा, क्या "पक्षी", "बिल्ली" और "कुत्ता" से छुटकारा पाने का कोई तरीका है?

दूसरे शब्दों में, मैं करने के लिए कोशिश कर रहा हूँ:

{ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    , 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    , 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
} 

धन्यवाद, Behzad

उत्तर

9

प्रश्न # 1

क्यों यह सरणी संकेतक उपयोग कर रहा है "[] ", जबकि पक्षी, बिल्ली, और कुत्ते सरणी नहीं हैं?

इस JSON प्रतिनिधित्व आप @XmlElementRef एनोटेशन जो JAXB बताता विरासत संकेतक के रूप में @XmlRootElement एनोटेशन के मूल्य का उपयोग करने के लिए के साथ अपने मॉडल मैप की गई है प्राप्त करने के लिए। मोक्सी के जेएसओएन बाध्यकारी के साथ ये चाबियाँ बन गईं। हम इन चाबियों का मान JSON सरणी बनाते हैं क्योंकि कुंजी को दोहराने की अनुमति नहीं है।

चिड़ियाघर

अपने मॉडल में आप अपने animals क्षेत्र/संपत्ति पर @XmlElementRef एनोटेशन की है।

import java.util.Collection; 
import javax.xml.bind.annotation.XmlElementRef; 

class Zoo { 
    @XmlElementRef 
    public Collection<? extends Animal> animals; 
} 

पशु

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
public abstract class Animal { 

    private String name; 

} 

बर्ड

अपने उपवर्गों में से प्रत्येक पर आप एक @XmlRootElement एनोटेशन की है।

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/आउटपुट

{ 
    "bird" : [ { 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    } ], 
    "cat" : [ { 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    } ], 
    "dog" : [ { 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

अधिक जानकारी के लिए


प्रश्न # 2

दूसरा, वहाँ एक रास्ता "पक्षी", "बिल्ली", और "कुत्ता" से छुटकारा पाने के लिए है?

आपको विभिन्न उप-वर्गों का प्रतिनिधित्व करने के लिए किसी प्रकार की विरासत सूचक की आवश्यकता होगी।

विकल्प # 1 - @XmlDescriminatorNode/@XmlDescriminatorValue

यहाँ मैं ऐसा करते हैं MOXY का उपयोग @XmlDescriminatorNode/@XmlDescriminatorValue एनोटेशन।

चिड़ियाघर

import java.util.Collection; 

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

पशु

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlDiscriminatorNode("@type") 
public abstract class Animal { 

    private String name; 

} 

बर्ड

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; 

@XmlDiscriminatorValue("bird") 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/आउटपुट

{ 
    "animals" : [ { 
     "type" : "bird", 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    }, { 
     "type" : "cat", 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    }, { 
     "type" : "dog", 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

अधिक जानकारी

विकल्प # 2 के लिए - @XmlClassExtractor

क्लास एक्स्ट्रेक्टर (AnimalExtractor)

आप कुछ कोड लिख सकते हैं जो JSON सामग्री के आधार पर उचित उपclass निर्धारित करेगा।

import org.eclipse.persistence.descriptors.ClassExtractor; 
import org.eclipse.persistence.sessions.*; 

public class AnimalExtractor extends ClassExtractor { 

    @Override 
    public Class extractClassFromRow(Record record, Session session) { 
     if(null != record.get("@wingSpan") || null != record.get("@preferredFood")) { 
      return Bird.class; 
     } else if(null != record.get("@favoriteToy")) { 
      return Cat.class; 
     } else { 
      return Dog.class; 
     } 
    } 

} 

पशु

@XmlClassExtractor एनोटेशन ClassExtractor निर्दिष्ट करने के लिए प्रयोग किया जाता है।

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlClassExtractor; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlClassExtractor(AnimalExtractor.class) 
public abstract class Animal { 

    private String name; 

} 

बर्ड

कैसे MOXY @XmlElement और @XmlAttribute एनोटेशन प्रक्रियाओं के कारण, इच्छित डेटा के किसी भी ClassExtractor को उपलब्ध कराया जाना @XmlAttribute साथ एनोटेट करने की आवश्यकता होगी।

import javax.xml.bind.annotation.XmlAttribute; 

public class Bird extends Animal { 

    @XmlAttribute 
    private String wingSpan; 

    @XmlAttribute 
    private String preferredFood; 

} 

इनपुट।json/आउटपुट

{ 
    "animals" : [ { 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1", 
     "name" : "bird-1" 
    }, { 
     "favoriteToy" : "toy-1", 
     "name" : "cat-1" 
    }, { 
     "breed" : "bread-1", 
     "leashColor" : "black", 
     "name" : "dog-1" 
    } ] 
} 

अधिक जानकारी के लिए


डेमो कोड

निम्नलिखित डेमो कोड का उपयोग ऊपर वर्णित दोनों मैपिंग के साथ किया जा सकता है।

import java.util.*; 
import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 
import org.eclipse.persistence.jaxb.JAXBContextProperties; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     Map<String, Object> properties = new HashMap<String, Object>(); 
     properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); 
     properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 
     JAXBContext jc = JAXBContext.newInstance(new Class[] {Zoo.class}, properties); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     StreamSource json = new StreamSource("src/forum14210676/input.json"); 
     Zoo zoo = unmarshaller.unmarshal(json, Zoo.class).getValue(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(zoo, System.out); 
    } 

} 
+1

आपकी प्रतिक्रिया के लिए यू बहुत बहुत धन्यवाद। –

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद। मुझे डी-सीरियलाइजेशन के दौरान अपवाद मिल रहा है। मैं पोस्ट को अपडेट करने में सक्षम नहीं था। मैंने इस जानकारी को एक उत्तर के रूप में जोड़ा है। आपकी सहायताके लिए धन्यवाद! –

+0

@ बेहज़ादपिवाली - क्या आप इस मुद्दे को पोस्ट कर सकते हैं जिसे आप एक नए प्रश्न के रूप में देख रहे हैं? –