So given I have class Name:
class Name {
private String first;
private String middle;
private String last;
public getFirst() { return first; }
public getMiddle() { return middle; }
public getLast() { return last; }
}
I would like to serialize instances of this class using the mapping XML without having to list each property in the mapping XML:
<java-types>
<java-type name="Name">
<java-attributes>
<xml-element java-attribute="first"/>
<xml-element java-attribute="middle"/>
<xml-element java-attribute="last"/>
</java-attributes>
</java-type>
</java-types>
So ideally I would like to have mapping file like this:
<java-types>
<java-type name="Name" xml-accessor-type="GETTERS"/>
</java-types>
I have some legacy DTO classes like this intended for for serialization only (no setters intentionally) with 30 or more properties and ideally I would want to avoid listing each single property in the mapping file.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
For this use case I would recommend using the field access type. When this is specified the JAXB implementation will use the fields (instance variables) to access the data instead of going through the property (get method). Below I'll demonstrate how to do this using MOXy's external mapping document extension:
bindings.xml
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum10141543">
<java-types>
<java-type name="Name" xml-accessor-type="FIELD">
<xml-root-element/>
</java-type>
</java-types>
</xml-bindings>
Name
package forum10141543;
class Name {
private String first;
private String middle;
private String last;
public Name() {
}
public Name(String first, String middle, String last) {
this.first = first;
this.middle = middle;
this.last = last;
}
public String getFirst() { return first; }
public String getMiddle() { return middle; }
public String getLast() { return last; }
}
jaxb.properties
To specify MOXy as your JAXB provider you need to add a file called jaxb.properties
in the same package as your domain classes with the following entry.
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
The following code demonstrates how to pass in the bindings file when bootstrapping the JAXBContext
:
package forum10141543;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum10141543/bindings.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Name.class}, properties);
Name name = new Name("Jane", "Anne", "Doe");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(name, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
<name>
<first>Jane</first>
<middle>Anne</middle>
<last>Doe</last>
</name>
For More Information
- http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
- http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html