java left logo
java middle logo
java right logo
 

Home arrow Java EE Tips arrow Java Architecture for XML Binding arrow What is New in JAXB 2.0
 
 
Main Menu
Home
Java Tutorials
Book Reviews
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Java Network
Java Forums
Java Blog




Most Visited Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews
Top Rated Tips
Java SE Tips
Java ME Tips
Java EE Tips
Other API Tips
Java Applications
Java Libraries
Java Games
Book Reviews


Statistics
Registered Users: 4095
Java SE Tips: 614
Java ME Tips: 202
Java EE Tips: 183
Other API Tips: 779
Java Applications: 298
Java Libraries: 209
Java Games: 16
Book Reviews:
 
 
 
What is New in JAXB 2.0 E-mail
User Rating: / 70
PoorBest 

This Tech Tip reprinted with permission by java.sun.com

Java Architecture for XML Binding, JAXB, is a technology that simplifies the use of XML content in Java programming language applications. JAXB does this by specifying a binding between an XML document and JavaBeans technology components, based on the XML document's XSD schema. Previous Enterprise Java Technologies Tech Tips covered XML Serialization with JAXB and using JAXB with RelaxNG. Both tips used JAXB 1.0, which is packaged with the Java Web Services Developer Pack (Java WSDP) 1.6.

JAXB 2.0, JSR 222, includes a number of important improvements to JAXB 1.0. Some of these are:

  • Support for all W3C XML Schema features. JAXB 1.0 did not specify bindings for some of the W3C XML Schema features.This support will be fully provided in the FCS release, but is not yet complete in the current Early Access release.
  • 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 tip demonstrates two of these improvements: validation (as a part of marshalling and unmarshalling) using the JAXP validation APIs, and Java-to-Schema binding.

You'll find the example code for this tip in a downloadable archive. To run the examples, you'll need the most current Early Access 3 version of the JAXB 2.0 Reference Implementation. The Early Access 3 version of the JAXB 2.0 Reference Implementation is also packaged in Java WSDP 2.0.

Unmarshalling and Marshalling with the JAXP 1.3 Validation Schema

One of the enhancements in JAXB 2.0 is the additional validation capabilities provided through the use of the JAXP 1.3 validation APIs. Let's examine this by looking at unmarshalling and marshalling in JAXB 2.0 using the JAXP 1.3 validation schema. Using JAXB, a Java application can unmarshal an XML instance document into Java content objects, optionally validating the source XML document before generating the Java content objects. A Java application can also use JAXB to marshal Java content objects into XML instance documents.

Before an XML document can be unmarshalled, you need to bind the schema for the XML document into a set of Java interfaces and classes that represents the schema. You then compile the interfaces and classes. The example in this tip uses a purchase order schema, po.xsd. This is the same schema that is used in the JAXB samples packaged in Java WSDP 1.6. The JAXB samples are described in the Java Web Services Developer Pack 1.6 Tutorial. If you examine the po.xsd schema, note especially the restrictions specified for the quantity element and the partNum attribute:

   <xsd:element name="quantity">
      <xsd:simpleType>
      <xsd:restriction base="xsd:positiveInteger">
         <xsd:maxExclusive value="100"/>
       </xsd:restriction>
              
      <xsd:attribute name="partNum" type="SKU" 
        use="required"/>

The quantity cannot exceed 100 and the part number must have an SKU type.

As is the case in JAXB 1.0, you bind the schema in JAXB 2.0 using the XML binding compiler (xjc). You then compile the generated interfaces and classes using the javac command. In the example archive, the binding and compilation steps are provided as ant tasks in a build file, build.xml.

After binding and compiling, you can unmarshal the XML document. The XML document used in this tip, po.xml, is a purchase order document that contains some information that violates the restrictions specified in the po.xsd schema. In particular, one of the items in the purchase order specifies a quantity greater than 100 and a partNum attribute that does not correspond to the type SKU.

     <item partNum="002" >
        <productName>Reliving the Ordeal</productName>
        <quantity>150</quantity>
        <USPrice>11.99</USPrice>
     </item>

