The JavaTM Architecture for XML Binding (JAXB) provides a fast and convenient way to bind between XML schemas and Java representations, making it easy for Java developers to incorporate XML data and processing functions in Java applications. As part of this process, JAXB provides methods for unmarshalling XML instance documents into Java content trees, and then marshalling Java content trees back into XML instance documents. JAXB also provides a way to generate XML schema from Java objects.
JAXB 2.0 includes several important improvements to JAXB 1.0:
Support for all W3C XML Schema features. (JAXB 1.0 did not specify bindings for some of the W3C XML Schema features.)
Support for binding Java-to-XML, with the addition of the javax.xml.bind.annotation package to control this binding. (JAXB 1.0 specified the mapping of XML Schema-to-Java, but not Java-to-XML Schema.)
A significant reduction in the number of generated schema-derived classes.
Additional validation capabilities through the JAXP 1.3 validation APIs.
Smaller runtime libraries.
This chapter describes the JAXB architecture, functions, and core concepts, and provides examples with step-by-step procedures for using JAXB.
This section describes the components and interactions in the JAXB processing model.
Figure 17–1 shows the components that make up a JAXB implementation.
A JAXB implementation consists of the following architectural components:
Schema compiler: Binds a source schema to a set of schema-derived program elements. The binding is described by an XML-based binding language.
Schema generator: Maps a set of existing program elements to a derived schema. The mapping is described by program annotations.
Binding runtime framework: Provides unmarshalling (reading) and marshalling (writing) operations for accessing, manipulating, and validating XML content using either schema-derived or existing program elements.
Figure 17–2 shows what occurs during the JAXB binding process.
The general steps in the JAXB data binding process are:
Generate classes: An XML schema is used as input to the JAXB binding compiler to generate JAXB classes based on that schema.
Compile classes: All of the generated classes, source files, and application code must be compiled.
Unmarshal: XML documents written according to the constraints in the source schema are unmarshalled by the JAXB binding framework. Note that JAXB also supports unmarshalling XML data from sources other than files/documents, such as DOM nodes, string buffers, SAX Sources, and so forth.
Generate content tree: The unmarshalling process generates a content tree of data objects instantiated from the generated JAXB classes; this content tree represents the structure and content of the source XML documents.
Validate (optional): The unmarshalling process optionally involves validation of the source XML documents before generating the content tree. Note that if you modify the content tree in Step 6, below, you can also use the JAXB Validate operation to validate the changes before marshalling the content back to an XML document.
Process content: The client application can modify the XML data represented by the Java content tree by means of interfaces generated by the binding compiler.
Marshal: The processed content tree is marshalled out to one or more XML output documents. The content may be validated before marshalling.
Unmarshalling provides a client application the ability to convert XML data into JAXB-derived Java objects.
Marshalling provides a client application the ability to convert a JAXB-derived Java object tree back into XML data.
By default, the Marshaller uses UTF-8 encoding when generating XML data.
Client applications are not required to validate the Java content tree before marshalling. There is also no requirement that the Java content tree be valid with respect to its original schema to marshal it back into XML data.
Validation is the process of verifying that an XML document meets all the constraints expressed in the schema. JAXB 1.0 provided validation at unmarshal time and also enabled on-demand validation on a JAXB content tree. JAXB 2.0 only allows validation at unmarshal and marshal time. A web service processing model is to be lax in reading in data and strict on writing it out. To meet that model, validation was added to marshal time so one could confirm that they did not invalidate the XML document when modifying the document in JAXB form.
This section describes how JAXB represents XML content as Java objects.
JAXB supports the grouping of generated classes in Java packages. A package consists of the following:
A Java class name that is derived from the XML element name, or specified by a binding customization.
An ObjectFactory class, which is a factory that is used to return instances of a bound Java class.
This section describes the default XML-to-Java bindings used by JAXB. All of these bindings can be overridden on global or case-by-case levels by means of a custom binding declaration. See the JAXB Specification for complete information about the default JAXB bindings.
A schema component using a simple type definition typically binds to a Java property. Since there are different kinds of such schema components, the following Java property attributes (common to the schema components) include:
Base type
Collection type, if any
Predicate
The rest of the Java property attributes are specified in the schema component using the simple type definition.
The following sections explain the default schema-to-Java, JAXBElement, and Java-to-schema data type bindings.
The Java language provides a richer set of data type than XML schema. Table 17–1 lists the mapping of XML data types to Java data types in JAXB.
Table 17–1 JAXB Mapping of XML Schema Built-in Data Types
XML Schema Type |
Java Data Type |
---|---|
xsd:string |
java.lang.String |
xsd:integer |
java.math.BigInteger |
xsd:int |
int |
xsd.long |
long |
xsd:short |
short |
xsd:decimal |
java.math.BigDecimal |
xsd:float |
float |
xsd:double |
double |
xsd:boolean |
boolean |
xsd:byte |
byte |
xsd:QName |
javax.xml.namespace.QName |
xsd:dateTime |
javax.xml.datatype.XMLGregorianCalendar |
xsd:base64Binary |
byte[] |
xsd:hexBinary |
byte[] |
xsd:unsignedInt |
long |
xsd:unsignedShort |
int |
xsd:unsignedByte |
short |
xsd:time |
javax.xml.datatype.XMLGregorianCalendar |
xsd:date |
javax.xml.datatype.XMLGregorianCalendar |
xsd:g |
javax.xml.datatype.XMLGregorianCalendar |
xsd:anySimpleType |
java.lang.Object |
xsd:anySimpleType |
java.lang.String |
xsd:duration |
javax.xml.datatype.Duration |
xsd:NOTATION |
javax.xml.namespace.QName |
When XML element information can not be inferred by the derived Java representation of the XML content, a JAXBElement object is provided. This object has methods for getting and setting the object name and object value.
Table 17–2 shows the default mapping of Java classes to XML data types.
Table 17–2 JAXB Mapping of XML Data Types to Java Classes
Java Class |
XML Data Type |
---|---|
java.lang.String |
xs:string |
java.math.BigInteger |
xs:integer |
java.math.BigDecimal |
xs:decimal |
java.util.Calendar |
xs:dateTime |
java.util.Date |
xs:dateTime |
javax.xml.namespace.QName |
xs:QName |
java.net.URI |
xs:string |
javax.xml.datatype.XMLGregorianCalendar |
xs:anySimpleType |
javax.xml.datatype.Duration |
xs:duration |
java.lang.Object |
xs:anyType |
java.awt.Image |
xs:base64Binary |
javax.activation.DataHandler |
xs:base64Binary |
javax.xml.transform.Source |
xs:base64Binary |
java.util.UUID |
xs:string |
The following sections explain how to customize generated JAXB classes and Java program elements.
Custom JAXB binding declarations allow you to customize your generated JAXB classes beyond the XML-specific constraints in an XML schema to include Java-specific refinements, such as class and package name mappings.
JAXB provides two ways to customize an XML schema:
As inline annotations in a source XML schema
As declarations in an external binding customization file that is passed to the JAXB binding compiler
Code examples that show how to customize JAXB bindings are provided later in this chapter.
The JAXB annotations defined in the javax.xml.bind.annotations package can be used to customize Java program elements to XML schema mapping. Table 17–3 summarizes the JAXB annotations that can be used with a Java package.
Table 17–3 JAXB Annotations Associated with a Java Package
Table 17–4 summarizes JAXB annotations that can be used with a Java class.
Table 17–4 JAXB Annotations Associated with a Java Class
Table 17–5 summarizes JAXB annotations that can be used with a Java enum type.
Table 17–5 JAXB Annotations Associated with a Java enum Type
Table 17–6 summarizes JAXB annotations that can be used with Java properties and fields.
Table 17–6 JAXB Annotations Associated with Java Properties and Fields
Table 17–7 summarizes the JAXB annotation that can be used with object factories.
Table 17–7 JAXB Annotations Associated with Object Factories
Table 17–8 summarizes JAXB annotations that can be used with adapters.
Table 17–8 JAXB Annotations Associated with Adapters
The sections that follow provide instructions for using the example Java applications that are included in the tut-install/javaeetutorial5/examples/jaxb/ directory. These examples demonstrate and build upon key JAXB features and concepts. Follow these procedures in the order presented.
After reading this section, you should feel comfortable enough with JAXB that you can:
Generate JAXB Java classes from an XML schema
Use schema-derived JAXB classes to unmarshal and marshal XML content in a Java application
Create a Java content tree from scratch using schema-derived JAXB classes
Validate XML content during unmarshalling and at runtime
Customize JAXB schema-to-Java bindings
This chapter describes three sets of examples:
The Basic examples (Modify Marshal, Unmarshal Validate) demonstrate basic JAXB concepts like unmarshalling, marshalling, and validating XML content using default settings and bindings.
The Customize examples (Customize Inline, Datatype Converter, External Customize) demonstrate various ways of customizing the default binding of XML schemas to Java objects.
The Java-to-Schema examples show how to use annotations to map Java classes to XML schema.
The Basic and Customize examples are based on a Purchase Order scenario. Each uses an XML document, po.xml, written against an XML schema, po.xsd. These documents are derived from the W3C XML Schema Part 0: Primer, edited by David C. Fallside.
The Basic and Customize example directories contain several base files:
po.xsd is the XML schema you will use as input to the JAXB binding compiler, and from which schema-derived JAXB Java classes will be generated. For the Customize Inline and Datatype Converter examples, this file contains inline binding customizations.
po.xml is the Purchase Order XML file containing sample XML content, and is the file you will unmarshal into a Java content tree in each example. This file is almost exactly the same in each example, with minor content differences to highlight different JAXB concepts.
Main.java is the main Java class for each example.
build.xml is an Ant project file provided for your convenience. Use the Ant tool to generate, compile, and run the schema-derived JAXB classes automatically. The build.xml file varies across the examples.
MyDatatypeConverter.java in the inline-customize example is a Java class used to provide custom data type conversions.
binding.xjb in the External Customize example is an external binding declarations file that is passed to the JAXB binding compiler to customize the default JAXB bindings.
Table 17–9, Table 17–10, and Table 17–11 briefly describe the Basic, Customize, and Java-to-Schema JAXB examples.
Table 17–9 Basic JAXB Examples
Example Name |
Description |
---|---|
Demonstrates how to modify a Java content tree. |
|
Demonstrates how to enable validation during unmarshalling. |
Table 17–10 Customize JAXB Examples
Example Name |
Description |
---|---|
Demonstrates how to customize the default JAXB bindings by using inline annotations in an XML schema. |
|
Similar to the Customize Inline example, this example illustrates alternate, more terse bindings of XML simpleType definitions to Java data types. |
|
Illustrates how to use an external binding declarations file to pass binding customizations for a read-only schema to the JAXB binding compiler. |
Table 17–11 Java-to-Schema JAXB Examples
Example Name |
Description |
---|---|
Illustrates how to marshal and unmarshal JAXB-annotated classes to XML schema. The example also shows how to enable JAXP 1.3 validation at unmarshal time using a schema file that was generated from the JAXB mapped classes. |
|
Illustrates how to use the @XmlAccessorOrder and @XmlType.propOrder mapping annotations in Java classes to control the order in which XML content is marshalled/unmarshalled by a Java type. |
|
Illustrates how to use the interface XmlAdapter and the annotation @XmlJavaTypeAdapter to provide a a custom mapping of XML content into and out of a HashMap (field) that uses an int as the key and a String as the value. |
|
Illustrates how to use the annotation @XmlAttribute to define a property or field to be handled as an XML attribute. |
|
Illustrates how to use the annotation @XmlRootElement to define an XML element name for the XML schema type of the corresponding class. |
|
Illustrates how to use the annotation @XmlSchemaType to customize the mapping of a property or field to an XML built-in type. |
|
Illustrates how to use the annotation @XmlType to map a class or enum type to an XML schema type. |
The JAXB XJC schema binding compiler transforms, or binds, a source XML schema to a set of JAXB content classes in the Java programming language. The compiler, xjc, is provided in two flavors in the Application Server: xjc.sh (Solaris/Linux) and xjc.bat (Windows). Both xjc.sh and xjc.bat take the same command-line options. You can display quick usage instructions by invoking the scripts without any options, or with the -help switch. The syntax is as follows:
xjc [-options ...] schema
The xjc command line options are as follows:
Do not perform strict validation of the input schema or schemas. By default, xjc performs strict validation of the source schema before processing. Note that this does not mean the binding compiler will not perform any validation; it simply means that it will perform less-strict validation.
By default, the XJC binding compiler strictly enforces the rules outlined in the Compatibility chapter of the JAXB Specification. In the default (strict) mode, you are also limited to using only the binding customizations defined in the specification. By using the -extension switch, you will be allowed to use the JAXB Vendor Extensions.
Specify one or more external binding files to process. (Each binding file must have its own -b switch.) The syntax of the external binding files is extremely flexible. You may have a single binding file that contains customizations for multiple schemas or you can break the customizations into multiple bindings files. In addition, the ordering of the schema files and binding files on the command line does not matter.
By default, xjc will generate Java content classes in the current directory. Use this option to specify an alternate output directory. The directory must already exist; xjc will not create it for you.
Specify an alternate output directory. By default, the XJC binding compiler will generate the Java content classes in the current directory. The output directory must already exist; the XJC binding compiler will not create it for you.
Specify the HTTP/HTTPS proxy. The format is [user[:password]@]proxyHost[:proxyPort]. The old -host and -port options are still supported by the Reference Implementation for backwards compatibility, but they have been deprecated.
Specify where to find client application class files used by the <jxb:javaType> and <xjc:superClass> customizations.
Specify catalog files to resolve external entity references. Supports TR9401, XCatalog, and OASIS XML Catalog format. For more information, see the XML Entity and URI Resolvers document or examine the catalog-resolver sample application.
Force the XJC binding compiler to mark the generated Java sources read-only. By default, the XJC binding compiler does not write-protect the Java source files it generates.
Suppress the generation of package level annotations into **/package-info.java. Using this switch causes the generated code to internalize those annotations into the other generated classes.
Treat input schemas as W3C XML Schema (default). If you do not specify this switch, your input schemas will be treated as W3C XML Schema.
Suppress compiler output, such as progress information and warnings.
Display a brief summary of the compiler switches.
Display the compiler version information.
Enable source location support for generated code.
Generate accessor methods with the synchronized keyword.
Mark the generated code with the -@javax.annotation.Generated annotation.
The JAXB Schema Generator, schemagen, creates a schema file for each namespace referenced in your Java classes. The schema generator can be launched using the appropriate schemagen shell script in the bin directory for your platform. The schema generator processes Java source files only. If your Java sources reference other classes, those sources must be accessible from your system CLASSPATH environment variable, otherwise errors will occur when the schema is generated. There is no way to control the name of the generated schema files.
You can display quick usage instructions by invoking the scripts without any options, or with the -help option. The syntax is as follows:
schemagen [-d path] [java-source-files]
The -d path option specifies the location of the processor- and javac-generated class files.
When you run the JAXB binding compiler against the po.xsd XML schema used in the basic examples (Unmarshal Read, Modify Marshal, Unmarshal Validate), the JAXB binding compiler generates a Java package named primer.po containing 11 classes, making a total of 12 classes in each of the basic examples, as described in Table 17–12.
Table 17–12 Schema-Derived JAXB Classes in the Basic Examples
Class |
Description |
---|---|
primer/po/Comment.java |
Public interface extending javax.xml.bind.Element; binds to the global schema element named comment. Note that JAXB generates element interfaces for all global element declarations. |
primer/po/Items.java |
Public interface that binds to the schema complexType named Items. |
primer/po/ObjectFactory.java |
Public class extending com.sun.xml.bind.DefaultJAXBContextImpl; used to create instances of specified interfaces. For example, the ObjectFactory createComment() method instantiates a Comment object. |
primer/po/PurchaseOrder.java |
Public interface extending javax.xml.bind.Element, and PurchaseOrderType; binds to the global schema element named PurchaseOrder. |
primer/po/PurchaseOrderType.java |
Public interface that binds to the schema complexType named PurchaseOrderType. |
primer/po/USAddress.java |
Public interface that binds to the schema complexType named USAddress. |
primer/po/impl/CommentImpl.java |
Implementation of Comment.java |
primer/po/impl/ItemsImpl.java |
Implementation of Items.java |
primer/po/impl/PurchaseOrderImpl.java |
Implementation of PurchaseOrder.java |
primer/po/impl/PurchaseOrderTypeImpl.java |
Implementation of PurchaseOrderType.java |
primer/po/impl/USAddressImpl.java |
Implementation of USAddress.java |
You should never directly use the generated implementation classes (*Impl.java in the packagename/impl/ directory). These classes cannot be referenced directly because the class names in this directory are not standardized by the JAXB specification. The ObjectFactory method is the only portable means to create an instance of a schema-derived interface. There is also an ObjectFactory.newInstance(Class JAXBinterface) method that enables you to create instances of interfaces.
These classes and their specific bindings to the source XML schema for the basic examples are described in Table 17–13. .
Table 17–13 Schema-to-Java Bindings for the Basic Examples
The sections that follow briefly explain the functions of the following individual classes generated by the JAXB binding compiler for the Basic examples:
In Comment.java:
The Comment class is part of the primer.po package.
Comment is a public interface that extends javax.xml.bind.Element.
Content in instantiations of this class binds to the XML schema element named comment.
The getValue() and setValue() methods are used to get and set strings representing XML comment elements in the Java content tree.
In Items.java:
The Items class is part of the primer.po package.
The class provides public interfaces for Items and ItemType.
Content in instantiations of this class binds to the XML ComplexTypes Items and its child element ItemType.
Item provides the getItem() method.
ItemType provides methods for:
getPartNum();
setPartNum(String value);
getComment();
setComment(java.lang.String value);
getUSPrice();
setUSPrice(java.math.BigDecimal value);
getProductName();
setProductName(String value);
getShipDate();
setShipDate(java.util.Calendar value);
getQuantity();
setQuantity(java.math.BigInteger value);
In ObjectFactory.java:
The ObjectFactory class is part of the primer.po package.
ObjectFactory provides factory methods for instantiating Java interfaces representing XML content in the Java content tree.
Method names are generated by concatenating:
The string constant create.
If the Java content interface is nested within another interface, then the concatenation of all outer Java class names.
The name of the Java content interface.
For example, in this case, for the Java interface primer.po.Items.ItemType, ObjectFactory creates the method createItemsItemType().
In PurchaseOrder.java:
The PurchaseOrder class is part of the primer.po package.
PurchaseOrder is a public interface that extends javax.xml.bind.Element and primer.po.PurchaseOrderType.
Content in instantiations of this class binds to the XML schema element named purchaseOrder.
In PurchaseOrderType.java:
The PurchaseOrderType class is part of the primer.po package.
Content in instantiations of this class binds to the XML schema child element named PurchaseOrderType.
PurchaseOrderType is a public interface that provides the following methods:
getItems();
setItems(primer.po.Items value);
getOrderDate();
setOrderDate(java.util.Calendar value);
getComment();
setComment(java.lang.String value);
getBillTo();
setBillTo(primer.po.USAddress value);
getShipTo();
setShipTo(primer.po.USAddress value);
In USAddress.java:
The USAddress class is part of the primer.po package.
Content in instantiations of this class binds to the XML schema element named USAddress.
USAddress is a public interface that provides the following methods:
getState();
setState(String value);
getZip();
setZip(java.math.BigDecimal value);
getCountry();
setCountry(String value);
getCity();
setCity(String value);
getStreet();
setStreet(String value);
getName();
setName(String value);
This section describes the Basic examples (Modify Marshal, Unmarshal Validate) that demonstrate how to:
Unmarshal an XML document into a Java content tree and access the data contained within it
Modify a Java content tree
Use the ObjectFactory class to create a Java content tree from scratch and then marshal it to XML data
Perform validation during unmarshalling
Validate a Java content tree at runtime
The Modify Marshal example demonstrates how to modify a Java content tree.
The tut-install/javaeetutorial5/examples/jaxb/modify-marshal/src/modifymarshal/Main.java class declares imports for three standard Java classes plus four JAXB binding framework classes and primer.po package:
import java.io.FileInputStream; import java.io.IOException; import java.math.BigDecimal; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import primer.po.*;
A JAXBContext instance is created for handling classes generated in primer.po.
JAXBContext jc = JAXBContext.newInstance( "primer.po" );
An Unmarshaller instance is created, and po.xml is unmarshalled.
Unmarshaller u = jc.createUnmarshaller(); PurchaseOrder po = (PurchaseOrder)u.unmarshal( new FileInputStream( "po.xml" ) );
set methods are used to modify information in the address branch of the content tree.
USAddress address = po.getBillTo(); address.setName( "John Bob" ); address.setStreet( "242 Main Street" ); address.setCity( "Beverly Hills" ); address.setState( "CA" ); address.setZip( new BigDecimal( "90210" ) );
A Marshaller instance is created, and the updated XML content is marshalled to system.out. The setProperty API is used to specify output encoding; in this case formatted (human readable) XML format.
Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal( po, System.out );
Follow these instructions to build and run the Modify Marshal example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the modify-marshal folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the modify-marshal project and select Run.
To compile and run the Modify Marshal example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/modify-marshal/ directory and type the following:
ant runapp |
The Unmarshal Validate example demonstrates how to enable validation during unmarshalling. Note that JAXB provides functions for validation during unmarshalling but not during marshalling. Validation is explained in more detail in More about Validation.
The tut-install/javaeetutorial5/examples/jaxb/unmarshal-validate/src/unmarshalvalidate/Main.java class declares imports for three standard Java classes plus seven JAXB binding framework classes and the primer.po package:
import java.io.FileInputStream; import java.io.IOException; import java.math.BigDecimal; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.util.ValidationEventCollector; import primer.po.*;
A JAXBContext instance is created for handling classes generated in primer.po.
JAXBContext jc = JAXBContext.newInstance( "primer.po" );
An Unmarshaller instance is created.
Unmarshaller u = jc.createUnmarshaller();
The default JAXB Unmarshaller ValidationEventHandler is enabled to send to validation warnings and errors to system.out. The default configuration causes the unmarshal operation to fail upon encountering the first validation error.
u.setValidating( true );
An attempt is made to unmarshal po.xml into a Java content tree. For the purposes of this example, the po.xml contains a deliberate error.
PurchaseOrder po = (PurchaseOrder)u.unmarshal( new FileInputStream("po.xml"));
The default validation event handler processes a validation error, generates output to system.out, and then an exception is thrown.
} catch( UnmarshalException ue ) { System.out.println( "Caught UnmarshalException" ); } catch( JAXBException je ) { je.printStackTrace(); } catch( IOException ioe ) { ioe.printStackTrace(); }
Follow these instructions to build and run the Unmarshal Validate example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the unmarshal-validate folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the unmarshal-validate project and select Run.
To compile and run the Unmarshal Validate example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/unmarshal-validate/ directory and type the following:
ant runapp |
The next part of this chapter describes several examples that build on the concepts demonstrated in the Basic examples.
The goal of this section is to illustrate how to customize JAXB bindings by means of custom binding declarations made in either of two ways:
As annotations made inline in an XML schema
As statements in an external file passed to the JAXB binding compiler
Unlike the examples in Basic JAXB Examples, which focus on the Java code in the respective Main.java class files, the examples here focus on customizations made to the XML schema before generating the schema-derived Java binding classes.
Although JAXB binding customizations must currently be made by hand, it is envisioned that a tool/wizard might eventually be written by Sun or a third party to make this process more automatic. One of the goals of the JAXB technology is to standardize the format of binding declarations, thereby making it possible to create customization tools and to provide a standard interchange format between JAXB implementations.
This section just begins to scratch the surface of customizations you can make to JAXB bindings and validation methods. For more information, refer to the JAXB Specification .
In most cases, the default bindings generated by the JAXB binding compiler will be sufficient to meet your needs. There are cases, however, in which you might want to modify the default bindings. Some of these include:
Creating API documentation for the schema-derived JAXB packages, classes, methods and constants; by adding custom Javadoc tool annotations to your schemas, you can explain concepts, guidelines, and rules specific to your implementation.
Providing semantically meaningful customized names for cases that the default XML name-to-Java identifier mapping cannot handle automatically; for example:
To resolve name collisions (as described in Appendix D.2.1 of the JAXB Specification). Note that the JAXB binding compiler detects and reports all name conflicts.
To provide names for typesafe enumeration constants that are not legal Java identifiers; for example, enumeration over integer values.
To provide better names for the Java representation of unnamed model groups when they are bound to a Java property or class.
To provide more meaningful package names than can be derived by default from the target namespace URI.
Overriding default bindings; for example:
Specify that a model group should be bound to a class rather than a list.
Specify that a fixed attribute can be bound to a Java constant.
Override the specified default binding of XML Schema built-in data types to Java data types. In some cases, you might want to introduce an alternative Java class that can represent additional characteristics of the built-in XML Schema data type.
This section explains some core JAXB customization concepts:
Inline and external customizations
Scope, inheritance, and precedence
Customization syntax
Customization namespace prefix
Customizations to the default JAXB bindings are made in the form of binding declarations passed to the JAXB binding compiler. These binding declarations can be made in either of two ways:
As inline annotations in a source XML schema
As declarations in an external binding customizations file
For some people, using inline customizations is easier because you can see your customizations in the context of the schema to which they apply. Conversely, using an external binding customization file enables you to customize JAXB bindings without having to modify the source schema, and enables you to easily apply customizations to several schema files at once.
You can combine the two types of customizations. For example, you could include a reference to an external binding customizations file in an inline annotation. However, you cannot declare both an inline and external customization on the same schema element.
Each of these types of customization is described in more detail below.
Customizations to JAXB bindings made by means of inline binding declarations in an XML schema file take the form of <xsd:appinfo> elements embedded in schema <xsd:annotation> elements (xsd: is the XML schema namespace prefix, as defined in W3C XML Schema Part 1: Structures). The general form for inline customizations is shown below.
<xs:annotation> <xs:appinfo> . . binding declarations . . </xs:appinfo> </xs:annotation>
Customizations are applied at the location at which they are declared in the schema. For example, a declaration at the level of a particular element would apply to that element only. Note that the XMLSchema namespace prefix must be used with the <annotation> and <appinfo> declaration tags. In the example above, xs: is used as the namespace prefix, so the declarations are tagged <xs:annotation> and <xs:appinfo>.
Customizations to JAXB bindings made by means of an external file containing binding declarations take the general form shown below.
<jxb:bindings schemaLocation = "xs:anyURI"> <jxb:bindings node = "xs:string">* <binding declaration> <jxb:bindings> </jxb:bindings>
schemaLocation is a URI reference to the remote schema.
node is an XPath 1.0 expression that identifies the schema node within schemaLocation to which the given binding declaration is associated.
For example, the first schemaLocation/node declaration in a JAXB binding declarations file specifies the schema name and the root schema node:
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
A subsequent schemaLocation/node declaration, say for a simpleType element named ZipCodeType in the above schema, would take the form:
<jxb:bindings node="//xs:simpleType[@name=’ZipCodeType’]">
Binding customization files should be straight ASCII text. The name or extension does not matter, although a typical extension, used in this chapter, is .xjb.
Customization files containing binding declarations are passed to the JAXB Binding compiler, xjc, using the following syntax:
xjc -b file schema
where file is the name of binding customization file, and schema is the name of the schema or schemas you want to pass to the binding compiler.
You can have a single binding file that contains customizations for multiple schemas, or you can break the customizations into multiple bindings files; for example:
xjc schema1.xsd schema2.xsd schema3.xsd -b bindings123.xjb xjc schema1.xsd schema2.xsd schema3.xsd -b bindings1.xjb -b bindings2.xjb -b bindings3.xjb
Note that the ordering of schema files and binding files on the command line does not matter, although each binding customization file must be preceded by its own -b switch on the command line.
For more information about xjc compiler options in general, see JAXB Compiler Options.
There are several rules that apply to binding declarations made in an external binding customization file that do not apply to similar declarations made inline in a source schema:
The binding customization file must begin with the jxb:bindings version attribute, plus attributes for the JAXB and XMLSchema namespaces:
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
The remote schema to which the binding declaration applies must be identified explicitly in XPath notation by means of a jxb:bindings declaration specifying schemaLocation and node attributes:
schemaLocation specifies a URI reference to the remote schema.
node specifies an XPath 1.0 expression that identifies the schema node within schemaLocation to which the given binding declaration is associated; in the case of the initial jxb:bindings declaration in the binding customization file, this node is typically "/xs:schema".
Similarly, individual nodes within the schema to which customizations are to be applied must be specified using XPath notation; for example:
<jxb:bindings node="//xs:complexType[@name=’USAddress’]">
In such cases, the customization is applied to the node by the binding compiler as if the declaration was embedded inline in the node’s <xs:appinfo> element.
To summarize these rules, the external binding element <jxb:bindings> is only recognized for processing by a JAXB binding compiler in three cases:
When its parent is an <xs:appinfo> element.
When it is an ancestor of another <jxb:bindings> element.
When it is the root element of a document. An XML document that has a <jxb:bindings> element as its root is referred to as an external binding declaration file.
Default JAXB bindings can be customized or overridden at four different levels, or scopes.
Figure 17–3 illustrates the inheritance and precedence of customization declarations. Specifically, declarations towards the top of the pyramid inherit and supersede declarations below them. For example, Component declarations inherit from and supersede Definition declarations; Definition declarations inherit and supersede Schema declarations; and Schema declarations inherit and supersede Global declarations.
The syntax for the four types of JAXB binding declarations, as well as the syntax for the XML-to-Java data type binding declarations and the customization namespace prefix, are described below.
Global scope customizations are declared with <globalBindings>. The syntax for global scope customizations is as follows:
<globalBindings> [ collectionType = "collectionType" ] [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ] [ generateIsSetMethod = "true" | "false" | "1" | "0" ] [ enableFailFastCheck = "true" | "false" | "1" | "0" ] [ choiceContentProperty = "true" | "false" | "1" | "0" ] [ underscoreBinding = "asWordSeparator" | "asCharInWord" ] [ typesafeEnumBase = "typesafeEnumBase" ] [ typesafeEnumMemberName = "generateName" | "generateError" ] [ enableJavaNamingConventions = "true" | "false" | "1" | "0" ] [ bindingStyle = "elementBinding" | "modelGroupBinding" ] [ <javaType> ... </javaType> ]* </globalBindings>
collectionType can be either indexed or any fully qualified class name that implements java.util.List.
fixedAttributeAsConstantProperty can be either true, false, 1, or 0. The default value is false.
generateIsSetMethod can be either true, false, 1, or 0. The default value is false.
enableFailFastCheck can be either true, false, 1, or 0. If enableFailFastCheck is true or 1 and the JAXB implementation supports this optional checking, type constraint checking is performed when setting a property. The default value is false. Please note that the JAXB implementation does not support failfast validation.
choiceContentProperty can be either true, false, 1, or 0. The default value is false. choiceContentProperty is not relevant when the bindingStyle is elementBinding. Therefore, if bindingStyle is specified as elementBinding, then the choiceContentProperty must result in an invalid customization.
underscoreBinding can be either asWordSeparator or asCharInWord. The default value is asWordSeparator.
typesafeEnumBase can be a list of QNames, each of which must resolve to a simple type definition. The default value is xs:NCName. See Typesafe Enumeration Binding Declarations for information about localized mapping of simpleType definitions to Java typesafe enum classes.
typesafeEnumMemberName can be either generateError or generateName. The default value is generateError.
enableJavaNamingConventions can be either true, false, 1, or 0. The default value is true.
bindingStyle can be either elementBinding, or modelGroupBinding. The default value is elementBinding.
<javaType> can be zero or more javaType binding declarations. For more information, see javaType Binding Declarations.
<globalBindings> declarations are only valid in the annotation element of the top-level schema element. There can only be a single instance of a <globalBindings> declaration in any given schema or binding declarations file. If one source schema includes or imports a second source schema, the <globalBindings> declaration must be declared in the first source schema.
Schema scope customizations are declared with <schemaBindings>. The syntax for schema scope customizations is:
<schemaBindings> [ <package> package </package> ] [ <nameXmlTransform> ... </nameXmlTransform> ]* </schemaBindings> <package [ name = "packageName" ] [ <javadoc> ... </javadoc> ] </package> <nameXmlTransform> [ <typeName [ suffix="suffix" ] [ prefix="prefix" ] /> ] [ <elementName [ suffix="suffix" ] [ prefix="prefix" ] /> ] [ <modelGroupName [ suffix="suffix" ] [ prefix="prefix" ] /> ] [ <anonymousTypeName [ suffix="suffix" ] [ prefix="prefix" ] /> ] </nameXmlTransform>
As shown above, <schemaBinding> declarations include two subcomponents:
<package>...</package> specifies the name of the package and, if desired, the location of the API documentation for the schema-derived classes.
<nameXmlTransform>...</nameXmlTransform> specifies customizations to be applied.
The <class> binding declaration enables you to customize the binding of a schema element to a Java content interface or a Java Element interface. <class> declarations can be used to customize:
A name for a schema-derived Java interface
An implementation class for a schema-derived Java content interface
The syntax for <class> customizations is:
<class [ name = "className"] [ implClass= "implClass" ] > [ <javadoc> ... </javadoc> ] </class>
name is the name of the derived Java interface. It must be a legal Java interface name and must not contain a package prefix. The package prefix is inherited from the current value of package.
implClass is the name of the implementation class for className and must include the complete package name.
The <javadoc> element specifies the Javadoc tool annotations for the schema-derived Java interface. The string entered here must use CDATA or < to escape embedded HTML tags.
The <property> binding declaration enables you to customize the binding of an XML schema element to its Java representation as a property. The scope of customization can either be at the definition level or component level depending upon where the <property> binding declaration is specified.
The syntax for <property> customizations is:
<property [ name = "propertyName"] [ collectionType = "propertyCollectionType" ] [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ] [ generateIsSetMethod = "true" | "false" | "1" | "0" ] [ enableFailFastCheck ="true" | "false" | "1" | "0" ] [ <baseType> ... </baseType> ] [ <javadoc> ... </javadoc> ] </property> <baseType> <javaType> ... </javaType> </baseType>
name defines the customization value propertyName; it must be a legal Java identifier.
collectionType defines the customization value propertyCollectionType, which is the collection type for the property. propertyCollectionType. If specified, can be either indexed or any fully-qualified class name that implements java.util.List.
fixedAttributeAsConstantProperty defines the customization value fixedAttributeAsConstantProperty. The value can be either true, false, 1, or 0.
generateIsSetMethod defines the customization value of generateIsSetMethod. The value can be either true, false, 1, or 0.
enableFailFastCheck defines the customization value enableFailFastCheck. The value can be either true, false, 1, or 0. Please note that the JAXB implementation does not support failfast validation.
<javadoc> customizes the Javadoc tool annotations for the property’s getter method.
The <javaType> declaration provides a way to customize the translation of XML data types to and from Java data types. XML provides more data types than Java, and so the <javaType> declaration lets you specify custom data type bindings when the default JAXB binding cannot sufficiently represent your schema.
The target Java data type can be a Java built-in data type or an application-specific Java data type. If an application-specific data type is used as the target, your implementation must also provide parse and print methods for unmarshalling and marshalling data. To this end, the JAXB specification supports a parseMethod and printMethod:
The parseMethod is called during unmarshalling to convert a string from the input document into a value of the target Java data type.
The printMethod is called during marshalling to convert a value of the target type into a lexical representation.
If you prefer to define your own data type conversions, JAXB defines a static class, DatatypeConverter, to assist in the parsing and printing of valid lexical representations of the XML Schema built-in data types.
The syntax for the <javaType> customization is:
<javaType name= "javaType" [ xmlType= "xmlType" ] [ hasNsContext = "true" | "false" ] [ parseMethod= "parseMethod" ] [ printMethod= "printMethod" ]>
name is the Java data type to which xmlType is to be bound.
xmlType is the name of the XML Schema data type to which javaType is to be bound; this attribute is required when the parent of the <javaType> declaration is <globalBindings>.
hasNsContext allows a namespace context to be specified as a second parameter to a print or a parse method; can be either true, false, 1, or 0. By default, this attribute is false, and in most cases you will not need to change it.
parseMethod is the name of the parse method to be called during unmarshalling.
printMethod is the name of the print method to be called during marshalling.
The <javaType> declaration can be used in:
A <globalBindings> declaration
An annotation element for simple type definitions, GlobalBindings, and <basetype> declarations
A <property> declaration
See MyDatatypeConverter Class for an example of how <javaType> declarations and the DatatypeConverterInterface interface are implemented in a custom data type converter class.
The typesafe enumeration declarations provide a localized way to map XML simpleType elements to Java typesafe enum classes. There are two types of typesafe enumeration declarations you can make:
<typesafeEnumClass> lets you map an entire simpleType class to typesafe enum classes.
<typesafeEnumMember> lets you map just selected members of a simpleType class to typesafe enum classes.
In both cases, there are two primary limitations on this type of customization:
Only simpleType definitions with enumeration facets can be customized using this binding declaration.
This customization only applies to a single simpleType definition at a time. To map sets of similar simpleType definitions on a global level, use the typesafeEnumBase attribute in a <globalBindings> declaration, as described in Global Binding Declarations.
The syntax for the <typesafeEnumClass> customization is:
<typesafeEnumClass [ name = "enumClassName" ] [ <typesafeEnumMember> ... </typesafeEnumMember> ]* [ <javadoc> enumClassJavadoc </javadoc> ] </typesafeEnumClass>
name must be a legal Java Identifier, and must not have a package prefix.
You can have zero or more <typesafeEnumMember> declarations embedded in a <typesafeEnumClass> declaration.
<javadoc> customizes the Javadoc tool annotations for the enumeration class.
The syntax for the <typesafeEnumMember> customization is:
<typesafeEnumMember name = "enumMemberName"> [ value = "enumMemberValue" ] [ <javadoc> enumMemberJavadoc </javadoc> ] </typesafeEnumMember>
name must always be specified and must be a legal Java identifier.
value must be the enumeration value specified in the source schema.
<javadoc> customizes the Javadoc tool annotations for the enumeration constant.
For inline annotations, the <typesafeEnumClass> declaration must be specified in the annotation element of the <simpleType> element. The <typesafeEnumMember> must be specified in the annotation element of the enumeration member. This allows the enumeration member to be customized independently from the enumeration class.
For information about typesafe enum design patterns, see the sample chapter of Joshua Bloch’s Effective Java Programming on the Java Developer Connection.
The <javadoc> declaration lets you add custom Javadoc tool annotations to schema-derived JAXB packages, classes, interfaces, methods, and fields. Note that <javadoc> declarations cannot be applied globally; they are only valid as sub-elements of other binding customizations.
The syntax for the <javadoc> customization is:
<javadoc> Contents in <b>Javadoc<\b> format. </javadoc>
or
<javadoc> <<![CDATA[ Contents in <b>Javadoc<\b> format ]]> </javadoc>
Note that documentation strings in <javadoc> declarations applied at the package level must contain <body> open and close tags; for example:
<jxb:package name="primer.myPo"> <jxb:javadoc> <![CDATA[<body>Package level documentation for generated package primer.myPo.</body>]]> </jxb:javadoc> </jxb:package>
All standard JAXB binding declarations must be preceded by a namespace prefix that maps to the JAXB namespace URI (http://java.sun.com/xml/ns/jaxb). For example, in this sample, jxb: is used. To this end, any schema you want to customize with standard JAXB binding declarations must include the JAXB namespace declaration and JAXB version number at the top of the schema file. For example, in po.xsd for the Customize Inline example, the namespace declaration is as follows:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="1.0">
A binding declaration with the jxb namespace prefix would then take the form:
<xsd:annotation> <xsd:appinfo> <jxb:globalBindings binding declarations /> <jxb:schemaBindings> . . binding declarations . . </jxb:schemaBindings> </xsd:appinfo> </xsd:annotation>
Note that in this example, the globalBindings and schemaBindings declarations are used to specify, respectively, global scope and schema scope customizations. These customization scopes are described in more detail in Scope, Inheritance, and Precedence.
The Customize Inline example illustrates some basic customizations made by means of inline annotations to an XML schema named po.xsd. In addition, this example implements a custom data type converter class, MyDatatypeConverter.java, which illustrates print and parse methods in the <javaType> customization for handling custom data type conversions.
To summarize this example:
po.xsd is an XML schema containing inline binding customizations.
MyDatatypeConverter.java is a Java class file that implements print and parse methods specified by <javaType> customizations in po.xsd.
Main.java is the primary class file in the Customize Inline example, which uses the schema-derived classes generated by the JAXB compiler.
Follow these instructions to build and run the Customize Inline example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the inline-customize folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the inline-customize project and select Run.
To compile and run the Customize Inline example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/inline-customize/ directory and type the following:
ant runapp |
Key customizations in this sample, and the custom MyDatatypeConverter.java class, are described in more detail below.
The customized schema used in the Customize Inline example is in the file tut-install/javaeetutorial5/examples/jaxb/inline-customize/po.xsd. The customizations are in the <xsd:annotation> tags.
The code below shows the globalBindings declarations in po.xsd:
<jxb:globalBindings fixedAttributeAsConstantProperty="true" collectionType="java.util.Vector" typesafeEnumBase="xsd:NCName" choiceContentProperty="false" typesafeEnumMemberName="generateError" bindingStyle="elementBinding" enableFailFastCheck="false" generateIsSetMethod="false" underscoreBinding="asCharInWord"/>
In this example, all values are set to the defaults except for collectionType.
Setting fixedAttributeAsConstantProperty to true indicates that all fixed attributes should be bound to Java constants. By default, fixed attributes are just mapped to either simple or collection property, whichever is more appropriate.
Setting collectionType to java.util.Vector specifies that all lists in the generated implementation classes should be represented internally as vectors. Note that the class name you specify for collectionType must implement java.util.List and be callable by newInstance.
If typesafeEnumBase is set to xsd:string, it would be a global way to specify that all simple type definitions deriving directly or indirectly from xsd:string and having enumeration facets should be bound by default to a typesafe enum. If typesafeEnumBase is set to an empty string, "", no simple type definitions would ever be bound to a typesafe enum class by default. The value of typesafeEnumBase can be any atomic simple type definition except xsd:boolean and both binary types.
The JAXB implementation does not support the enableFailFastCheck attribute.
Using typesafe enum classes enables you to map schema enumeration values to Java constants, which in turn makes it possible to do compares on Java constants rather than string values.
The following code shows the schema binding declarations in po.xsd:
<jxb:schemaBindings> <jxb:package name="primer.myPo"> <jxb:javadoc> <![CDATA[<body> Package level documentation for generated package primer.myPo.</body>]]> </jxb:javadoc> </jxb:package> <jxb:nameXmlTransform> <jxb:elementName suffix="Element"/> </jxb:nameXmlTransform> </jxb:schemaBindings>
<jxb:package name="primer.myPo"/> specifies the primer.myPo as the package in which the schema-derived classes should be generated.
<jxb:nameXmlTransform> specifies that all generated Java element interfaces should have Element appended to the generated names by default. For example, when the JAXB compiler is run against this schema, the element interfaces CommentElement and PurchaseOrderElement will be generated. By contrast, without this customization, the default binding would instead generate Comment and PurchaseOrder.
This customization is useful if a schema uses the same name in different symbol spaces; for example, in global element and type definitions. In such cases, this customization enables you to resolve the collision with one declaration rather than having to individually resolve each collision with a separate binding declaration.
<jxb:javadoc> specifies customized Javadoc tool annotations for the primer.myPo package. Note that, unlike the <javadoc> declarations at the class level, below, the opening and closing <body> tags must be included when the <javadoc> declaration is made at the package level.
The following code shows the class binding declarations in po.xsd:
<xsd:complexType name="PurchaseOrderType"> <xsd:annotation> <xsd:appinfo> <jxb:class name="POType"> <jxb:javadoc> A <b>Purchase Order</b> consists of addresses and items. </jxb:javadoc> </jxb:class> </xsd:appinfo> </xsd:annotation> . . . </xsd:complexType>
The Javadoc tool annotations for the schema-derived POType class will contain the description "A <b>Purchase Order</b> consists of addresses and items." The < is used to escape the opening bracket on the <b> HTML tags.
When a <class> customization is specified in the appinfo element of a complexType definition, as it is here, the complexType definition is bound to a Java content interface.
Later in po.xsd, another <javadoc> customization is declared at this class level, but this time the HTML string is escaped with CDATA:
<xsd:annotation> <xsd:appinfo> <jxb:class> <jxb:javadoc> <![CDATA[ First line of documentation for a <b>USAddress</b>.]]> </jxb:javadoc> </jxb:class> </xsd:appinfo> </xsd:annotation>
If you want to include HTML markup tags in a <jaxb:javadoc> customization, you must enclose the data within a CDATA section or escape all left angle brackets using <. See XML 1.0 2nd Edition for more information.
Of particular interest here is the generateIsSetMethod customization, which causes two additional property methods, isSetQuantity and unsetQuantity, to be generated. These methods enable a client application to distinguish between schema default values and values occurring explicitly within an instance document.
For example, in po.xsd:
<xsd:complexType name="Items"> <xsd:sequence> <xsd:element name="item" minOccurs="1" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="productName" type="xsd:string"/> <xsd:element name="quantity" default="10"> <xsd:annotation> <xsd:appinfo> <jxb:property generateIsSetMethod="true"/> </xsd:appinfo> </xsd:annotation> ... </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType>
The @generateIsSetMethod applies to the quantity element, which is bound to a property within the Items.ItemType interface. unsetQuantity and isSetQuantity methods are generated in the Items.ItemType interface.
The class tut-install/javaeetutorial5/examples/jaxb/inline-customize/src/inlinecustomize/primer/MyDatatypeConverter, shown below, provides a way to customize the translation of XML data types to and from Java data types by means of a <javaType> customization.
package primer; import java.math.BigInteger; import javax.xml.bind.DatatypeConverter; public class MyDatatypeConverter { public static short parseIntegerToShort(String value) { BigInteger result = DatatypeConverter.parseInteger(value); return (short)(result.intValue()); } public static String printShortToInteger(short value) { BigInteger result = BigInteger.valueOf(value); return DatatypeConverter.printInteger(result); } public static int parseIntegerToInt(String value) { BigInteger result = DatatypeConverter.parseInteger(value); return result.intValue(); } public static String printIntToInteger(int value) { BigInteger result = BigInteger.valueOf(value); return DatatypeConverter.printInteger(result); } };
The following code shows how the MyDatatypeConverter class is referenced in a <javaType> declaration in po.xsd:
<xsd:simpleType name="ZipCodeType"> <xsd:annotation> <xsd:appinfo> <jxb:javaType name="int" parseMethod="primer.MyDatatypeConverter.parseIntegerToInt" printMethod="primer.MyDatatypeConverter.printIntTo Integer" /> </xsd:appinfo> </xsd:annotation> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType>
In this example, the jxb:javaType binding declaration overrides the default JAXB binding of this type to java.math.BigInteger. For the purposes of the Customize Inline example, the restrictions on ZipCodeType (specifically, that legal United States ZIP codes are limited to five digits) make it so all valid values can easily fit within the Java primitive data type int. Note also that, because <jxb:javaType name="int"/> is declared within ZipCodeType, the customization applies to all JAXB properties that reference this simpleType definition, including the getZip and setZip methods.
The Datatype Converter example is very similar to the Customize Inline example. As with the Customize Inline example, the customizations in the Datatype Converter example are made by using inline binding declarations in the XML schema for the application, po.xsd.
The global, schema, and package, and most of the class customizations for the Customize Inline and Datatype Converter examples are identical. Where the Datatype Converter example differs from the Customize Inline example is in the parseMethod and printMethod used for converting XML data to the Java int data type.
Specifically, rather than using methods in the custom MyDataTypeConverter class to perform these data type conversions, the Datatype Converter example uses the built-in methods provided by javax.xml.bind.DatatypeConverter:
<xsd:simpleType name="ZipCodeType"> <xsd:annotation> <xsd:appinfo> <jxb:javaType name="int" parseMethod="javax.xml.bind.DatatypeConverter.parseInt" printMethod="javax.xml.bind.DatatypeConverter.printInt"/> </xsd:appinfo> </xsd:annotation> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType>
Follow these instructions to build and run the Datatype Converter example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the datatypeconverter folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the datatypeconverter project and select Run.
To compile and run the Datatype Converter example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/datatypeconverter/ directory and type the following:
ant runapp |
The following sections provide information about binding declaration files:
All JAXB binding declarations files must begin with:
JAXB version number
Namespace declarations
Schema name and node
The version, namespace, and schema declarations in bindings.xjb are as follows:
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jxb:bindings schemaLocation="po.xsd" node="/xs:schema"> ... binding-declarations ... </jxb:bindings> <!-- schemaLocation="po.xsd" node="/xs:schema" --> </jxb:bindings>
An XML file with a root element of <jaxb:bindings> is considered an external binding file. The root element must specify the JAXB version attribute with which its binding declarations must comply; specifically the root <jxb:bindings> element must contain either a <jxb:version> declaration or a version attribute. By contrast, when making binding declarations inline, the JAXB version number is made as attribute of the <xsd:schema> declaration:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" jxb:version="1.0">
As shown in JAXB Version, Namespace, and Schema Attributes, the namespace declarations in the external binding declarations file include both the JAXB namespace and the XMLSchema namespace. Note that the prefixes used in this example could in fact be anything you want; the important thing is to consistently use whatever prefixes you define here in subsequent declarations in the file.
The fourth line of the code in JAXB Version, Namespace, and Schema Attributes specifies the name of the schema to which this binding declarations file will apply, and the schema node at which the customizations will first take effect. Subsequent binding declarations in this file will reference specific nodes within the schema, but this first declaration should encompass the schema as a whole; for example, in bindings.xjb:
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
The global schema binding declarations in bindings.xjb are the same as those in po.xsd for the Datatype Converter example. The only difference is that because the declarations in po.xsd are made inline, you need to embed them in <xs:appinfo> elements, which are in turn embedded in <xs:annotation> elements. Embedding declarations in this way is unnecessary in the external bindings file.
<jxb:globalBindings fixedAttributeAsConstantProperty="true" collectionType="java.util.Vector" typesafeEnumBase="xs:NCName" choiceContentProperty="false" typesafeEnumMemberName="generateError" bindingStyle="elementBinding" enableFailFastCheck="false" generateIsSetMethod="false" underscoreBinding="asCharInWord"/> <jxb:schemaBindings> <jxb:package name="primer.myPo"> <jxb:javadoc> <![CDATA[<body>Package level documentation for generated package primer.myPo.</body>]]> </jxb:javadoc> </jxb:package> <jxb:nameXmlTransform> <jxb:elementName suffix="Element"/> </jxb:nameXmlTransform> </jxb:schemaBindings>
By comparison, the syntax used in po.xsd for the Datatype Converter example is:
<xsd:annotation> <xsd:appinfo> <jxb:globalBindings ... binding-declarations ... <jxb:schemaBindings> ... binding-declarations ... </jxb:schemaBindings> </xsd:appinfo> </xsd:annotation>
The class-level binding declarations in bindings.xjb differ from the analogous declarations in po.xsd for the Datatype Converter example in two ways:
As with all other binding declarations in bindings.xjb, you do not need to embed your customizations in schema <xsd:appinfo> elements.
You must specify the schema node to which the customization will be applied. The general syntax for this type of declaration is:
<jxb:bindings node="//node-type[@name=’node-name’]">
For example, the following code shows binding declarations for the complexType named USAddress.
<jxb:bindings node="//xs:complexType[@name=’USAddress’]"> <jxb:class> <jxb:javadoc> <![CDATA[First line of documentation for a <b>USAddress</b>.]]> </jxb:javadoc> </jxb:class> <jxb:bindings node=".//xs:element[@name=’name’]"> <jxb:property name="toName"/> </jxb:bindings> <jxb:bindings node=".//xs:element[@name=’zip’]"> <jxb:property name="zipCode"/> </jxb:bindings> </jxb:bindings> <!-- node="//xs:complexType[@name=’USAddress’]" -->
Note in this example that USAddress is the parent of the child elements name and zip, and therefore a </jxb:bindings> tag encloses the bindings declarations for the child elements as well as the class-level javadoc declaration.
The External Customize example is identical to the Datatype Converter example, except that the binding declarations in the External Customize example are made by means of an external binding declarations file rather than inline in the source XML schema.
The binding customization file used in the External Customize example is tut-install/javaeetutorial5/examples/jaxb/external-customize/binding.xjb.
This section compares the customization declarations in bindings.xjb with the analogous declarations used in the XML schema, po.xsd, in the Datatype Converter example. The two sets of declarations achieve precisely the same results.
Follow these instructions to build and run the External Customize example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the external-customize folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the external-customize project and select Run.
To compile and run the External Customize example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/external-customize/ directory and type the following:
ant runapp |
The Java-to-Schema examples show how to use annotations to map Java classes to XML schema.
If you are using JDK 6, perform the following steps before you run any of the Java-to-Schema examples:
Change to one of the Java-to-Schema example directories (for example, tut-install/javaeetutorial5/examples/jaxb/j2s-create-marshal.
Run the following Ant command:
ant update-endorsed |
This command creates an endorsed directory in the JDK and copies the webservices-api.jar file from the Application Server's lib/endorsed/ directory into it.
The Create Marshal example illustrates Java-to-schema databinding. It demonstrates marshalling and unmarshalling of JAXB annotated classes and also shows how to enable JAXP 1.3 validation at unmarshal time using a schema file that was generated from the JAXB mapped classes.
The schema file, bc.xsd, was generated with the following commands:
schemagen src/cardfile/*.java cp schema1.xsd bc.xsd |
Note that schema1.xsd, was copied to bc.xsd; schemagen does not allow you to specify a schema name of your choice.
Follow these instructions to build and run the Create Marshal example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-create-marshal folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-create-marshal project and select Run.
To compile and run the Create Marshal example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-create-marshal/ directory and type the following:
ant runapp |
The j2s-xmlAccessorOrder example shows how to use the @XmlAccessorOrder and @XmlType.propOrder annotations to dictate the order in which XML content is marshalled/unmarshalled by a Java type.
With Java-to-schema mapping, a JavaBean’s properties and fields are mapped to an XML Schema type. The class elements are mapped to either an XML Schema complex type or an XML Schema simple type. The default element order for a generated schema type is currently unspecified because Java reflection does not impose a return order. The lack of reliable element ordering negatively impacts application portability. You can use two annotations, @XmlAccessorOrder and @XmlType.propOrder, to define schema element ordering for applications that need to be portable across JAXB Providers.
The @XmlAccessorOrder annotation imposes one of two element ordering algorithms, AccessorOrder.UNDEFINED or AccessorOrder.ALPHABETICAL. AccessorOrder.UNDEFINED is the default setting. The order is dependent on the system’s reflection implementation. AccessorOrder.ALPHABETICAL orders the elements in lexicographic order as determined by java.lang.String.CompareTo(String anotherString).
You can define the @XmlAccessorOrder annotation for annotation type ElementType.PACKAGE on a class object. When the @XmlAccessorOrder annotation is defined on a package, the scope of the formatting rule is active for every class in the package. When defined on a class, the rule is active on the contents of that class.
There can be multiple @XmlAccessorOrder annotations within a package. The order of precedence is the innermost (class) annotation takes precedence over the outer annotation. For example, if @XmlAccessorOrder(AccessorOrder.ALPHABETICAL) is defined on a package and @XmlAccessorOrder(AccessorOrder.UNDEFINED) is defined on a class in that package, the contents of the generated schema type for the class would be in an unspecified order and the contents of the generated schema type for every other class in the package would be alphabetical order.
The @XmlType annotation can be defined for a class. The annotation element propOrder() in the @XmlType annotation allows you to specify the content order in the generated schema type. When you use the @XmlType.propOrder annotation on a class to specify content order, all public properties and public fields in the class must be specified in the parameter list. Any public property or field that you want to keep out of the parameter list must be annotated with @XmlAttribute or @XmlTransient annotation.
The default content order for @XmlType.propOrder is {} or {""}, not active. In such cases, the active @XmlAccessorOrder annotation takes precedence. When class content order is specified by the @XmlType.propOrder annotation, it takes precedence over any active @XmlAccessorOrder annotation on the class or package. If the @XmlAccessorOrder and @XmlType.propOrder(A, B, ...) annotations are specified on a class, the propOrder always takes precedence regardless of the order of the annotation statements. For example, in the code below, the @XmlAccessorOrder annotation precedes the @XmlType.propOrder annotation.
@XmlAccessorOrder(AccessorOrder.ALPHABETICAL) @XmlType(propOrder={"name", "city"}) public class USAddress { . . public String getCity() {return city;} public void setCity(String city) {this.city = city;} public String getName() {return name;} public void setName(String name) {this.name = name;} . . }
In the code below, the @XmlType.propOrder annotation precedes the @XmlAccessorOrder annotation.
@XmlType(propOrder={"name", "city"}) @XmlAccessorOrder(AccessorOrder.ALPHABETICAL) public class USAddress { . . public String getCity() {return city;} public void setCity(String city) {this.city = city;} public String getName() {return name;} public void setName(String name) {this.name = name;} . . }
In both scenarios, propOrder takes precedence and the identical schema content shown below will be generated.
<xs:complexType name="usAddress"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0"/> <xs:element name="city" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType>
The purchase order code example demonstrates the effects of schema content ordering using the @XmlAccessorOrder annotation at the package and class level, and the @XmlType.propOrder annotation on a class.
Class package-info.java defines @XmlAccessorOrder to be ALPHABETICAL for the package. The public fields shipTo and billTo in class PurchaseOrderType will be affected in the generated schema content order by this rule. Class USAddress defines the @XmlType.propOrder annotation on the class. User of this annotation demonstrates user-defined property order superseding ALPHABETICAL order in the generated schema.
The generated schema file can be found in the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlAccessorOrder/build/schemas/ directory.
Follow these instructions to build and run the XmlAccessorOrder example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlAccessorOrder folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlAccessorOrder project and select Run.
To compile and run the XmlAccessorOrder example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlAccessorOrder/ directory and type the following:
ant runapp |
The XmlAdapter Field example demonstrates how to use the XmlAdapter interface and the @XmlJavaTypeAdapter annotation to provide a custom mapping of XML content into and out of a HashMap (field) that uses an int as the key and a String as the value.
Interface XmlAdapter and annotation @XmlJavaTypeAdapter are used for special processing of data types during unmarshalling/marshalling. There are a variety of XML data types for which the representation does not map easily into Java (for example, xs:DateTime and xs:Duration), and Java types which do not map conveniently into XML representations, for example implementations of java.util.Collection (such as List) and java.util.Map (such as HashMap) or for non-JavaBean classes.
The XmlAdapter interface and the @XmlJavaTypeAdapter annotation are provided for cases such as these. This combination provides a portable mechanism for reading/writing XML content into and out of Java applications.
The XmlAdapter interface defines the methods for data reading/writing.
/* * ValueType - Java class that provides an XML representation * of the data. It is the object that is used for * marshalling and unmarshalling. * * BoundType - Java class that is used to process XML content. */ public abstract class XmlAdapter<ValueType,BoundType> { // Do-nothing constructor for the derived classes. protected XmlAdapter() {} // Convert a value type to a bound type. public abstract BoundType unmarshal(ValueType v); // Convert a bound type to a value type. public abstract ValueType marshal(BoundType v); }
You can use the @XmlJavaTypeAdapter annotation to associate a particular XmlAdapter implementation with a Target type, PACKAGE, FIELD, METHOD, TYPE, or PARAMETER.
The XmlAdapter Field example shows how to use an XmlAdapter for mapping XML content into and out of a (custom) HashMap. The HashMap object, basket, in class KitchenWorldBasket, uses a key of type int and a value of type String. These data types should be reflected in the XML content that is read and written, so the XML content should look like this.
<basket> <entry key="9027">glasstop stove in black</entry> <entry key="288">wooden spoon</entry> </basket>
The default schema generated for Java type HashMap does not reflect the desired format.
<xs:element name="basket"> <xs:complexType> <xs:sequence> <xs:element name="entry" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="key" minOccurs="0" type="xs:anyType"/> <xs:element name="value" minOccurs="0" type="xs:anyType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element>
In the default HashMap schema, key and value are both elements and are of data type anyType. The XML content will look like this:
<basket> <entry> <key>9027</> <value>glasstop stove in black</> </entry> <entry> <key>288</> <value>wooden spoon</> </entry> </basket>
To resolve this issue, the example uses two Java classes, PurchaseList and PartEntry, that reflect the needed schema format for unmarshalling/marshalling the content. The XML schema generated for these classes is as follows:
<xs:complexType name="PurchaseListType"> <xs:sequence> <xs:element name="entry" type="partEntry" nillable="true" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="partEntry"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="key" type="xs:int" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType>
Class AdapterPurchaseListToHashMap implements the XmlAdapter interface. In class KitchenWorldBasket, the @XmlJavaTypeAdapter annotation is used to pair AdapterPurchaseListToHashMap with field HashMap basket. This pairing will cause the marshal/unmarshal method of AdapterPurchaseListToHashMap to be called for any corresponding marshal/unmarshal action on KitchenWorldBasket.
Follow these instructions to build and run the XmlAdapter Field example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlAdapter-field folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlAdapter-field project and select Run.
To compile and run the XmlAdapter Field example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlAdapter-field/ directory and type the following:
ant runapp |
The XmlAttribute Field example shows how to use the @XmlAttribute annotation to define a property or field to be treated as an XML attribute.
The @XmlAttribute annotation maps a field or JavaBean property to an XML attribute. The following rules are imposed:
A static final field is mapped to a XML fixed attribute.
When the field or property is a collection type, the items of the collection type must map to a schema simple type.
When the field or property is other than a collection type, the type must map to a schema simple type.
When following the JavaBean programming paradigm, a property is defined by a get and set prefix on a field name.
int zip; public int getZip(){return zip;} public void setZip(int z){zip=z;}
Within a bean class, you have the choice of setting the @XmlAttribute annotation on one of three components: the field, the setter method, or the getter method. If you set the @XmlAttribute annotation on the field, the setter method will need to be renamed or there will be a naming conflict at compile time. If you set the @XmlAttribute annotation on one of the methods, it must be set on either the setter or getter method, but not on both.
The XmlAttribute Field example shows how to use the @XmlAttribute annotation on a static final field, on a field rather than on one of the corresponding bean methods, on a bean property (method), and on a field that is other than a collection type. In class USAddress, fields, country, and zip are tagged as attributes. The setZip method was disabled to avoid the compile error. Property state was tagged as an attribute on the setter method. You could have used the getter method instead. In class PurchaseOrderType, field cCardVendor is a non-collection type. It meets the requirement of being a simple type; it is an enum type.
Follow these instructions to build and run the XmlAttribute Field example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlAttribute-field folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlAttribute-field project and select Run.
To compile and run the XmlAttribute Field example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlAttribute-field/ directory and type the following:
ant runapp |
The XmlRootElement example demonstrates the use of the @XmlRootElement annotation to define an XML element name for the XML schema type of the corresponding class.
The @XmlRootElement annotation maps a class or an enum type to an XML element. At least one element definition is needed for each top-level Java type used for unmarshalling/marshalling. If there is no element definition, there is no starting location for XML content processing.
The @XmlRootElement annotation uses the class name as the default element name. You can change the default name by using the annotation attribute name. If you do, the specified name will then be used as the element name and the type name. It is common schema practice for the element and type names to be different. You can use the @XmlType annotation to set the element type name.
The namespace attribute of the @XmlRootElement annotation is used to define a namespace for the element.
Follow these instructions to build and run the XmlRootElement example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlRootElement folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlRootElement project and select Run.
To compile and run the XmlRootElement example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlRootElement/ directory and type the following:
ant runapp |
The XmlSchemaType Class example demonstrates the use of the annotation @XmlSchemaType to customize the mapping of a property or field to an XML built-in type.
The @XmlSchemaType annotation can be used to map a Java type to one of the XML built-in types. This annotation is most useful in mapping a Java type to one of the nine date/time primitive data types.
When the @XmlSchemaType annotation is defined at the package level, the identification requires both the XML built-in type name and the corresponding Java type class. An @XmlSchemaType definition on a field or property takes precedence over a package definition.
The XmlSchemaType Class example shows how to use the @XmlSchemaType annotation at the package level, on a field, and on a property. File TrackingOrder has two fields, orderDate and deliveryDate, which are defined to be of type XMLGregorianCalendar. The generated schema will define these elements to be of XML built-in type gMonthDay. This relationship was defined on the package in the file package-info.java. Field shipDate in file TrackingOrder is also defined to be of type XMLGregorianCalendar, but the @XmlSchemaType annotation statements override the package definition and specify the field to be of type date. Property method getTrackingDuration defines the schema element to be defined as primitive type duration and not Java type String.
Follow these instructions to build and run the XmlSchemaType Class example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlSchemaType-class folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlSchemaType-class project and select Run.
To compile and run the XmlSchemaType Class example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlSchemaType-class/ directory and type the following:
ant runapp |
The XmlType example demonstrates the use of the @XmlType annotation. The @XmlType annotation maps a class or an enum type to a XML Schema type.
A class must have either a public zero-argument constructor or a static zero-argument factory method in order to be mapped by this annotation. One of these methods is used during unmarshalling to create an instance of the class. The factory method may reside within in a factory class or the existing class.
There is an order of precedence as to which method is used for unmarshalling:
If a factory class is identified in the annotation, a corresponding factory method in that class must also be identified and that method will be used.
If a factory method is identified in the annotation but no factory class is identified, the factory method must reside in the current class. The factory method is used even if there is a public zero arg constructor method present.
If no factory method is identified in the annotation, the class must contain a public zero arg constructor method.
In this example, a factory class provides zero arg factory methods for several classes. The @XmlType annotation on class OrderContext references the factory class. The unmarshaller will use the identified factory method in this class.
public class OrderFormsFactory { public OrderContext newOrderInstance() { return new OrderContext() } public PurchaseOrderType newPurchaseOrderType() { return new newPurchaseOrderType(); } } @XmlType(name="oContext", factoryClass="OrderFormsFactory", factoryMethod="newOrderInstance") public class OrderContext { public OrderContext(){ ..... } }
In this example, a factory method is defined in a class, which also contains a standard class construct. Because the factoryMethod value is defined and no factoryClass is defined, the factory method newOrderInstance is used during unmarshalling.
@XmlType(name="oContext", factoryMethod="newOrderInstance") public class OrderContext { public OrderContext(){ ..... } public OrderContext newOrderInstance() { return new OrderContext(); } }
Follow these instructions to build and run the XmlType example on your Application Server instance using the NetBeans IDE.
In NetBeans IDE, select File->Open Project.
In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.
Select the j2s-xmlType folder.
Select the Open as Main Project check box.
Click Open Project.
Right-click the j2s-xmlType project and select Run.
To compile and run the XmlType example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/j2s-xmlType/ directory and type the following:
ant runapp |
For more information about JAXB, XML, and XML Schema, see:
Java Community Process page:
W3C Recommendation “Extensible Markup Language (XML) 1.0”:
XML Information Set:
W3C XML Schema Part 0: Primer, edited by David C. Fallside:
XML Path Language, edited by James Clark and Steve DeRose: