Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
html
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export...
Sponsored by:
JAXB prerequisites
To get started with JAXB 2.0 you need: Java Platform, Standard Edition 5: JAXB 2.0 relies heavily on features of Java SE 5, such as annotations and generics An implementation of JAXB 2.0 This article was written using the GlassFish JAXB reference implementation release candidate.
The corresponding XML schema describes how the training course is booked, and contains details of the booked course, the enrolled students, the company making the booking, and so forth. An XML schema description is extremely rigorous and can include details such as the number of elements allowed in a list of objects (cardinality), optional and mandatory attributes, and more. The schema for the training course bookings (called course-booking.xsd) is shown here:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="booking" type="courseBooking"/> <xsd:complexType name="courseBooking"> <xsd:sequence> <xsd:element ref="company" /> <xsd:element ref="student" minOccurs="1" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="courseReference" type="xsd:string" use="required"/> <xsd:attribute name="courseDate" type="xsd:date" use="required"/> <xsd:attribute name="invoiceReference" type="xsd:string" use="required"/> <xsd:attribute name="totalPrice" type="xsd:decimal" use="required"/> </xsd:complexType> <xsd:element name="student" type="studentType"/> <xsd:complexType name="studentType"> <xsd:attribute name="firstName" type="xsd:string" use="required"/> <xsd:attribute name="surname" type="xsd:string" use="required"/> </xsd:complexType> <xsd:element name="company" type="companyType"/> <xsd:complexType name="companyType"> <xsd:sequence> <xsd:element name="address"/> <xsd:element ref="contact" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string"/> </xsd:complexType> <xsd:element name="contact" type="contactType"/> <xsd:complexType name="contactType"> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="telephone" type="xsd:string" use="required"/> <xsd:attribute name="email" type="xsd:string" use="required"/> </xsd:complexType> </xsd:schema>
1 of 4
2/14/2013 8:58 AM
http://www.javaworld.com/javaworld/jw-06-2006/jw-0626-jaxb.html
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export...
The command line tool xjc runs the JAXB compiler. To run the JAXB compiler against our schema, we run the following command:
$xjc course-booking.xsd -p nz.co.equinox.training.domain.booking -d src/generated
This will generate a set of Java classes annotated with JAXB 2.0 annotations. Some of the more useful options are described here:
-d <dir>: Place the generated files into this directory. -p <package>: Place the generated files in this package. -nv: Don't perform strict validation of the input schema. -httpproxy <proxy>: Use this if you are behind a proxy. Takes the format [user[:password]@]proxyHost[:proxyPort]. -classpath <arg>: Specify the classpath, if necessary. -readOnly: Generates read-only source code files, if your OS supports this.
There is also an equivalent ant task, which makes it quite easy to integrate into an Ant or Maven-based build process. The list of generated classes is shown here:
CompanyType.java ContactType.java CourseBooking.java ObjectFactory.java StudentType.java
Users of previous versions of JAXB may notice that this is a slick set of annotated and fully documented Java classes, rather than the more cumbersome set of interfaces and implementations of previous versions. Thus, we have less generated classes, and lighter and more elegant code. And, as you will see in the next section, manipulating these classes is easy.
To unmarshall an XML document, you create an Unmarshaller from the context, as shown here:
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
The unmarshaller can process XML data from a wide variety of data sources: files, input streams, URLs, DOM objects, SAX parsers, and more. Here we provide a simple File object pointing to our XML document. The unmarshaller returns a typed JAXBElement, from which we can obtain our unmarshalled object by using the getValue() method:
JAXBElement<CourseBooking> bookingElement = (JAXBElement<CourseBooking>) unmarshaller.unmarshal( new File("src/test/resources/xml/booking.xml"));
Document validation
Document validation is the process of ensuring your XML document corresponds to the definition given in the corresponding XML schema. It is an important aspect of any project involving XML exchanges, especially if the XML comes from other systems. Document validation in JAXB 2.0 is easier and more flexible than in previous versions. You can simply attach a ValidatonEventHandler to the unmarshaller before unmarshalling the XML document, as shown here:
unmarshaller.setEventHandler(new BookingValidationEventHandler());
A validation event handler implements the ValidationEventHandler interface and the handleEvent() method, as shown here:
public class BookingValidationEventHandler implements ValidationEventHandler{
if (ve.getSeverity()==ValidationEvent.FATAL_ERROR || ve .getSeverity()==ValidationEvent.ERROR){ ValidationEventLocator locator = ve.getLocator(); //Print message from valdation event System.out.println("Invalid booking document: " + locator.getURL()); System.out.println("Error: " + ve.getMessage()); //Output line and column number System.out.println("Error at column " + locator.getColumnNumber() + ", line " + locator.getLineNumber()); } return true; } }
2 of 4
2/14/2013 8:58 AM
http://www.javaworld.com/javaworld/jw-06-2006/jw-0626-jaxb.html
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export...
Here we just print details of the error, but in a real application, some less trivial treatment might be appropriate. In some cases, you may even consider that the validation error is not a show-stopper and that it will not block the processing. By returning true, you tell the unmarshaller to continue the unmarshalling process: false would terminate the process with an appropriate exception.
Marshalling a document
Marshalling involves transforming your Java classes into XML format. In JAXB 2.0, creating and manipulating these Java classes is simple. In most cases, you can just treat them like ordinary Java classes, as shown here:
CourseBooking booking = new CourseBooking(); booking.setCourseReference("UML-101"); booking.setTotalPrice(new BigDecimal(10000)); ...
Note that you can still use the ObjectFactory class similarly to how you used it in JAXB 1.0, as shown in the following listing. However, unlike JAXB 1.0, there are no interfaces or implementation classes: all domain objects are just annotated JavaBeans components.
ObjectFactory factory = new ObjectFactory(); CourseBooking booking = factory.createCourseBooking(); ...
Although most XML data types map directly to normal Java classes, some special treatment is needed for certain data types, such as dates. In these cases, you must use the DatatypeFactory, as shown here:
DatatypeFactory datatypes = DatatypeFactory.newInstance(); booking.setCourseDate(datatypes.newXMLGregorianCalendarDate(2006,06,15,0));
Once your domain object is initialized, use the JAXB context to create a Marshaller object and a typed JAXBElement. Creating the marshaller is simple:
Marshaller marshaller = jaxbContext.createMarshaller();
Next, you create a JAXBElement object that encapsulates your domain object. The typed JAXBElement corresponds to the root element complexType of your XML document. Then use the generated ObjectFactory class as follows:
JAXBElement<CourseBooking> bookingElement = (new ObjectFactory()).createBooking(booking);
In this example, we set a property so that the output will be formatted for human use and then write to standard output:
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal( bookingElement, System.out );
CourseBooking booking = new CourseBooking(); booking.setCourseReference("UML-101"); booking.setTotalPrice(new BigDecimal(10000)); booking.setInvoiceReference("123456"); DatatypeFactory datatypes = DatatypeFactory.newInstance(); booking.setCourseDate(datatypes.newXMLGregorianCalendarDate(2006,06,15,0)); booking.setTotalPrice(new BigDecimal(10000)); booking.setInvoiceReference("123456"); booking.getStudent().add(new StudentType()); booking.getStudent().get(0).setFirstName("John"); booking.getStudent().get(0).setSurname("Smith"); booking.setCompany(new CompanyType()); booking.getCompany().setName("Clients inc."); booking.getCompany().setContact(new ContactType()); booking.getCompany().getContact().setName("Paul"); booking.getCompany().getContact().setEmail("paul@clients.inc"); booking.getCompany().getContact().setTelephone("12345678"); booking.getCompany().setAddress("10 client street");
// Marshal to System.out Marshaller marshaller = jaxbContext.createMarshaller(); JAXBElement<CourseBooking> bookingElement = (new ObjectFactory()).createBooking(booking); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
3 of 4
2/14/2013 8:58 AM
http://www.javaworld.com/javaworld/jw-06-2006/jw-0626-jaxb.html
http://www.javaworld.com/cgi-bin/mailto/x_java.cgi?pagetosend=/export...
Conclusion
JAXB is a powerful tool for integrating XML into a Java application. With full XML Schema support, more flexible validation, and simpler, cleaner generated classes, JAXB 2.0 is even better and goes a long way towards a seamless integration of XML in Java.
4 of 4
2/14/2013 8:58 AM