Unmarshalling in JAXB 2.0 is much the same as unmarshalling in JAXB 1.0. You first create a JAXBContext object that provides an entry point to the JAXB API. Then you create an Unmarshaller object that controls the process of unmarshalling.

   JAXBContext jc = JAXBContext.newInstance"techtip" );
   Umarshaller u = jc.createUnmarshaller();  

Where JAXB 2.0 differs from JAXB 1.0 in the unmarshalling process is validation. In JAXB 1.0 you could validate source data against an associated schema as part of the unmarshalling process by specifying:

   unmarshaller.setValidating(true);

Validation capabilities have been expanded in JAXB 2.0 through the use of the JAXP 1.3 Schema Validation Framework. To use this enhanced level of validation, you first create an instance of the SchemaFactory for the W3C XML Schema 1.0 language:

   SchemaFactory sf = SchemaFactory.newInstance(
      javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);

The SchemaFactory instance is used to create a new JAXP 1.3 Schema object:

   Schema schema = sf.newSchema(new File("po.xsd"));

Then you use the setSchema method to identify the JAXP 1.3 Schema object (in this case, the po.xsd) that should be used to validate subsequent unmarshal operations. If you pass null into this method, it disables validation.

   u.setSchema(schema);

The application has the option of customizing validation error handling by overriding the default event handler. It does this using the method call setEventHandler(ValidationEventHandler).

The previous approach to unmarshalling by JAXB 1.0, called "structural unmarshalling", is more rigid in regard to invalid XML content. If JAXB 1.0 detects a structural inconsistency that it is unable to recover from, it aborts the unmarshal process and throws an UnmarshalException. For example, it can rigidly give up unmarshalling if it encounters an unexpected element or attribute.

JAXB 2.0, by comparison, allows for more flexible unmarshalling. Flexible unmarshalling enables greater predictability in unmarshalling invalid XML content. JAXB 2.0 unmarshals xml content by element name, rather than strictly by the position of the element within a content model.

Here is how to specify your own custom event handler:

   u.setEventHandler(new DefaultValidationEventHandler())

The custom validation event handler must implement the ValidationEventHandler interface and the method handleEvent. The boolean return value should be set to true if the JAXB Provider attempts to continue the current unmarshal, validate, or marshal operation after handling this warning or error. The return value should be set to false if the provider terminates the current operation with the appropriate UnmarshalException, ValidationException, or MarshalException. Note that the default ValidationHandler in JAXB 2.0 always returns true (provided that the handleEvent is not overridden). Here is an example of a custom event handler:

   public class MyValidationEventHandler implements 
    ValidationEventHandler{
     
      public boolean handleEvent(ValidationEvent ve) {            
        if (ve.getSeverity()==ve.FATAL_ERROR ||  
                               ve .getSeverity()==ve.ERROR){
            ValidationEventLocator  locator = ve.getLocator();
            //print message from valdation event
            System.out.println("Message is " + ve.getMessage());
            //output line and column number
            System.out.println("Column is " 
                  locator.getColumnNumber() 
                  " at line number " + locator.getLineNumber());
         }
         return true;
       }
    
   }

The JAXB specification mandates that all provider implementations report validation errors when errors are encountered. However, the implementation does not have to stop processing the data. A JAXB implementation can successfully unmarshal an invalid XML document even if the XML document is not valid.

After po.xml is unmarshalled, you can manipulate the marshalled objects like any other Java objects. For example, to display the shipTo address, do the following:

   JAXBElement<?> poElement = 
   JAXBElement<?>)u.unmarshal
      new FileInputStream"po.xml" ) );
   PurchaseOrderType po = (
      PurchaseOrderType)poElement.getValue();
   USAddress address = po.getShipTo();   

