[java] जेएसीएबी वंशानुक्रम, मार्शल क्लास के उप-कक्षा में असंबद्ध


Answers

निम्नलिखित स्निपेट एक हद तक हल्की प्रकाश के साथ एक जूनि 4 परीक्षण की विधि है:

@Test
public void testUnmarshallFromParentToChild() throws JAXBException {
  Person person = new Person();
  int age = 30;
  String name = "Foo";
  person.name = name;
  person.age= age;

  // Marshalling
  JAXBContext context = JAXBContext.newInstance(person.getClass());
  Marshaller marshaller = context.createMarshaller();

  StringWriter writer = new StringWriter();
  marshaller.marshal(person, writer);

  String outString = writer.toString();

  assertTrue(outString.contains("</person"));

  // Unmarshalling
  context = JAXBContext.newInstance(Person.class, RecieverPerson.class);
  Unmarshaller unmarshaller = context.createUnmarshaller();
  StringReader reader = new StringReader(outString);
  RecieverPerson reciever = (RecieverPerson)unmarshaller.unmarshal(reader);

  assertEquals(name, reciever.name);
  assertEquals(age, reciever.age);
}

महत्वपूर्ण हिस्सा, JAXBContext.newInstance(Class... classesToBeBound) के उपयोग के लिए उपयोग नहीं है।

 context = JAXBContext.newInstance(Person.class, RecieverPerson.class);

इस कॉल के साथ, जेएसीएबी निर्दिष्ट वर्गों पर एक संदर्भ समापन की गणना करेगा और RecieverPerson को पहचान लेगा। परीक्षण पास और अगर आप मापदंडों के आदेश को बदलते हैं, तो आपको एक java.lang.ClassCastException मिलेगा (इसलिए उन्हें इस क्रम में पारित किया जाना चाहिए)।

Question

मैं XML पढ़ने और लिखने के लिए जेएसीएबी का उपयोग कर रहा हूं। मैं क्या चाहता हूं कि मार्शलिंग के लिए एक बेस जेएक्सबी वर्ग और बिना विरासत के लिए विरासत में मिली जेएक्सएबी वर्ग का उपयोग करना। यह एक प्रेषक जावा अनुप्रयोग को एक्सएमएल को दूसरे रिसीवर जावा अनुप्रयोग भेजने के लिए अनुमति देता है। प्रेषक और रिसीवर एक आम JAXB पुस्तकालय साझा करेंगे I मैं रिसीवर को एक्सएमएल को रिसीवर के विशिष्ट जेएक्सएबी वर्ग में जोड़ना चाहता हूं जो जेनेरिक जेएसीएबी क्लास का विस्तार करता है।

उदाहरण:

यह आम JAXB वर्ग है जो प्रेषक द्वारा उपयोग किया जाता है।

@XmlRootElement(name="person")
public class Person {
    public String name;
    public int age;
}

यह रिसीवर विशिष्ट जेएक्सबी क्लास का उपयोग किया जाता है जब एक्सएमएल को बेमेल होता है। रिसीवर वर्ग के रिसीवर आवेदन के लिए विशिष्ट तर्क है।

@XmlRootElement(name="person")
public class ReceiverPerson extends Person {
    public doReceiverSpecificStuff() ...
}

मार्शलिंग के रूप में अपेक्षित काम करता है इस समस्या के साथ unmarshalling है, यह अभी भी उपकारित ReceiverPerson के पैकेज नाम का उपयोग करते हुए JAXBContext के बावजूद Person को unmarshals

JAXBContext jaxbContext = JAXBContext.newInstance(package name of ReceiverPerson);

मैं क्या चाहता हूं कि ReceiverPerson पार्सन को अनारशेल करना है एकमात्र तरीका मैं ऐसा करने में सक्षम @XmlRootElement , Person से @XmlRootElement हटाने के लिए। दुर्भाग्य से ऐसा करने से Person को मार्शल होने से रोकता है। ऐसा लगता है कि JAXB आधार क्लास पर शुरू होता है और जब तक उचित नाम के साथ पहले @XmlRootElement न मिल पाता है तब तक इसका काम नीचे आता है। मैंने एक createPerson() विधि जोड़ने का प्रयास किया है जो ReceiverPerson createPerson() लिए देता है, लेकिन इससे मदद नहीं मिलती




Unmarshalling के दौरान वांछित वर्ग को इन्स्तांत करने के लिए एक कस्टम ObjectFactory बनाएँ। उदाहरण:

JAXBContext context = JAXBContext.newInstance("com.whatever.mypackage");
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setProperty("com.sun.xml.internal.bind.ObjectFactory", new ReceiverPersonObjectFactory());
return unmarshaller;

public class ReceiverPersonObjectFactory extends ObjectFactory {
    public Person createPerson() {
        return new ReceiverPerson();
    }
}



चूंकि आपके पास वास्तव में दो अलग-अलग एप्लिकेशन हैं, उन्हें "व्यक्ति" के अलग-अलग संस्करणों के साथ संकलित करें - व्यक्ति पर @XmlRootElement(name="person") न होने @XmlRootElement(name="person") रिसीवर ऐप न केवल यह बदसूरत है, लेकिन यह आपके द्वारा प्रेषक और रिसीवर दोनों के लिए व्यक्ति की एक ही परिभाषा का उपयोग करने से बनाए रखे रखरखाव को हरा देता है इसकी एक विशेषता यह है कि यह काम करता है




Links



Tags

java java   xml   jaxb