Java Model
The following domain model will be used for this example. The only annotation I have used is @XmlRootElement. Below I will describe how the copy operation can be performed with or without this annotation.
package blog.copy; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Customer { private String name; private Address address; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
and
package blog.copy; public class Address { private String street; private String city; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
Demo Code - With @XmlRootElement
When the root object is annotated with @XmlRootElement the copy operation involves the following steps:
- Wrap the object to be copied in a JAXBSource
- Unmarshal the JAXBSource
package blog.copy; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.util.JAXBSource; public class Demo { public static void main(String[] args) throws Exception { // Build an instance of Customer with an Address Customer originalCustomer = new Customer(); originalCustomer.setName("Jane Doe"); Address originalAddress = new Address(); originalAddress.setStreet("123 A Street"); originalAddress.setCity("Any Town"); originalCustomer.setAddress(originalAddress); // Create the JAXBContext JAXBContext jc = JAXBContext.newInstance(Customer.class); // Wrap the Customer object in a JAXBSource JAXBSource source = new JAXBSource(jc, originalCustomer); // Treat the JAXBSource as an XML input and unmarshal it Unmarshaller unmarshaller = jc.createUnmarshaller(); Customer copiedCustomer = (Customer) unmarshaller.unmarshal(source); // Marshal the copy of Customer to demonstrate that it is populated Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(copiedCustomer, System.out); } }
Demo Code - Without @XmlRootElement
When the root object is not annotated with @XmlRootElement the copy operation is slightly longer:
- Wrap the object to be marshalled in a JAXBElement
- Wrap the JAXBElement in a JAXBSource
- Unmarshal the JAXBSource passing the target class as a parameter
package blog.copy; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.util.JAXBSource; import javax.xml.namespace.QName; public class JAXBElementDemo { public static void main(String[] args) throws Exception { // Build an instance of Customer with an Address Customer originalCustomer = new Customer(); originalCustomer.setName("Jane Doe"); Address originalAddress = new Address(); originalAddress.setStreet("123 A Street"); originalAddress.setCity("Any Town"); originalCustomer.setAddress(originalAddress); // Create the JAXBContext JAXBContext jc = JAXBContext.newInstance(Customer.class); // Wrap the Customer object in a JAXBElement and a JAXBSource JAXBElement<Customer> originalJAXBElement = new JAXBElement<Customer>(new QName("root"),Customer.class, originalCustomer); JAXBSource source = new JAXBSource(jc, originalJAXBElement); // Treat the JAXBSource as an XML input and unmarshal it Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement<Customer> copiedJAXBElement = unmarshaller.unmarshal(source, Customer.class); Customer copiedCustomer = copiedJAXBElement.getValue(); // Marshal the copy of Customer to demonstrate that it is populated Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(copiedJAXBElement, System.out); } }Further Reading
If you found this post useful, then you may also be interested in:
Can this method also be used to copy a non-root element, address in your example? How would the procedure differ? Thanks.
ReplyDeleteTo apply this method to a non-root case you would need to wrap the object to be copied in a JAXBElement to provide root element information (for this purpose it would not matter what root element you used). Then on the unmarshal you would need to use an unmarshal method that takes a class parameter:
Delete- http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshal(javax.xml.transform.Source,%20java.lang.Class)
-Blaise
Thanks! This was helpful.
ReplyDelete