Spring Web Services: Object-XML Mapping
Tuesday, November 22nd, 2005In this post on Spring Web Services, I will tell you something about the Object-XML Marshalling (OXM) support. In previous posts, I’ve told you about the dangers of OXM, but I also posted that:
As with O/R mapping, a good O/X mapping can certainly be extremely useful, if properly configured. So, a good SOAP stack should facilitate in this configuration, and offer something like Spring’s templates to easily convert XML to objects and vice-versa.
So, we’ve decided to add O/X Mapping to Spring-WS. This is one of the features which can also useful for REST Web services, since it has little to do with SOAP.
Marshaller and Unmarshaller
Central in Spring-WS’s are two interfaces: Marshaller and Unmarshaller. The Marshaller interface has just one method:
void marshal(Object graph, Result result)
throws XmlMappingException, IOException;
This method will marshall the given object graph to a javax.xml.transform.Result. Result basically is an XML output stream abstraction: concrete subclasses wrap a DOM document, an OutputStream or Writer, or a SAX ContentHandler.
Likewise, the Unmarshaller interface also has one method:
Object unmarshal(Source source)
throws XmlMappingException, IOException;
This method reads from the given javax.xml.transform.Source (an XML input stream abstraction), and returns the object read.
Implementations
Currently, we are thinking about three implementations for the two O/X interfaces: Castor, JAXB, and XMLBeans.
Most of these frameworks require some kind of configuration to operate. For instance, JAXB requires a JAXBContext, which needs a context path. Defining such a context can be quite simple, using the JaxbContextFactoryBean:
<bean id="jaxbMarshaller"
class="org.springframework.oxm.jaxb.JaxbMarshaller">
<property name="jaxbContext" ref="jaxbContext" />
</bean>
<bean id="jaxbUnmarshaller"
class="org.springframework.oxm.jaxb.JaxbUnmarshaller">
<property name="jaxbContext" ref="jaxbContext" />
</bean>
<bean id="jaxbContext"
class="org.springframework.oxm.jaxb.JaxbContextFactoryBean">
<property name="contextPath" value="com.example.myservice"/>
</bean>
Exceptions
Besides the I/O exception thrown by the marhsalling interfaces, there is also the XmlMappingException. This is an abstract runtime exception, which forms the root of the hierarchy of Object-XML Marshalling exceptions. It has concrete subclasses for marshalling and unmarshalling errors, and XML validation errors.
Additionally, this hierarchy follows one of the most popular features of Spring’s ORM support: it provides a unified abstraction for the various (checked) exceptions thrown by the marhalling frameworks. This means that it does not matter whether you are using Castor or JAXB: if marshalling fails, an MarshallingFailureException is thrown.