2012-12-18 11 views
10
public abstract class Parent<T> { 
    protected List<T> list; 

    @XmlTransient //Question why do we have to give this here? 
    public abstract List<T> getList(); 
    public abstract void setList(List<T> list); 
} 

@XmlRootElement(name = "child1") 
class Child1 extends Parent<ExtendedElement1>{ 
    @Override 
    public void setList(List<ExtendedElement1> list){ 
     this.list = list; 
    } 

    @Override 
    @XmlElementWrapper(name = "child1-list") 
    @XmlElement(name = "child-list-element") 
    public List<ExtendedElement1> getList(){ 
     return this.list; 
    } 
} 

@XmlRootElement(name = "child2") 
class Child2 extends Parent<ExtendedElement2>{ 
    @Override 
    public void setList(List<ExtendedElement2> list){ 
     this.list = list; 
    } 

    @Override 
    @XmlElementWrapper(name = "child1-list") 
    @XmlElement(name = "child-list-element") 
    public List<ExtendedElement2> getList(){ 
     return this.list; 
    } 
} 


class Element{ 
    @XmlElement(name = "integer", type = int.class) 
    private int i = 2; 
} 

class ExtendedElement1 extends Element{ 
    @XmlElement(name = "extended-element1-str", type = String.class) 
    private String str = "hello"; 
} 

class ExtendedElement2 extends Element{ 
    @XmlElement(name = "extended-element2-str", type = String.class) 
    private String str1 = "hello_there"; 
} 

मैं उदाहरण है जब मैं Parent वर्ग getList() विधि से@XmlTransient हटाने , निम्नलिखित एक्सएमएल मार्शल में पता चला है के रूप में:विरासत और जेएक्सबी एक साथ कैसे काम करते हैं?

<child1> 
<!-- List is serialized 2 times --> 
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1"> 
     <integer>2</integer> 
     <extended-element1-str>hello</extended-element1-str> 
    </list> 
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1"> 
     <integer>2</integer> 
     <extended-element1-str>hello</extended-element1-str> 
    </list> 
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1"> 
     <integer>2</integer> 
     <extended-element1-str>hello</extended-element1-str> 
    </list> 
    <child1-list> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
    </child1-list> 
</child1> 

लेकिन जब मैं@XmlTransient टिप्पणी जोड़ने, के रूप में उदाहरण के लिए xml को केवल एक सूची के साथ क्रमबद्ध किया गया है।

<child1> 
    <child1-list> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
     <child-list-element> 
      <integer>2</integer> 
      <extended-element1-str>hello</extended-element1-str> 
     </child-list-element> 
    </child1-list> 
</child1> 

इसलिए कृपया कोई मुझे समझा सकता है क्यों यह जनक कक्षा गेटर विधि में @XmlTransient देने के लिए आवश्यक है? इन मामलों के लिए विरासत और जेएक्सबी कैसे संबंधित हैं?

उत्तर

6

क्यों अपनी हो रहा

एक JAXB (JSR-222) कार्यान्वयन हर डोमेन वस्तु मैप कर देंगे कि यह एक जटिल प्रकार के लिए के बारे में पता है। इसका मतलब है कि यह मानता है कि निम्नलिखित XML प्रकार Parent वर्ग के लिए मौजूद है (जब list@XmlTransient नहीं है)।

<xs:complexType name="parent" abstract="true"> 
    <xs:sequence> 
     <xs:element name="list" type="xs:anyType" nillable="true" minOccurs="0" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 

अब Child2 में एक जटिल प्रकार भी है। जेएक्सबी की दो चीजें हो सकती हैं:

  • गुणों को ओवरराइड करने की अनुमति नहीं है, जो बहुत सीमित होगा।
  • ओवरराइड संपत्ति के लिए अतिरिक्त मैपिंग जेनरेट करें। child2 के नीचे स्कीमा में parent का विस्तार होता है। इसका मतलब है कि यह parent प्रकार के सभी तत्वों के साथ-साथ अपने सभी तत्व प्राप्त करता है।
<xs:complexType name="child2"> 
    <xs:complexContent> 
     <xs:extension base="parent"> 
     <xs:sequence> 
      <xs:element name="child1-list" minOccurs="0"> 
      <xs:complexType> 
       <xs:sequence> 
       <xs:element name="child-list-element" type="extendedElement2" minOccurs="0" maxOccurs="unbounded"/> 
       </xs:sequence> 
      </xs:complexType> 
      </xs:element> 
     </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 

आईटी

आप Parent कक्षा में list संपत्ति पर @XmlTransient डाल सकता है ठीक करने का तरीका, लेकिन इसके बजाय मैं @XmlTransient साथ Parent वर्ग व्याख्या की सिफारिश करेंगे।

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

@XmlTransient 
public abstract class Parent<T> { 
    protected List<T> list; 

    public abstract List<T> getList(); 
    public abstract void setList(List<T> list); 

} 

यह एक मैप किया वर्ग और जटिल प्रकार Child2 से मेल खाती है हो जाएगा के रूप में यह निकल जाएगा:

<xs:complexType name="child2"> 
    <xs:sequence> 
     <xs:element name="child1-list" minOccurs="0"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element name="child-list-element" type="extendedElement2" minOccurs="0" maxOccurs="unbounded"/> 
      </xs:sequence> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
+0

लेकिन क्या होगा अगर आप एक सार्वजनिक एपीआई को डिजाइन कर रहे हैं? क्या एनोटेशन का डिफ़ॉल्ट सेट प्रदान करने का कोई तरीका है, और उन्हें अतिसंवेदनशील बनाते हैं? मुझे यह धारणा मिल रही है कि ऐसा करने का कोई तरीका नहीं है, क्या मैं सही हूँ? देखें: http://stackoverflow.com/questions/38348083/jaxb-override-xmlelement-type-of-list – bvdb

संबंधित मुद्दे