One aspect of validation-unmarshall-time validation-has already been discussed in preceding sections. In this section, we will discuss another aspect of validation: on-demand validation. At times, developers may need to validate partial (or even complete) content trees. For example, it may be useful to validate only the Billingaddress object when user input is accepted, or, alternatively, the entire Purchaseorder and all the referenced objects against the XML schema when needed.
JAXB defines the javax.xml.bind.Validator interface for this purpose. Once the reference to this is obtained, an event handler can be set if needed and the relevant object passed for validation:
JAXBContext context = JAXBContext.newInstance( "com.flutebank.schema" ); // create an Unmarshaller Unmarshaller unmars = context.createUnmarshaller(); // unmarshall an XML document into its Java representation Purchaseorder po = (Purchaseorder)unmars.unmarshall( new FileInputStream( "purchaseorder.xml" ) ); Billingaddress address = po.getBillingaddress(); // do some work here changing the attributes of Purchaseorder // // create a Validator Validator v = context.createValidator(); // validate the entire content tree boolean isvalid = v.validateRoot( po ); System.out.println(isvalid); // validate partial content tree isvalid = v.validate(address); System.out.println(isvalid);
Developers can write a class that implements the ValidationEventHandler and register the implementation with the Validator instance to receive callbacks when appropriate ValiationEvents occur. This is analogous to the way SAX handlers are registered to receive events during parsing, discussed in Chapter 9.
In initial versions of the specifications, the logic and infrastructure to facilitate validation, marshalling, and unmarshalling were required to be included in the generated classes themselves. This not only opened the door for potential redundancy but also meant existing classes could not be used and increased the coupling between the generated code and the implementation. The current approach of logically separating the validation from the generated code is a lot cleaner.