JAXB Annotations Reference

Introduction

JAXB defines many annotations that shape how Java classes map to XML Schema. This article documents the JAXB annotations that you will use most often and provides practical examples how to use them.

This reference page is part of a series of articles on JAXB:

Index

These are the most common JAXB annotations:

AnnotationDescription
@XmlSchemaMaps a Java package to an XML namespace.
@XmlAccessorTypeDefines the fields and properties of your Java classes that the JAXB engine uses for binding. It has four values: PUBLIC_MEMBER, FIELD, PROPERTY and NONE.
@XmlAccessOrderDefines the sequential order of the children.
@XmlTypeMaps a Java class to a schema type. It defines the type name and order of its children.
@XmlRootElementDefines the XML root element. Root Java classes need to be registered with the JAXB context when it is created.
@XmlElementMaps a field or property to an XML element
@XmlAttributeMaps a field or property to an XML attribute
@XmlTransientPrevents mapping a field or property to the XML Schema
@XmlValueMaps a field or property to the text value on an XML tag.
@XmlListMaps a collection to a list of values separated by space.
@XmlElementWrapperMaps a Java collection to an XML wrapped collection
@XmlJavaTypeAdapterAdapts any Java class to an XML Schema type

@XmlSchema

The @XmlSchema tag maps Java packages to XML namespaces. It is defined at package level, so the best place to declare it is in the package-info.java.

The @XmlSchema most common configuration is to provide the namespace and elementFormDefault attributes:

This @XmlSchema declaration generates an XML Schema like the one below:

The namespace attribute in @XmlSchema maps to the targetNamespace attribute in xs:schema. The targetNamespace attribute has the namespace of the domain that the XML Schema defines.

The elementFormDefault attribute controls whether the elements must be namespace-qualified. Most XML Schema declarations set this to “qualified“. A qualified element means that all elements must belong to an XML Schema vocabulary. They must either have a namespace prefix or be part of the default namespace. There is also a counterpart attributeFormDefault, but is usually left as unqualified. For a good explanation of elementFormDefault and attributeFormDefault you can read Introduction to XML Schema.

Another usage of @XmlSchema is to declare multiple namespaces.

This declaration defines two namespaces, a default http://actimem.com/xsd/company.xsd and a prefixed http://actimem.com/xsd/employee.xsd. An example XML looks like this:

@XmlAccessorType

The @XmlAccessorType defines the fields and properties of your Java classes that the JAXB engine uses for binding. It has four values: PUBLIC_MEMBER, FIELD, PROPERTY and NONE.

PUBLIC_MEMBERIt binds public fields, annotated fields and properties (default)
FIELDIt binds fields and annotated properties
PROPERTYIt binds annotated fields and properties
NONEIt binds annotated fields and annotated properties

PUBLIC_MEMBER

PUBLIC_MEMBER is the default accessor type. JAXB generates bindings for:

  • Public fields
  • Annotated fields
  • Properties

The following example has Java class with a PUBLIC_MEMBER accessor type.

When marshalled generates the following XML:

FIELD

The FIELD accessor type creates bindings for:

  • Fields
  • Annotated properties

The following example has Java class with a FIELD accessor type.

When marshalled generates the following XML:

PROPERTY

The PROPERTY accessor type creates bindings for:

  • Annotated fields
  • Properties

Property is very similar to PUBLIC_MEMBER. The only difference is that it ignores public fields. The benefit of using PROPERTY over FIELD is that some frameworks such as JPA might inject additional fields.

The following example has a Java class with a PROPERTY accessor type.

When marshalled generates the following XML:

NONE

The NONE accessor type creates bindings for:

  • Annotated fields
  • Annotated properties

This accessor type is useful when you want to have absolute control. JAXB only binds fields and properties annotated with @XmlAttribute or @XmlElement.

@XmlAccessOrder

The @XmlAccessOrder defines the sequential order of the children. It can have two values:

  • ALPHABETICAL
  • UNDEFINED (default)

When UNDEFINED is used, most JAXB providers use the same order as fields and properties are defined in the Java class. This behaviour is however not guaranteed. The only portable way to keep the order consistent across JAXB providers is:

  • Set @XmlAccessOrder to ALPHABETICAL
  • Define the order in the propOrder attribute of the @XmlType annotation

@XmlType

The @XmlType annotation maps a Java class to a schema type. The @XmlType defines the type name, namespace and order of its children.

The @XmlType annotation has two attributes: name and propOrder. The name attribute defines the name of the type used in the XML Schema. The propOrder defines the sequential order of the children. If propOrder is not present, then the order is defined by the @XmlAccessOrder annotation.

This example illustrates the usage of @XmlType:

This is the XML Schema generated:

This is the XML generated:

@XmlRootElement

The @XmlRootElement defines an XML root element. Root Java classes need to be registered when the JAXB context when it is created.

The following example defines a root class:

You can also use the name attribute to change the root-node element name:

You can marshal and unmarshal this Java class as follows:

@XmlElement

The @XmlElement annotation maps a field or property to an XML element. By default, JAXB maps non-annotated Java field and properties to elements.

The @XmlElement annotation has four attributes of interest:

nameThe name of the element in the XML Schema
namespaceThe namespace of the element, if different to the parent node.
requiredControls the minOccurs XML Schema attribute (default false)

If required=”true” then minOccurs=”1″. If required=”false” then maxOccurs=”0″

nillableSupport for XML Schema nillable declarations (default false)

The following Java class illustrates the several usages of the @XmlElement annotation:

The schemagen tool will generate the following XML Schema:

The nillable attribute supports nillable XML elements. The code below marshals an ElementExample with all its non-required elements set to null.

The XML nillable element is represented with the XMLSchema-instance xsi:nil=”true”

@XmlAttribute

The @XmlAttribute maps a field or property to an XML attribute. It has three attributes of interest:

nameThe name of the element in the XML Schema
namespaceThe namespace of the element, if different to the parent node.
requiredControls the minOccurs XML Schema attribute (default false)

If required=”true” then minOccurs=”1″. If required=”false” then maxOccurs=”0″

The following Java class illustrate the usage of @XmlAttribute:

This class generates the following XML Schema:

The @XmlAttribute can also annotate Lists. The only constraint is that the values in the list must map to a simple XML Schema type (e.g. xs:string, xs:int, xs:date, etc.). The following Java class illustrates this:

The below code marshals the above Java class into XML:

It generates the following XML:

@XmlTransient

The @XmlTransient annotation prevents mapping a field or property to the XML Schema.

JAXB maps all private fields and properties to an XML element when @XmlAccessorType is set to PUBLIC_MEMBER, PROPERTY or FIELD.  The @XmlTransient ensures the annotated field or property is not marshalled to XML.

If you have many fields or properties that you do not want to map, then you might consider setting @XmlAccessorType to NONE. When NONE, only the fields annotated with @XmlAnnotation or @XmlElement are mapped.

@XmlValue

The @XmlValue annotation maps a field or property to the text value of an XML tag. A Java class containing a field or property is constrained as follows:

  • It cannot have any field or properties annotated with @XmlElement
  • The field or property annotated with @XmlValue must map to a simple type

This Java class shows how to use the @XmlValue annotation:

When marshalled, it generates an XML similar to the below:

@XmlList

The @XmlList annotation maps a collection to a list of values separated by space. The only limitation is that the items in the collection must map to simple XML Schema types. This is to say, @XmlList does not support complex types.

The Java class below shows an example how to use the @XmlList annotation (the @XmlElement is optional):

When adding three items to the names list, it generates the following XML:

This contrasts with a Java collection that only annotated with @XmlElement.  When this happens, JAXB wraps each item in the collection with an element. So the below Java class:

When marshalled, it generates this XML:

@XmlElementWrapper

The @XmlElementWrapper maps a Java collection to an XML wrapped collection. JAXB supports two types of collection mappings, wrapped and unwrapped. The default is unwrapped.

The Java class below annotates the employees collection with the @XmlElementWrapper annotation.

This is the XML generated. As you can see, the items in the list are wrapped by the employees XML element.

If we didn’t use the @XmlElementWrapper annotation, this is the XML that would be generated. Note that each item in the list is a direct child of company.

@XmlJavaTypeAdapter and @XmlJavaTypeAdapters

The @XmlJavaTypeAdapter is the workhorse of JAXB type mapping. JAXB can map any Java class to an XML Schema type using the @XmlJavaTypeAdapter annotation.

The following class illustrates how to use adapters. The Company class has three elements that map to non-standard XML Schema types: CompanyId, and Joda’s DateTime and LocalDate.

This is the implementation of the @XmlJavaTypeAdapter to support Joda DateTimes. The adapter extends from javax.xml.bind.annotation.adapters.XmlAdapter and must implement the marshal and umarshal methods.

Finally, we need to register the adapters for the package in the package-info.java file so that the JAXB engine can use them:

Note that you could also declare the @XmlJavaTypeAdapter annotation at method or class level.

Bibliography

The following two tabs change content below.

Eduard Manas

Eduard is a senior IT consultant with over 15 years in the financial sector. He is an experienced developer in Java, C#, Python, Wordpress, Tibco EMS/RV, Oracle, Sybase and MySQL.Outside of work, he likes spending time with family, friends, and watching football.

Latest posts by Eduard Manas (see all)

Leave a Reply