To marshal content back to an XML file, you perform the same steps as in JAXB 1.0. After creating a JAXBContext object (as shown earlier for unmarshalling), you create a Marshaller object that controls the process of marshalling. The following code snippet, for example, creates a Marshaller to marshal content to a file named incorrectpo.xml:

   Marshaller m = jc.createMarshaller();
        m.setPropertyMarshaller.JAXB_FORMATTED_OUTPUT, 
              Boolean.TRUE );
        OutputStream os = new FileOutputStream
              "incorrectpo.xml" );
        m.marshal(po, os);

The property JAXB.FORMATTED.OUTPUT controls whether the Marshaller formats the resulting XML data with line breaks and indentation.

Although not shown in the example code for this tip, JAXB 2.0 supports validation at marshal time (as well as at unmarshal time). JAXB 1.0 provided for validation only at unmarshal time, and also supported on-demand validation of a JAXB content tree. Marshal-time validation was added because of web services. A web service processing model should be lax in reading in data, and strict when writing it out. To meet that model, JAXB 2.0 added marshal-time validation to ensure that users do not invalidate an xml document if they modify the document in JAXB form.

Generating XML from Java Classes with Java-to-Schema Binding

As mentioned previously, JAXB 1.0 specified the mapping of XML Schema-to-Java, but not the mapping of Java-to-XML Schema. JAXB 2.0 completes this by specifying the mapping from Java-to-XML Schema. In addition, JAXB 2.0 relies on the use of annotations as specified in "A Metadata Facility for the Java Programming Language", JSR 175, to control this binding.

This tip demonstrates how to use JAXB 2.0 to generate an XML file from existing Java classes and then printing the contents of the generated XML file to the console. The two classes used are Scientist and Person, where the Person object is encapsulated in the Scientist object.

