JAXB 2 के ऑब्जेक्टफैक्ट कक्षाओं के बारे में क्या कहना है?


98

मैं JAXB का उपयोग करने के लिए नया हूं, और मैंने अपने XML स्कीमा से कक्षाओं का एक सेट उत्पन्न करने के लिए JAXB 2.1.3 के xjc का उपयोग किया है। मेरे स्कीमा में प्रत्येक तत्व के लिए एक वर्ग उत्पन्न करने के अलावा, इसने एक ObjectFactory वर्ग बनाया।

वहाँ कुछ भी नहीं लगता है कि मुझे सीधे तत्वों को तुरंत रोकना है, जैसे

MyElement element = new MyElement();

जबकि ट्यूटोरियल पसंद करने लगते हैं

MyElement element = new ObjectFactory().createMyElement();

अगर मैं ObjectFactory.java में देखता हूं, तो मैं देखता हूं:

public MyElement createMyElement() {
    return new MyElement();
}

तो सौदा क्या है? मुझे ऑब्जेक्टफैक्ट क्लास को इधर-उधर रखने पर भी क्यों परेशान होना चाहिए? मुझे लगता है कि अगर मैं एक परिवर्तित स्कीमा से फिर से संकलित करने के लिए लिखा गया था तो यह भी अधिलेखित हो जाएगा।


मुझे यकीन नहीं है कि अगर यह इच्छित डिज़ाइन है, लेकिन मैंने ऑब्जेक्टफैक्टिंग को JAXBContext निर्माण के लिए उपयोग करने के लिए एक आदर्श वर्ग पाया है। आपको वहां कुछ वर्गों की गणना करने की आवश्यकता है और JAXB उनके तरीकों, आदि का पालन करेगा, इसलिए वे कुछ जड़ों की तरह हैं। और ObjectFactory में सभी तत्वों के संदर्भ होते हैं, इसलिए सभी संबंधित वर्गों के साथ JAXBContext बनाने के लिए बस ObjectFactory.class का उपयोग करना पर्याप्त है।
वबजनर

जवाबों:


68

पिछड़ी संगतता एकमात्र कारण नहीं है। :-P

अधिक जटिल स्कीमा के साथ, जैसे कि उन तत्वों पर जटिल बाधाएं होती हैं जो किसी तत्व की सामग्री ले सकती हैं, कभी-कभी आपको वास्तविक JAXBElementऑब्जेक्ट बनाने की आवश्यकता होती है । वे आमतौर पर हाथ से बनाने के लिए तुच्छ नहीं हैं, इसलिए create*विधियां आपके लिए कड़ी मेहनत करती हैं। उदाहरण (XHTML 1.1 स्कीमा से):

@XmlElementDecl(namespace = "http://www.w3.org/1999/xhtml", name = "style", scope = XhtmlHeadType.class)
public JAXBElement<XhtmlStyleType> createXhtmlHeadTypeStyle(XhtmlStyleType value) {
    return new JAXBElement<XhtmlStyleType>(_XhtmlHeadTypeStyle_QNAME, XhtmlStyleType.class, XhtmlHeadType.class, value);
}

यह है कि आप एक <style>टैग में टैग कैसे प्राप्त करते हैं <head>:

ObjectFactory factory = new ObjectFactory();
XhtmlHtmlType html = factory.createXhtmlHtmlType();
XhtmlHeadType head = factory.createXhtmlHeadType();
html.setHead(head);
XhtmlStyleType style = factory.createXhtmlStyleType();
head.getContent().add(factory.createXhtmlHeadTypeStyle(style));

पहले तीन उपयोगों को बहुत अधिक ObjectFactoryमाना जा सकता है (हालांकि स्थिरता के लिए उपयोगी), लेकिन चौथा JAXB को बहुत आसान बनाता है, उपयोग करने के लिए बहुत आसान है। new JAXBElementहर बार हाथ से लिखकर निकालने में मदद करना!


क्या आप कुछ उपयोगी करने के लिए * () बनाने के लिए स्कीमा तत्व क्या (या कैसे जटिल) का एक उदाहरण / संदर्भ दे सकते हैं? मुझे आपके JAXB उदाहरण के साथ आपके द्वारा संदर्भित स्कीमा के भाग को खोजने में समस्या हो रही है। यदि मेरी स्कीमा बाद में और अधिक जटिल हो जाती है, तो यह निश्चित रूप से मेरे लिए इसका हिस्सा संभालने के लिए * बनाने के लिए अच्छा होगा, लेकिन जैसा कि यह है * अपने दम पर उप-तत्वों को बनाने से भी परेशान नहीं करता है ..
एंड्रयू कोलेसन

