Using ValidationEventHandler while converting XML to Java object in JAXB

Hi All,

JAXB as we know is an API  for XML Binding. It is heavily used in JAX-WS web services as a binding standard. XML Data binding describes the conversion of data between its XML and Java representations.

So this post talks about the phase when we convert the XML Data to its corresponding Java objects. It seems easy as just by calling the unmarshaller.unmarshal method. But what goes behind the scene is not that quite easy.

And think about a scenario where you have data payload in XML format of more than 3mb and just seeing some “NullPointerException” during un-marshalling will make you go mad(specially which I had felt so many times 🙂 ).

So to tackle this lets first of all understand what JAXB does during un-marshalling. JAXB reports validation of data through events.  It uses a handler called as “ValidationEventHandler“, And this handler represent an instance of “ValidationEvent” and provides many details about the un-marshalling related issues.

Lets see in an example(I am taking the base example I have posted in this post) https://rocksolutions.wordpress.com/2010/08/04/sample-on-jaxb-using-eclipse/

Step 1: Create a Custom Handler Class

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

public class CustomValidationEventHandler implements ValidationEventHandler {

    public boolean handleEvent(ValidationEvent event) {
        System.out.println("Event");
        System.out.println("Severity:  " + event.getSeverity());
        System.out.println("Message:  " + event.getMessage());
        System.out.println("Linked Exception:  " + event.getLinkedException());
        System.out.println("Locator:::");
        System.out.println("    Line Nbr:  " + event.getLocator().getLineNumber());
        System.out.println("    Column Nbr:  " + event.getLocator().getColumnNumber());
        System.out.println("    Offset:  " + event.getLocator().getOffset());
        System.out.println("    Objct:  " + event.getLocator().getObject());
        System.out.println("    Node:  " + event.getLocator().getNode());
        System.out.println("    URL:  " + event.getLocator().getURL());
        return true;
    }

}


Step 2: Register the Handler with the Unmarshller

unmarshaller.setEventHandler(new CustomValidationEventHandler());


Now run the program and you will see the somewhat similar output.

Severity:  1
Message:  cvc-maxLength-valid: Value 'TESTPRODUCT' with length = '10' is not facet-valid with respect to maxLength '8' for type 'stringWithMaxSize8'.
Linked Exception:  org.xml.sax.SAXParseException: cvc-maxLength-valid: Value 'TESTPRODUCT' with length = '10' is not facet-valid with respect to maxLength '8' for type 'stringWithMaxSize8'.
Locator:::
    Line Nbr:  3
    Column Nbr:  12
    Offset:  -1
    Object:  null
    Node:  null
    URL:  null

One thing which I have observed is that the Node and URL properties are not always available to be set on the locator. This is something which I am investigating will sure post the reasons on the same, would appreciate if somebody share the reason.

Please do share your thoughts about this Post 🙂


Thanks
R Vashi

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s