Category Archives: JAXB

JAXB

XML Schema Validation using JAXB

Hi All,

This is a very small post on a very important part of XML Schema validation. While interchanging the data across different systems using XML format, it becomes  more important to validate the XML data with XML schema. As XSD plays a crucial part to validate all the possible combination of data to carry in XML document.

Now lets see an example of performing XSD Validation using JAXB.

//Setting the Validation
Schema schema;
SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI ); //W3C XML Schema Namespace URI.
schema = schemaFactory.newSchema(new File(“src/product.xsd”)); //THE XSD Location
marshaller.setSchema(schema); //Register the schema in marshaller
marshaller.marshal(product, System.out); //marshal the object

To list all the validation  issues in logger  or on system console, you can use my previous post on registering ValidationHandler in JAXB.(Read POST http://wp.me/pQKn2-gj )

Hope this helps.


Thanks
R Vashi

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

JAXB. Unmarshalling strings XML’s

Hi,

In this article I will show how to unmarshall XML string using JAXB, Usually JAXB uses InputStreams and OutputStreams for the XML text input and output, respectively.

One of workaround by passing a ByteArrayInputStreams (java.io) or ByteArrayOutputStreams (java.io) for XML String  or Using StreamSource to read the input via StringReader.

You can simply read my previous article “Sample on JAXB” to get the complete instruction on building a sample project on JAXB with eclipse plugin.

Below is the method which we can use to perform the unmarshalling of XML String into Java JAXB objects.
1. Via ByteArrayInputStream

public List loadObjectFromXMLString(String xmlString){
try{
ByteArrayInputStream input = new ByteArrayInputStream (xmlString.getBytes());
Object jaxbObject = unmarshaller.unmarshal( input);
if(items == null) {
items = (ItemsType)(((JAXBElement)jaxbObject).getValue());
return(items.getItem());
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}

2 Via StreamSource

JAXBContext jc = JAXBContext.newInstance( “com.acme.foo” );
Unmarshaller u = jc.createUnmarshaller();
StringBuffer xmlStr = new StringBuffer( “<?xml version=”1.0″?>…” );
Object o = u.unmarshal( new StreamSource( new StringReader( xmlStr.toString() ) ) );

[NOTE] This example is totally based on my previous article “Sample on JAXB”. Simply add the above method/statements if your building the project on my previous article instructions. Even there are many ways to do the same thing mentioned in the article. please go through with the below URL.
http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#supportedProps


Thanks
R Vashi

Sample on JAXB using Eclipse

Java Architecture for XML Binding (JAXB) allows Java developers to map Java classes to XML representations.

JAXB provides two main features:

1. The ability to marshal Java objects into XML

2. To unmarshal  XML back into Java objects.

In other words, JAXB allows storing and retrieving data in memory in any XML format, without the need to implement a specific set of XML loading and saving routines for the program’s class structure. It is similar to xsd.exe and xmlserializers in .Net Framework.

JAXB is particularly useful when the specification is complex and changing. In such a case, regularly changing the XML Schema definitions to keep them synchronised with the Java definitions can be time consuming and error prone.

Follow the steps to configure and Test JXB Sample project in Eclipse.

1. Install Eclipse plug-in for JXB2.0 https://jaxb-workshop.dev.java.net/plugins/eclipse/xjc-plugin.html
or click on the link to download jaxb-xjc(rename the “docx” extension  2 “jar”)

2. Once download extract the Zip file and copy the folder “org.jvnet.jaxbw.eclipse_1.0.0” into the home directory of Eclipse > plug-in

3. Re-start the Eclipse, if the plug-in doesn’t appear then simple run the “eclipse.exe -clean” option.

4. Now create one project SampleJXB and inside the java source folder create a package like “com.mytest.jxb”

5 Add one XSD with below contents.

<?xml version=”1.0″ encoding=”utf-16″?>

<xsd:schema attributeFormDefault=”unqualified” elementFormDefault=”qualified” version=”1.0″ xmlns:xsd=”http://www.w3.org/2001/XMLSchema”&gt;

<xsd:element name=”persons” />

<xsd:complexType name=”itemsType”>

<xsd:sequence>

<xsd:element maxOccurs=”unbounded” type=”itemType” />

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name=”itemType”>

<xsd:sequence>

<xsd:element name=”firstname” />

<xsd:element name=”lastname” />

<xsd:element name=”email” />

</xsd:sequence>

</xsd:complexType>

</xsd:schema>

6 Now right click on the XSD file and choose JAXB 2.0 -> Run XJC

7 You will be prompted for package name and output directory in the wizard. Simple add the package name given in step 4 and follow the rest of steps.

8 Now navigate to the java package, You will notice 3 classes got generated after running the JAXB command

1. ItemsType.java

2. ItemType.java

3. ObjectFactory.java

9 Now write one Java class to interact with JAXB

import java.io.FileOutputStream;

import java.io.InputStream;

import java.util.List;

import javax.xml.bind.JAXBContext;

import javax.xml.bind.JAXBElement;

import javax.xml.bind.JAXBException;

import javax.xml.bind.Marshaller;

import javax.xml.bind.Unmarshaller;

public class PersonListManager {

private JAXBContext jaxbContext = null;

private Unmarshaller unmarshaller = null;

private ItemsType items = null;

public PersonListManager() {

try {

jaxbContext = JAXBContext.newInstance(“com.mytest.jxb”); //MAKE SURE THE SAME PACAKGE NAME GIVEN IN STEP 4

unmarshaller = jaxbContext.createUnmarshaller();

} catch (JAXBException e) {

}

}

public List loadXML(InputStream istrm) {

try {

Object obj = unmarshaller.unmarshal(istrm);

if(items == null) {

items = (ItemsType)(((JAXBElement)obj).getValue());

return(items.getItem());

}

} catch (JAXBException e) {

e.printStackTrace();

}

return null;

}

/**

* This method will write back to the XML

* @param xmlName

* @throws Exception

*/

public void writeDataInXML(String xmlName) throws Exception{

/* Make sure ItemsType should have @XmlRootElement(name=”items”)if missing add */

ObjectFactory factory= new ObjectFactory();

ItemsType persons = factory.createItemsType();

ItemType item = factory.createItemType();

item.setFirstname(“xyz”);

item.setLastname(“jkl”);

item.setEmail(“anyemail@aa123.com”);

persons.getItem().add(book1);

Marshaller marshaller =jaxbContext.createMarshaller();

marshaller.marshal(library, new FileOutputStream(xmlName)) ;

}

}

10. Now write one more Java class to test the JAXB.

public class TestJAXB {

public static void main(String[] args) {

PersonListManager xmgr = new PersonListManager();

File file = new File(“NewXMLSchema.xml”);

List lst = new ArrayList();

try {

FileInputStream fis = new FileInputStream(file);

lst = xmgr.loadXML(fis);

Iterator<ItemType> lst = rtList.iterator();

while(lst.hasNext()){

ItemType item = lst.next();

System.out.println(“First Name = ” + item.getFirstname().trim() +

“\t\tLast Name = ” + item.getLastname().trim() +

“\t\tEmail = ” + item.getEmail().trim());

}

//xmgr.writeDataInXML(“NewXMLSchema.xml”);

} catch (FileNotFoundException e) {

e.printStackTrace();

}catch(Exception e){

e.printStackTrace();

}

}

}


Thanks
R Vashi