A class maps to either an XML Schema complex type or an XML Schema simple type. The XML Schema type is derived based on the mapping of JavaBean properties and fields contained in the class. In JAXB 2.0, annotations are used to specify to the Java-to-Schema binding framework how to treat the Java classes. The annotation @Xmltype is used for a top-level value class, mapping it to a complex schema type:

   @XmlType       
   public class Person  {
            
      private String name;
       private int age;
   .....

When a top-level class is annotated with the @XmlRootElement annotation, the value of the class is represented as an XML root element in an XML document:

   @XmlRootElement
        
   public class Scientist  {
    
       private Person person;    
       private String researchInstitute; 
       private Collection publications;
   ...

These annotations specify that the Scientist object is the root element, and the Person object is of Xmltype. There are many other annotation types defined including XmlAttribute, XmlElement, and XmlSchema. The full list is available in the javax.xml.bind.annotation API documentation.

The annotations and default mapping are designed to enable the classes to be mapped to schema with minimal changes to existing code. The default mapping is specified in terms of default annotations that are considered to apply to a program element even if the annotations are not specified. For more detail, see section 8.12 in the final JAXB 2.0 specification. In the code example for this tip, the class Person does need not be annotated with @XmlType. Without the annotation, the JavaBeans object is still mapped to the correct type (you can test this by commenting out the annotation). You should specify a customizing annotation when the default binding is not sufficient. For example, you should use @XmlAttribute to specify a customizing annotation for the default binding of a field or property to an attribute.

With the Java-to-XML Schema mapping in place, you can marshal Java objects without providing an XMLSchema. First create a JavaContext object, specifying the pertinent context path. In this example, the Scientist Java object (which requires the creation of a Person object) provides the context path. Then you pass the JavaContext object to the marshaller.

   JAXBContext context = 
      JAXBContext.newInstance(Scientist.class);
   Marshaller m = context.createMarshaller();
   m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

After creating the necessary Scientist and Person objects with appropriate properties, you can perform any operation using the marshalled XML file. For example you can print the XML contents to the console:

   Scientist scientist = js.getScientist();
   m.marshal(scientist, System.out);

For more information about JAXB 2.0, see the JAXB 2.0 project page.

Running the Sample Code

A sample package accompanies this tip that demonstrates the techniques covered in the tip. To install and run the sample:

  1. If you don't have Java 2 Platform, Standard Edition (J2SE) 5.0 installed, download and install it from the J2SE 5.0 downloads page. JAXB 2.0 requires J2SE 5.0 because it uses some of the new language features in J2SE 5.0 such as annotations.
  2. Download and install latest JAXB 2.0 bundle from JAXB 2.0 Project downloads page.
  3. Download the sample archive for the tip. Extract the downloaded archive contents to the <JAXB_RI>/samples directory, where <JAXB_RI> is the directory where you installed JAXB 2.0 RI EA 3. You should now see the newly extracted directory as <JAXB_RI>/samples/techtip. For example, if you installed the EA3 release on a Windows machine at C:\Sun\, then your newly created directory should be at C:\Sun\jaxb-ri-20050622\samples\techtip.
  4. It is important to extract this zip file to this directory because build.xml file for the tip depends on the directory structure defined in the JAXB 2.0 EA3 bundle. The classpath and execute properties are already defined in the build.xml file, so that you can compile and execute the appropriate targets.

    To execute the unmarshalling and marshalling example, perform the following steps:

  5. Navigate to the <JAXB_RI>/samples/techtip directory, and execute the following command:
  6.             ant compile
    

    This generates and compiles the Java classes from the po.xsd schema, and the example Java classes. Note that there is no ant binary packaged with JAXB 2.0 package. If you have Java WSDP 1.6 installed, you can use the ant binary located in the <JWSDP_HOME>/apache-ant/bin directory (where is where you installed Java WSDP 1.6). Or you can download ant from the apache web site.

  7. Unmarshal the po.xml document, validating it with the JAXP 1.3 Schema Validation Framework, and then marshal it. To do that, execute the following command:
  8.        
                ant run-validate
    

    The marshalling operation will generate the incorrectpo.xml file. The output should include the following:

               Message is cvc-type.3.1.3: The value '150' of element 
               'quantity' is not valid.
               Column is 31 at line number 28
                  Bugsy Brown
                  99 9th Avenue
                  New York, NY 12345
                  US
    
    

    Still able to marshal invalid document

    To execute the Java to Schema binding example, execute the following command:

             ant run-javaToSchema 
    

    The output should include the following:

             <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
             <scientist>
                 <person>
                     <name>Linus Pauling</name>
                     <age>93</age>
                     <sex>Male</sex>
                 </person>
                 <publications xmlns:
                 xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                 xsi:type="xs:string">Respect for vitamin C
                 </publications>
                 <publications xmlns:
                 xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                 xsi:type="xs:string">The Nature of the Chemical Bond
                 </publications>
             </scientist>

About the Author

Kim LiChong is a Member of Technical Staff in the Java Web Services Performance Engineering Group at Sun Microsystems. His interests include XML parsing performance, and is one of the authors of the StAX 1.0 White Paper: Streaming APIs for XML Parsers. He also is a co-owner of xmltest, a microbenchmark used to measure XML parsing performance. For more information about xmltest, see the xmltest project page.

Copyright (c) 2004-2005 Sun Microsystems, Inc.
All Rights Reserved.


 Related Tips

 

Page 1 of 0 ( 0 comments )

You can share your information about this topic using the form below!

Please do not post your questions with this form! Thanks.


Name (required)


E-Mail (required)

Your email will not be displayed on the site - only to our administrator
Homepage(optional)



Comment Enable HTML code : Yes No



 
       
         
     
 
 
 
   
 
 
java bottom left
java bottom middle
java bottom right
RSS 0.91 FeedRSS 1.0 FeedRSS 2.0 FeedATOM FeedOPML Feed

Home - About Us - Privacy Policy
Copyright 2005 - 2008 www.java-tips.org
Java is a trademark of Sun Microsystems, Inc.