prev table of contents next

4.4 Last Resort: Assembling a Java Object

With all the features XML schema provides and JAXB translates you might think that including arbitrary Java objects in an XML document won't ever be necessary. But the need does arise occasionally. Special dumps of application data, for instance, may have to use this rather extreme technique. All in all, it is surprisingly simple, provided that the class of the object implements the java.util.Serializable interface. The schema element that is to contain the serialized binary data should be declared with a type of xsd:hexBinary. The schema snippet shows a simple container for some such object.

<xsd:complexType name="JavaObjectType">
  <xsd:sequence>
    <xsd:element name="data" type="xsd:hexBinary"/>
  </xsd:sequence>
</xsd:complexType>

<xsd:element name="container" type="JavaObjectType"/>
The generated Java class JavaObjectType has a field byte[] data, which is just what we need for calling the java.io.ObjectOutputStream methods writeObject and readObject. The code required to serialize a Java object into a XML element is shown below.
JavaObjectType makePojoElem( ObjectFactory objFact, Object pojo )
    throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream ooStream = new ObjectOutputStream( baos );
    ooStream.writeObject( pojo );
    ooStream.flush();
    JavaObjectType joElem = objFact.createJavaObjectType();
    joElem.setData( baos.toByteArray() );
    ooStream.close();
    return joElem;
}
The generated XML text is verbose and lengthy, since all object data required for a full reconstruction is included in the serialized data. Here it is, omitting a few hundred hexadecimal digits:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="serial.xsd">
    <data>ACED00057372...7878</data>
</container>

The reverse process is even simpler. The byte array returned by the getter for the data element is fed to the ObjectInputStream which smartly returns the original object.

Object getPojo( JavaObjectType joElem )
    throws IOException, ClassNotFoundException {
    ByteArrayInputStream bais = new ByteArrayInputStream( joElem.getData() );
    ObjectInputStream oiStream = new ObjectInputStream( bais );
    Object pojo = oiStream.readObject();
    oiStream.close();
    return pojo;
}


prev table of contents next