Overview

JAXB Postprocessing

No Comments

In one of our current projects, we use JAXB in order to unmarshal structured content pulled from a CMS. We encountered the necessity to perform additional steps after the “pure” unmarshalling in order to give the newly created object tree a consistent state. In this specific case we needed a mapping between ID strings (defined by the content editors) and numeric IDs (used in the application logic). Because this mapping is not available from the XML, it has to be created after the unmarshalling.

Looking for the most elegant way to extend our generic XML reader for postprocessing purposes, we first thought of defining an interface that has to be implemented of every mapped top-level model class in need of postprocessing. This idea turned out to be redundant because JAXB offers pre- and postprocessing mechanisms. The Javadoc for javax.xml.bind.Unmarshaller contains exactly what we need.

By adding a method

void afterUnmarshal(Unmarshaller, Object parent);

to the mapped model class, you get a callback hook that will be called after unmarshalling. Inside the method, you have full access to the Unmarshaller and to the parent object. Parent is null if the object is equivalent to the XmlRootElement.

If you implement this method in the “top level” model class, you can easily traverse the object tree from there and perform the steps necessary. In our case, this method looks (and is) quite harmless:

void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
    createIDs();
}

The method “createIDs();” has default access. Thus, because the associated unit test is in the same package, it can create mock objects and call createIDs() directly instead of using the afterUnmarshal(…) method, which would not be quite appropriate in the absence of JAXB. The second advantage is that afterUnmarshal(…) can be extended to whatever need may arise in the future, without creating a bunch of unrelated code in one method.

Comment

Your email address will not be published. Required fields are marked *