2012-12-18 16 views
9

मैं एक स्कीमा निम्न प्रकार परिभाषित करता है:JAXB साथ Serializing और किसी भी

<xsd:complexType name="Payload"> 
    <xsd:sequence> 
     <xsd:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax"/> 
    </xsd:sequence> 
</xsd:complexType> 

और वह इसलिए की तरह एक वस्तु बनाता है:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Payload", propOrder = { 
    "any" 
}) 
public class Payload { 

    @XmlAnyElement(lax = true) 
    protected List<Object> any; 
} 

अब मैं एक और जोड़ने का प्रयास करना JAXB वस्तु उत्पन्न कि पेलोड इस तरह कुछ कर रहा है:

Class payloadClass = ...; 
JAXBContext context = JAXBContext.newInstance(WrapperRequest.class, payloadClass); 
... 
marshaller.marshal(wrappedRequest); 

लेकिन मुझे एक भयानक अपवाद मिलता है जो ऐसा लगता है कि यह कभी भी खराब नहीं होगा k इसलिए मैं पहले एक्सएमएल में पेलोड ऑब्जेक्ट को क्रमबद्ध करने का निर्णय लेता हूं, फिर उसे पेलोड में एक स्ट्रिंग के रूप में जोड़ें।

StringWriter writer = new StringWriter(); 
JAXBContext context = JAXBContext.newInstance(sdoRequest.getClass()); 
Marshaller marshaller = context.createMarshaller(); 
marshaller.marshal(new JAXBElement(new QName("uri", sdoRequest.getClass().getSimpleName()), sdoRequest.getClass(), sdoRequest), writer); 
payload.getAny().add(writer.toString()); 

और यह एक अपवाद कह "java.lang.String" एक @XmlRootElement शामिल नहीं है के साथ चल रही है।

तो एक्सएस का उपयोग कैसे होगा: जेएक्सबी के साथ कभी भी काम करता है? कुछ भी काम नहीं करना चाहता क्योंकि जेएक्सबी ऑब्जेक्ट में पेलोड बदल देता है, और यह ऑब्जेक्ट में कुछ भी क्रमबद्ध नहीं करेगा। यह सब एक्सिस 2 के अंदर भी है, इसलिए इस बिंदु पर पहुंचना बहुत चुनौतीपूर्ण रहा है।

+1

जब आप लिपटे ऑब्जेक्ट को किसी भी पेलोड में जोड़ने का प्रयास करते हैं तो आपको क्या अपवाद मिलता है? – gregwhitaker

+1

निम्नलिखित में मदद करनी चाहिए: http://blog.bdoughan.com/2010/08/using-xmlanyelement-to-build-generic.html –

+0

यह आंशिक रूप से डब्लूएसडीएल को एक साथ रखा गया है जिस पर मेरा शून्य नियंत्रण है। लेकिन, रैपिंग अनुरोध एक डब्लूएसडीएल में परिभाषित किया गया है और पेलोड में जाने का अनुरोध किसी अन्य डब्लूएसडीएल में परिभाषित किया गया है। वे दोनों बेसआरक्वेट घोषित करते हैं, लेकिन जब कोड उत्पन्न होता है तो वे अलग-अलग वर्ग होते हैं। और मुझे यह अपवाद मिलता है दो वर्गों में एक ही एक्सएमएल प्रकार का नाम {http://esp.lala.com/2012/eo}BaseRequest है। उन्हें अलग-अलग नाम देने के लिए @ XmlType.name और @ XmlType.namespace का उपयोग करें। – chubbsondubs

उत्तर

14

नीचे मैं एक उदाहरण के साथ JAXB (JSR-222) और any प्रदर्शन करेंगे:

पेलोड

any संपत्ति @XmlAnyElement(lax=true) साथ टिप्पणी की जाती है। इसका अर्थ यह है कि उस संपत्ति के लिए यदि कोई तत्व @XmlRootElement या @XmlElementDecl के माध्यम से कक्षा से जुड़ा हुआ है तो संबंधित वस्तु का एक उदाहरण संपत्ति को पॉप्युलेट करने के लिए उपयोग किया जाएगा यदि तत्व org.w3c.dom.Element के उदाहरण के रूप में सेट नहीं किया जाएगा।

package forum13941747; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Payload", propOrder = { 
    "any" 
}) 
public class Payload { 