यदि आप XHTML 1.1 और XHTML मॉड्यूलर 1.1 तारकोल डाउनलोड करते हैं, तो आपको "SCHEMA" नामक निर्देशिका मिलेगी। सभी .xsd फ़ाइलों को एक ही निर्देशिका में रखें। .Xsd फ़ाइलों में से कुछ w3.org/2001/xml.xsd भी आयात करेंगे ; यदि आप चाहते हैं कि आप हर बार xjc चलाने के बाद फ़ाइल को डाउनलोड न करें, तो आप स्थानों को उचित रूप से समायोजित करना चाहेंगे। [cont]
क्रिस जस्टर-यंग

[cont] .xsd का विशिष्ट भाग जो <head> की सामग्री को निर्दिष्ट करता है, इस मामले में, xhtml11-model-1.xsd में, xhtml.head.content समूह के अंतर्गत है।
क्रिस जस्टर-यंग

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

धन्यवाद! मुझे लगता है कि मेरा स्कीमा पर्याप्त रूप से जटिल नहीं है, लेकिन मैं इसे भविष्य के लिए ध्यान में रखूंगा। :) मुझे पता था कि मुझे कुछ याद करना होगा।
एंड्रयू कोलेसन

39

जैसा कि @ क्रिस ने बताया, कभी-कभी JAXB POJOs के साथ काम नहीं कर सकता है, क्योंकि स्कीमा को बिल्कुल जावा पर मैप नहीं किया जा सकता है। इन मामलों में, JAXBElementआवरण की वस्तुओं को अतिरिक्त प्रकार की जानकारी प्रदान करना आवश्यक है।

दो ठोस उदाहरण हैं जो मुझे मिले हैं जहां यह आम है।

  • यदि आप उस वर्ग की एक वस्तु को अलग करना चाहते हैं जिसमें @XmlRootElementएनोटेशन नहीं है । डिफ़ॉल्ट रूप से XJC केवल @XmlRootElementकुछ तत्वों के लिए उत्पन्न होता है , और दूसरों के लिए नहीं। इसके लिए सटीक तर्क थोड़ा जटिल है, लेकिन आप "सरल बाध्यकारी मोड"@XmlRootElement का उपयोग करके अधिक कक्षाएं उत्पन्न करने के लिए XJC को बाध्य कर सकते हैं।

  • जब आपका स्कीमा सबस्टेशन समूहों का उपयोग करता है। यह बहुत उन्नत स्कीमा उपयोग है, लेकिन XJC JAXBElementरैपरों का भारी उपयोग करके जावा में प्रतिस्थापन समूहों का अनुवाद करता है ।

तो एक एक्सजेसी-जनित ऑब्जेक्ट मॉडल में जो JAXBElement(किसी भी कारण से) का भारी उपयोग करता है , आपको उन JAXBElementउदाहरणों के निर्माण का एक तरीका चाहिए । उत्पन्न ObjectFactoryइसे करने का सबसे आसान तरीका है। आप उन्हें स्वयं बना सकते हैं , लेकिन ऐसा करने के लिए यह स्पष्ट और त्रुटि-प्रवण है।


अतिरिक्त उदाहरणों के लिए धन्यवाद!
एंड्रयू कोलेसन

2
वाह, यह एक विजयी जवाब है। +1
क्रिस जस्टर-यंग

मैं XmlRootElement को 95% समय के रूप में उत्पन्न करने के लिए एनाक्स का उपयोग करना पसंद करता हूं यदि मेरे पास एक एलीमेण्ट है जो एक कॉम्प्लेक्स टाइप को संदर्भित करता है, तो मैं चाहता हूं कि XmlRootElement (अच्छी तरह से, 100% से अधिक जैसा कि मैंने उपयोग के मामले को हिट नहीं किया है जहां मैं नहीं चाहता हूं अभी तक)
डीन हिलर

9

पीछे संगतता, मुझे लगता है ...

http://weblogs.java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html :

... कोई और अधिक ObjectFactory.createXYZ। उन कारखाने के तरीकों के साथ समस्या यह थी कि वे एक जाँच JAXBException फेंक देते हैं। अब आप बस नए XYZ () कर सकते हैं, कोई और अधिक प्रयास / कैच न करें। (मुझे पता है, मुझे पता है, ... यह उन में से एक है "हम क्या सोच रहे थे !?" चीजें) ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.