2012-01-04 8 views
7

मैंने Blaise Doughan's answer to a question on this subject का अध्ययन किया है लेकिन एक और सवाल है।मैं XmlJavaTypeAdapters के साथ क्या पैकेज-जानकारी एनोटेट करता हूं?

XmlJavaTypeAdapters आपको XmlJavaTypeAdapter एनोटेशन का एक समूह सूचीबद्ध करने देता है, जिनमें से प्रत्येक यह नियंत्रित करता है कि कैसे एक गैर-बाध्यकारी प्रकार JAXB द्वारा बाध्यकारी प्रकार के लिए मैप किया गया है।

आप पैकेज स्तर पर इस एनोटेशन का उपयोग कर सकते हैं। जब आप ऐसा करते हैं, तो प्रत्येक XmlJavaTypeAdapter एनोटेशन को type() विशेषता पूरी तरह से निर्दिष्ट करने की आवश्यकता होती है।

वहाँ एक आवश्यकता है कि पैकेज है कि एनोटेट की जा रही गैर bindable प्रकार के पैकेज अनुकूलित किया जा रहा के साथ कोई लेना देना नहीं दिखाई दे रहा है। यह सुविधाजनक और अच्छा है।

, यही कारण है कि हालांकि, मुझे मेरे अगले प्रश्न की ओर जाता है: अगर कोई टिप्पणी किए गए पैकेज और प्रकार के पैकेज के बीच कोई रिश्ता अनुकूलित किया जा रहा है, कैसे करता है JAXB पैकेज स्तरीय XmlJavaTypeAdapters एनोटेशन की खोज? दूसरे शब्दों में, क्या यह पता चलता है कि कौन से पैकेज संभावित XmlJavaTypeAdapters एनोटेशन के लिए परामर्श ले सकते हैं? मैं में, कहते हैं एक यादृच्छिक पैकेज, कि एक एकल, ginormous package-info वर्ग है कि मेरी गैर bindable प्रकार के सभी के लिए सभी एडेप्टर के साथ टिप्पणी की जाती है शामिल मेरी .ear फ़ाइल के lib निर्देशिका में .jar फ़ाइल कर सकते हैं?

उत्तर

7

जब जेएक्सबी रनटाइम एक जेएक्सबी-एनोटेटेड क्लास लोड करता है, तो वह उस वर्ग के समान पैकेज में package-info.java ढूंढता है, और यह जांचता है कि पैकेज-स्तरीय एनोटेशन देखने के लिए। इसलिए XmlJavaTypeAdapters को "गैर-बाध्यकारी" प्रकारों के समान पैकेज में रहने की आवश्यकता नहीं है, यह को "बाध्यकारी" प्रकारों के समान पैकेज में रहना होगा।

उदाहरण के लिए, मैं एक JAXB-एनोटेट वर्ग A, पैकेज X में है, जो पैकेज Y में टाइप B की संपत्ति है है का कहना है। B संपत्ति को बांधने के लिए, मान लीजिए कि एक प्रकार एडाप्टर आवश्यक है। उस एडाप्टर को A में ही निर्दिष्ट किया जा सकता है, या इसे पैकेज X में package-info.java में निर्दिष्ट किया जा सकता है। पैकेज Y बहुत मनमाना है, और जेएक्सबी रनटाइम के लिए कोई रूचि नहीं है।

मुझे उम्मीद है कि यह समझ में आता है।

+0

बहुत उपयोगी; धन्यवाद। क्या ग्राफ वहां से चला गया है? ऐसा लगता है कि मेरे पास एक एकल बाध्यकारी प्रकार है जिसे मैं जेएक्सबी को खिलाता हूं। मान लें कि उसके पैकेज को 647 'XmlJavaTypeAdapter' एनोटेशन के साथ एनोटेट किया गया है, जिनमें से प्रत्येक उस प्रकार के लिए एक गैर-बाध्यकारी प्रकार और एडाप्टर निर्दिष्ट करता है। क्या मेरा 'JAXBContext' अब सभी 647 अब-अनुकूलित प्रकारों को संभालने में सक्षम होगा? –