    @XmlAnyElement(lax = true) 
    protected List<Object> any; 

} 

फू

नीचे एक वर्ग @XmlRootElement साथ एनोटेट का एक उदाहरण है।

package forum13941747; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

} 

बार

नीचे @XmlRootElement एनोटेशन के बिना एक वर्ग का एक उदाहरण है। इस उपयोग के मामले में हम @XmlRegistry के साथ एनोटेटेड फैक्ट्री क्लास (आमतौर पर ObjectFactory कहा जाता है) पर @XmlElementDecl एनोटेशन का लाभ उठाएंगे।

package forum13941747; 

public class Bar { 

} 

ObjectFactory

नीचे Bar वर्ग के लिए एक @XmlElementDecl एनोटेशन निर्दिष्ट करने का एक उदाहरण है।

package forum13941747; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 
import javax.xml.namespace.QName; 

@XmlRegistry 
public class ObjectFactory { 

    @XmlElementDecl(name="bar") 
    public JAXBElement<Bar> createBar(Bar bar) { 
     return new JAXBElement<Bar>(new QName("bar"), Bar.class, bar); 
    } 

} 

input.xml

नीचे इनपुट दस्तावेज़ हम इस उदाहरण के लिए प्रयोग करेंगे। 0 तत्व हैं जो any संपत्ति से मेल खाते हैं।पहला Foo कक्षा पर @XmlRootElement एनोटेशन से मेल खाता है। दूसरा Bar वर्ग के लिए @XmlElementDecl एनोटेशन से मेल खाता है और तीसरा डोमेन वर्गों में से किसी के अनुरूप नहीं है।

<?xml version="1.0" encoding="UTF-8"?> 
<payload> 
    <foo/> 
    <bar/> 
    <other/> 
</payload> 

डेमो

डेमो कोड के नीचे हम जिसके परिणामस्वरूप any संपत्ति में इनपुट दस्तावेज़, तो उत्पादन वस्तुओं की कक्षाएं unmarshal जाएगा और फिर payload वस्तु वापस एक्सएमएल के लिए मार्शल में।

package forum13941747; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Payload.class, Foo.class, ObjectFactory.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum13941747/input.xml"); 
     Payload payload = (Payload) unmarshaller.unmarshal(xml); 

     for(Object o : payload.any) { 
      System.out.println(o.getClass()); 
     } 

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

} 

आउटपुट

नीचे डेमो कोड को चलने से उत्पादन होता है। any संपत्ति में वस्तुओं से संबंधित वर्गों पर ध्यान दें। foo तत्व Foo वर्ग का एक उदाहरण बन गया। bar तत्व JAXBElement का एक उदाहरण बन गया है जिसमें Bar का उदाहरण है। other तत्व org.w3c.dom.Element का उदाहरण बन गया। आप में DemoType.java। @XmlRootElement है करने की कोई जरूरत नीचे की तरह वस्तु mashelling के लिए वस्तु फैक्टरी के

class forum13941747.Foo 
class javax.xml.bind.JAXBElement 
class com.sun.org.apache.xerces.internal.dom.ElementNSImpl 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<payload> 
    <foo/> 
    <bar/> 
    <other/> 
</payload> 
1

उपयोग करें,

DemoType demoServiceRequest = new DemoType(); 
ObjectFactory obDemo = new ObjectFactory(); 
Request requestObject = new Request();  
requestObject.setAny(obDemo.createDemo(demoServiceRequest)); 

और (@XmlSeeAlso तरह Request.java पर DemoType वर्ग को जोड़ने {DemoType.class})