This post explains some of the frequently used JAXB2 annotations. For the complete list of JAXB2 annotations, please visit API Page.
Let’s quickly have a look of the mapped class, and the XML it will generate, then we will go through annotations, one at a time.
Mapped Class
package com.websystique.xml.model; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlList; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.joda.time.LocalDate; @XmlRootElement(name = "Student") @XmlType(propOrder = { "firstName", "lastName", "dob", "subjects", "groups" }) @XmlAccessorType(XmlAccessType.FIELD) public class Student { @XmlAttribute(name = "id") private int id; private String firstName; @XmlElement(name="last-name") private String lastName; @XmlElement(name = "birthDate") @XmlJavaTypeAdapter(LocalDateAdapter.class) private LocalDate dob; @XmlTransient private String section; @XmlElementWrapper(name="all-subjects") @XmlElement(name="subject") private List<String> subjects; @XmlList private List<String> groups; public int getId() { return id; } public List<String> getSubjects() { return subjects; } public void setSubjects(List<String> subjects) { this.subjects = subjects; } public List<String> getGroups() { return groups; } public void setGroups(List<String> groups) { this.groups = groups; } public void setId(int id) { this.id = id; } 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 String getSection() { return section; } public void setSection(String section) { this.section = section; } public LocalDate getDob() { return dob; } public void setDob(LocalDate dob) { this.dob = dob; } @Override public String toString() { return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob + ", section=" + section + "]"; } }
Adapter class used in Mapped Class
package com.websystique.xml.model; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.LocalDate; public class LocalDateAdapter extends XmlAdapter<String, LocalDate> { public LocalDate unmarshal(String v) throws Exception { return new LocalDate(v); } public String marshal(LocalDate v) throws Exception { return v.toString(); } }
Generated XML output
<!----------Generating the XML Output--------------> <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Student id="1"> <firstName>Alan</firstName> <last-name>Turing</last-name> <birthDate>1956-10-01</birthDate> <all-subjects> <subject>Maths</subject> <subject>Science</subject> <subject>Economics</subject> </all-subjects> <groups>Techies Volunteers</groups> </Student>
Now let’s go through annotations, one at a time:
@XmlRootElement
@XmlRootElement can be used to specify the root element of XML document generated by that particular class. By default class name is used as the root element, but you can specify a different name to be used via name
attribute.
<student..> ... </student>
@XmlType
@XmlType specify the order in which XML element will appear in generated XML. You can specify the prder using propOrder
property.
In our case, the XML elements in generated XML appear in the same order as we specified in ‘propOrder’.
@XmlAccessorType
JAXB annotations can be used either on method level or on field level. You can specify the exact strategy to be used via @XmlAccessorType on class level, providing the actual strategy with XmlAccessType.
@XmlAttribute
@XmlAttribute maps a java-bean property to an XML attribute. In our example, we have specified id property to be an attribute.
<student id="1"> ... </student>
@XmlElement
@XmlElement maps a java-bean property to an XML Element. By default , once @XmlRootElement
is declared on class level, all properties(or fields) will be treated as XML element with name as java-bean property name[unless they are decared otherwise, or are transient]
firstName java-bean property is mapped to firstName element in XML.
But you can specify a different name (using name attribute) if you prefer:
lastName java-bean property is mapped to last-name element in XML.
@XmlElementWrapper
@XmlElementWrapper can be used to create a wrapper around collection of elements.
In our case, we have created a wrapper all-subjects
around subject collection.
@XmlElementWrapper(name="all-subjects") @XmlElement(name="subject") private List<String> subjects;
maps to
<all-subjects> <subject>Maths</subject> <subject>Science</subject> <subject>Economics</subject> </all-subjects>
@XmlList
@XmlList can be used to represent a collection of elements as space separated text.
@XmlList private List<String> groups;
maps to
<groups>Techies Volunteers</groups>
@XmlTransient
@XmlTransient prevents a java-bean property to be mapped in XML. By default, since the @XmlRootElement
is present on class level, all the elements will be mapped to XML, but if a property is annotated with @XmlTransient, this will not be appear in generated XML.
In our case, property section is not present in generated XML.
@XmlJavaTypeAdapter
@XmlJavaTypeAdapter can be used to specify the adapter to be used for converting Java type to XML type and vice versa>.
@XmlElement(name = "birthDate") @XmlJavaTypeAdapter(LocalDateAdapter.class) private LocalDate dob;
maps to
<birthDate>1956-10-01</birthDate>
Below is the main class used to run this example.
package com.websystique.xml; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.joda.time.LocalDate; import com.websystique.xml.model.Student; public class JaxbAnnotationsDemo { public static void main(String[] args) throws JAXBException{ Student s = new Student(); s.setFirstName("Alan"); s.setLastName("Turing"); s.setSection("Computer Science"); s.setDob(new LocalDate(1956, 10, 1)); s.setId(1); List<String> subjects = new ArrayList<String>(); subjects.add("Maths"); subjects.add("Science"); subjects.add("Economics"); List<String> groups = new ArrayList<String>(); groups.add("Techies"); groups.add("Volunteers"); s.setGroups(groups); s.setSubjects(subjects); // create JAXB context JAXBContext context = JAXBContext.newInstance(Student.class); System.out.println("<!----------Generating the XML Output-------------->"); // Marshalling [Generate XML from JAVA] // create Marshaller using JAXB context Marshaller m = context.createMarshaller(); // To format the [to be]generated XML output m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Marshall it and write output to System.out or to a file m.marshal(s, System.out); } }
That’s it.
Download Source Code
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.