+0

@Laird: हाँ, जब तक (ए) आपके पास इसे संभालने के लिए रैम था, और (बी) सभी बाध्यकारी प्रकार उस पैकेज में थे। – skaffman

+0

दिलचस्प। ऐसा लगता है कि मुझे पूरी प्रक्रिया को बूटस्ट्रैप करना होगा, हालांकि। मेरा मतलब है, अगर मैं केवल एक ही प्रकार के जेएक्सबी को खिलाकर एडाप्टर का ढेर स्थापित कर सकता हूं, तो मुझे आशा है कि जेएक्सबी को बेहतर बनाना संभव होगा ताकि वह एकल प्रकार आवश्यक न हो। जैसे कि "रूट" 'पैकेज-जानकारी 'के लिए डिफ़ॉल्ट रूप से जेएक्सबी दिखता है ताकि शुरुआती बूटस्ट्रैपिंग आवश्यक न हो। आपकी सहायता के लिए एक बार फिर से धन्यवाद। –

5

वहाँ एक आवश्यकता है कि पैकेज है एनोटेट किया जा रहा गैर bindable प्रकार अनुकूलित किया जा रहा से पैकेज के साथ कोई लेना देना नहीं दिखाई दे रहा है। यह सुविधाजनक और अच्छा है।

यह सही है। जब पैकेज स्तर पर @XmlJavaTypeAdapter का उपयोग किया जाता है तो इसका अर्थ यह है कि इस पैकेज में रहने वाले वर्गों के लिए निर्दिष्ट प्रकार के सभी गुणों के लिए इस एडाप्टर को लागू करें। मैं एक उदाहरण के साथ नीचे प्रदर्शित करेंगे।

forum8735737.bar.package-जानकारी

इस पैकेज के लिए हम एक XmlAdapter कि इस पैकेज के भीतर प्रकार String के सभी क्षेत्रों/गुण को लागू किया जाएगा निर्दिष्ट करेगा।

@XmlJavaTypeAdapters({ 
    @XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class) 
}) 
package forum8735737.bar; 

import javax.xml.bind.annotation.adapters.*; 

forum8735737.bar।StringAdapter

हमारे XmlAdapter बस जब वास्ते अपर केस को String के सभी उदाहरणों में परिवर्तित कर देंगे:

package forum8735737.bar; 

import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class StringAdapter extends XmlAdapter<String, String> { 

    @Override 
    public String unmarshal(String v) throws Exception { 
     return v; 
    } 

    @Override 
    public String marshal(String v) throws Exception { 
     if(null == v) { 
      return v; 
     } 
     return v.toUpperCase(); 
    } 

} 

forum8735737.bar.Bar

Bar की संपत्ति के साथ इस पैकेज में एक POJO का प्रतिनिधित्व करता है टाइप करें String:

package forum8735737.bar; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bar { 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

forum8735737.foo.Foo

फू प्रकार String है कि एक अलग पैकेज में मौजूद है की संपत्ति के साथ एक डोमेन वस्तु का प्रतिनिधित्व करता है।

package forum8735737.foo; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

} 

डेमो

निम्नलिखित कोड दोनों Foo और Bar के उदाहरण बना सकते हैं और एक्सएमएल के लिए मार्शल होगा:

package forum8735737; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

import forum8735737.bar.Bar; 
import forum8735737.foo.Foo; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Foo.class, Bar.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     Foo foo = new Foo(); 
     foo.setName("Foo"); 
     marshaller.marshal(foo, System.out); 

     Bar bar = new Bar(); 
     bar.setName("Bar"); 
     marshaller.marshal(bar, System.out); 
    } 

} 
XmlAdapter हम forum8735737.bar पैकेज के लिए पंजीकृत इस वर्ग पर लागू नहीं होगा

आउटपुट

सूचना कैसे bar भीतर name तत्व का मान अपर केस में बदल दिया गया:

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
    <name>Foo</name> 
</foo> 
<?xml version="1.0" encoding="UTF-8"?> 
<bar> 
    <name>BAR</name> 
</bar> 
संबंधित मुद्दे