I need to marshall and unmarshall a Java class to XML. The class in not owned by me, that I cannot add anotations so that I can use JAXB.
Is there a good way to conv
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
DOMAIN MODEL
I will use the following domain model for this answer. Note how there are no JAXB annotations on the model.
Customer
package forum11693552;
import java.util.*;
public class Customer {
private String firstName;
private String lastName;
private List phoneNumbers = new ArrayList();
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(List phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
}
PhoneNumber
package forum11693552;
public class PhoneNumber {
private String type;
private String number;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
OPTION #1 - Any JAXB (JSR-222) Implementation
JAXB is configurartion by exception, this means you only need to add annotations where you want the mapping behaviour to differ from the default. Below is a link to an example demonstrating how to use any JAXB impl without annotations:
Demo
package forum11693552;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Customer customer = new Customer();
customer.setFirstName("Jane");
customer.setLastName("Doe");
PhoneNumber workPhone = new PhoneNumber();
workPhone.setType("work");
workPhone.setNumber("555-1111");
customer.getPhoneNumbers().add(workPhone);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement rootElement = new JAXBElement(new QName("customer"), Customer.class, customer);
marshaller.marshal(rootElement, System.out);
}
}
Output
Jane
Doe
555-1111
work
For More Information
OPTION #2 - EclipseLink JAXB (MOXy)'s External Mapping Document
If you do want to customize the mappings, then you may be interested in MOXy's external mapping document extension. A sample mapping document looks like the following:
oxm.xml
jaxb.properties
To enable MOXy as your JAXB provider you need to include a file called jaxb.properties
in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
When using EclipseLink MOXy as your JAXB provider (see), you can leverage the external mapping document when you bootstrap your JAXBContext
package forum11693552;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Map properties = new HashMap(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum11693552/oxm.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties);
Customer customer = new Customer();
customer.setFirstName("Jane");
customer.setLastName("Doe");
PhoneNumber workPhone = new PhoneNumber();
workPhone.setType("work");
workPhone.setNumber("555-1111");
customer.getPhoneNumbers().add(workPhone);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement rootElement = new JAXBElement(new QName("customer"), Customer.class, customer);
marshaller.marshal(rootElement, System.out);
}
}
Output
Jane
Doe
555-1111
For More Information