Movatterモバイル変換


[0]ホーム

URL:


21. Marshalling XML using O/X Mappers
Prev Part V. Data Access Next

21. Marshalling XML using O/X Mappers

21.1 Introduction

In this chapter, we will describe Spring’s Object/XML Mapping support. Object/XMLMapping, or O/X mapping for short, is the act of converting an XML document to and froman object. This conversion process is also known as XML Marshalling, or XMLSerialization. This chapter uses these terms interchangeably.

Within the field of O/X mapping, amarshaller is responsible for serializing anobject (graph) to XML. In similar fashion, anunmarshaller deserializes the XML toan object graph. This XML can take the form of a DOM document, an input or outputstream, or a SAX handler.

Some of the benefits of using Spring for your O/X mapping needs are:

21.1.1 Ease of configuration

Spring’s bean factory makes it easy to configure marshallers, without needing toconstruct JAXB context, JiBX binding factories, etc. The marshallers can be configuredas any other bean in your application context. Additionally, XML namespace-basedconfiguration is available for a number of marshallers, making the configuration evensimpler.

21.1.2 Consistent interfaces

Spring’s O/X mapping operates through two global interfaces: theMarshaller andUnmarshaller interface. These abstractions allow you to switch O/X mapping frameworkswith relative ease, with little or no changes required on the classes that do themarshalling. This approach has the additional benefit of making it possible to do XMLmarshalling with a mix-and-match approach (e.g. some marshalling performed using JAXB,other using XMLBeans) in a non-intrusive fashion, leveraging the strength of eachtechnology.

21.1.3 Consistent exception hierarchy

Spring provides a conversion from exceptions from the underlying O/X mapping tool to itsown exception hierarchy with theXmlMappingException as the root exception. As can beexpected, these runtime exceptions wrap the original exception so no information is lost.

21.2 Marshaller and Unmarshaller

As stated in the introduction, amarshaller serializes an object to XML, and anunmarshaller deserializes XML stream to an object. In this section, we will describethe two Spring interfaces used for this purpose.

21.2.1 Marshaller

Spring abstracts all marshalling operations behind theorg.springframework.oxm.Marshaller interface, the main method of which is shown below.

publicinterface Marshaller {/**     * Marshal the object graph with the given root into the provided Result.     */void marshal(Object graph, Result result)throws XmlMappingException, IOException;}

TheMarshaller interface has one main method, which marshals the given object to agivenjavax.xml.transform.Result. Result is a tagging interface that basicallyrepresents an XML output abstraction: concrete implementations wrap various XMLrepresentations, as indicated in the table below.

Result implementationWraps XML representation

DOMResult

org.w3c.dom.Node

SAXResult

org.xml.sax.ContentHandler

StreamResult

java.io.File,java.io.OutputStream, orjava.io.Writer

[Note]Note

Although themarshal() method accepts a plain object as its first parameter, mostMarshaller implementations cannot handle arbitrary objects. Instead, an object classmust be mapped in a mapping file, marked with an annotation, registered with themarshaller, or have a common base class. Refer to the further sections in this chapterto determine how your O/X technology of choice manages this.

21.2.2 Unmarshaller

Similar to theMarshaller, there is theorg.springframework.oxm.Unmarshallerinterface.

publicinterface Unmarshaller {/**     * Unmarshal the given provided Source into an object graph.     */    Object unmarshal(Source source)throws XmlMappingException, IOException;}

This interface also has one method, which reads from the givenjavax.xml.transform.Source (an XML input abstraction), and returns the object read. Aswith Result, Source is a tagging interface that has three concrete implementations. Eachwraps a different XML representation, as indicated in the table below.

Source implementationWraps XML representation

DOMSource

org.w3c.dom.Node

SAXSource

org.xml.sax.InputSource, andorg.xml.sax.XMLReader

StreamSource

java.io.File,java.io.InputStream, orjava.io.Reader

Even though there are two separate marshalling interfaces (Marshaller andUnmarshaller), all implementations found in Spring-WS implement both in one class.This means that you can wire up one marshaller class and refer to it both as amarshaller and an unmarshaller in yourapplicationContext.xml.

21.2.3 XmlMappingException

Spring converts exceptions from the underlying O/X mapping tool to its own exceptionhierarchy with theXmlMappingException as the root exception. As can be expected,these runtime exceptions wrap the original exception so no information will be lost.

Additionally, theMarshallingFailureException andUnmarshallingFailureExceptionprovide a distinction between marshalling and unmarshalling operations, even though theunderlying O/X mapping tool does not do so.

The O/X Mapping exception hierarchy is shown in the following figure:

oxm exceptions

O/X Mapping exception hierarchy

21.3 Using Marshaller and Unmarshaller

Spring’s OXM can be used for a wide variety of situations. In the following example, wewill use it to marshal the settings of a Spring-managed application as an XML file. Wewill use a simple JavaBean to represent the settings:

publicclass Settings {privateboolean fooEnabled;publicboolean isFooEnabled() {return fooEnabled;    }publicvoid setFooEnabled(boolean fooEnabled) {this.fooEnabled = fooEnabled;    }}

The application class uses this bean to store its settings. Besides a main method, theclass has two methods:saveSettings() saves the settings bean to a file namedsettings.xml, andloadSettings() loads these settings again. Amain() methodconstructs a Spring application context, and calls these two methods.

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.oxm.Marshaller;import org.springframework.oxm.Unmarshaller;publicclass Application {privatestaticfinal String FILE_NAME ="settings.xml";private Settings settings =new Settings();private Marshaller marshaller;private Unmarshaller unmarshaller;publicvoid setMarshaller(Marshaller marshaller) {this.marshaller = marshaller;    }publicvoid setUnmarshaller(Unmarshaller unmarshaller) {this.unmarshaller = unmarshaller;    }publicvoid saveSettings()throws IOException {        FileOutputStream os = null;try {            os =new FileOutputStream(FILE_NAME);this.marshaller.marshal(settings,new StreamResult(os));        }finally {if (os != null) {                os.close();            }        }    }publicvoid loadSettings()throws IOException {        FileInputStream is = null;try {            is =new FileInputStream(FILE_NAME);this.settings = (Settings)this.unmarshaller.unmarshal(new StreamSource(is));        }finally {if (is != null) {                is.close();            }        }    }publicstaticvoid main(String[] args)throws IOException {        ApplicationContext appContext =new ClassPathXmlApplicationContext("applicationContext.xml");        Application application = (Application) appContext.getBean("application");        application.saveSettings();        application.loadSettings();    }}

TheApplication requires both amarshaller andunmarshaller property to be set. Wecan do so using the followingapplicationContext.xml:

<beans><beanid="application"class="Application"><propertyname="marshaller"ref="castorMarshaller" /><propertyname="unmarshaller"ref="castorMarshaller" /></bean><beanid="castorMarshaller"class="org.springframework.oxm.castor.CastorMarshaller"/></beans>

This application context uses Castor, but we could have used any of the other marshallerinstances described later in this chapter. Note that Castor does not require any furtherconfiguration by default, so the bean definition is rather simple. Also note that theCastorMarshaller implements bothMarshaller andUnmarshaller, so we can refer to thecastorMarshaller bean in both themarshaller andunmarshaller property of theapplication.

This sample application produces the followingsettings.xml file:

<?xml version="1.0" encoding="UTF-8"?><settingsfoo-enabled="false"/>

21.4 XML configuration namespace

Marshallers could be configured more concisely using tags from the OXM namespace. Tomake these tags available, the appropriate schema has to be referenced first in thepreamble of the XML configuration file. Note the 'oxm' related text below:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:oxm="http://www.springframework.org/schema/oxm" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm.xsd">

Currently, the following tags are available:

Each tag will be explained in its respective marshaller’s section. As an example though,here is how the configuration of a JAXB2 marshaller might look like:

<oxm:jaxb2-marshallerid="marshaller"contextPath="org.springframework.ws.samples.airline.schema"/>

21.5 JAXB

The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, ajaxb.properties file, and possibly some resource files. JAXB also offers a way togenerate a schema from annotated Java classes.

Spring supports the JAXB 2.0 API as XML marshalling strategies, following theMarshaller andUnmarshaller interfaces described inSection 21.2, “Marshaller and Unmarshaller”.The corresponding integration classes reside in theorg.springframework.oxm.jaxbpackage.

21.5.1 Jaxb2Marshaller

TheJaxb2Marshaller class implements both the SpringMarshaller andUnmarshallerinterface. It requires a context path to operate, which you can set using thecontextPath property. The context path is a list of colon (:) separated Java packagenames that contain schema derived classes. It also offers aclassesToBeBound property,which allows you to set an array of classes to be supported by the marshaller. Schemavalidation is performed by specifying one or more schema resource to the bean, like so:

<beans><beanid="jaxb2Marshaller"class="org.springframework.oxm.jaxb.Jaxb2Marshaller"><propertyname="classesToBeBound"><list><value>org.springframework.oxm.jaxb.Flight</value><value>org.springframework.oxm.jaxb.Flights</value></list></property><propertyname="schema"value="classpath:org/springframework/oxm/schema.xsd"/></bean>    ...</beans>

XML configuration namespace

Thejaxb2-marshaller tag configures aorg.springframework.oxm.jaxb.Jaxb2Marshaller.Here is an example:

<oxm:jaxb2-marshallerid="marshaller"contextPath="org.springframework.ws.samples.airline.schema"/>

Alternatively, the list of classes to bind can be provided to the marshaller via theclass-to-be-bound child tag:

<oxm:jaxb2-marshallerid="marshaller"><oxm:class-to-be-boundname="org.springframework.ws.samples.airline.schema.Airport"/><oxm:class-to-be-boundname="org.springframework.ws.samples.airline.schema.Flight"/>    ...</oxm:jaxb2-marshaller>

Available attributes are:

AttributeDescriptionRequired

id

the id of the marshaller

no

contextPath

the JAXB Context path

no

21.6 Castor

Castor XML mapping is an open source XML binding framework. It allows you to transformthe data contained in a java object model into/from an XML document. By default, it doesnot require any further configuration, though a mapping file can be used to have morecontrol over the behavior of Castor.

For more information on Castor, refer to theCastor web site. The Springintegration classes reside in theorg.springframework.oxm.castor package.

21.6.1 CastorMarshaller

As with JAXB, theCastorMarshaller implements both theMarshaller andUnmarshallerinterface. It can be wired up as follows:

<beans><beanid="castorMarshaller"class="org.springframework.oxm.castor.CastorMarshaller" />    ...</beans>

21.6.2 Mapping

Although it is possible to rely on Castor’s default marshalling behavior, it might benecessary to have more control over it. This can be accomplished using a Castor mappingfile. For more information, refer toCastorXML Mapping.

The mapping can be set using themappingLocation resource property, indicated belowwith a classpath resource.

<beans><beanid="castorMarshaller"class="org.springframework.oxm.castor.CastorMarshaller" ><propertyname="mappingLocation"value="classpath:mapping.xml" /></bean></beans>

XML configuration namespace

Thecastor-marshaller tag configures aorg.springframework.oxm.castor.CastorMarshaller. Here is an example:

<oxm:castor-marshallerid="marshaller"mapping-location="classpath:org/springframework/oxm/castor/mapping.xml"/>

The marshaller instance can be configured in two ways, by specifying either the locationof a mapping file (through themapping-location property), or by identifying JavaPOJOs (through thetarget-class ortarget-package properties) for which there existcorresponding XML descriptor classes. The latter way is usually used in conjunction withXML code generation from XML schemas.

Available attributes are:

AttributeDescriptionRequired

id

the id of the marshaller

no

encoding

the encoding to use for unmarshalling from XML

no

target-class

a Java class name for a POJO for which an XML class descriptor is available (as generated through code generation)

no

target-package

a Java package name that identifies a package that contains POJOs and their corresponding Castor XML descriptor classes (as generated through code generation from XML schemas)

no

mapping-location

location of a Castor XML mapping file

no

21.7 XMLBeans

XMLBeans is an XML binding tool that has full XML Schema support, and offers full XMLInfoset fidelity. It takes a different approach to that of most other O/X mappingframeworks, in that all classes that are generated from an XML Schema are all derivedfromXmlObject, and contain XML binding information in them.

For more information on XMLBeans, refer to theXMLBeansweb site. The Spring-WS integration classes reside in theorg.springframework.oxm.xmlbeans package.

21.7.1 XmlBeansMarshaller

TheXmlBeansMarshaller implements both theMarshaller andUnmarshaller interfaces.It can be configured as follows:

<beans><beanid="xmlBeansMarshaller"class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />    ...</beans>
[Note]Note

Note that theXmlBeansMarshaller can only marshal objects of typeXmlObject, and noteveryjava.lang.Object.

XML configuration namespace

Thexmlbeans-marshaller tag configures aorg.springframework.oxm.xmlbeans.XmlBeansMarshaller. Here is an example:

<oxm:xmlbeans-marshallerid="marshaller"/>

Available attributes are:

AttributeDescriptionRequired

id

the id of the marshaller

no

options

the bean name of the XmlOptions that is to be used for this marshaller. Typically aXmlOptionsFactoryBean definition

no

21.8 JiBX

The JiBX framework offers a solution similar to that which JDO provides for ORM: abinding definition defines the rules for how your Java objects are converted to or fromXML. After preparing the binding and compiling the classes, a JiBX binding compilerenhances the class files, and adds code to handle converting instances of the classesfrom or to XML.

For more information on JiBX, refer to theJiBX website. The Spring integration classes reside in theorg.springframework.oxm.jibxpackage.

21.8.1 JibxMarshaller

TheJibxMarshaller class implements both theMarshaller andUnmarshallerinterface. To operate, it requires the name of the class to marshal in, which you canset using thetargetClass property. Optionally, you can set the binding name using thebindingName property. In the next sample, we bind theFlights class:

<beans><beanid="jibxFlightsMarshaller"class="org.springframework.oxm.jibx.JibxMarshaller"><propertyname="targetClass">org.springframework.oxm.jibx.Flights</property></bean>    ...</beans>

AJibxMarshaller is configured for a single class. If you want to marshal multipleclasses, you have to configure multipleJibxMarshallers with differenttargetClassproperty values.

XML configuration namespace

Thejibx-marshaller tag configures aorg.springframework.oxm.jibx.JibxMarshaller.Here is an example:

<oxm:jibx-marshallerid="marshaller"target-class="org.springframework.ws.samples.airline.schema.Flight"/>

Available attributes are:

AttributeDescriptionRequired

id

the id of the marshaller

no

target-class

the target class for this marshaller

yes

bindingName

the binding name used by this marshaller

no

21.9 XStream

XStream is a simple library to serialize objects to XML and back again. It does notrequire any mapping, and generates clean XML.

For more information on XStream, refer to theXStreamweb site. The Spring integration classes reside in theorg.springframework.oxm.xstream package.

21.9.1 XStreamMarshaller

TheXStreamMarshaller does not require any configuration, and can be configured in anapplication context directly. To further customize the XML, you can set analias map,which consists of string aliases mapped to classes:

<beans><beanid="xstreamMarshaller"class="org.springframework.oxm.xstream.XStreamMarshaller"><propertyname="aliases"><props><propkey="Flight">org.springframework.oxm.xstream.Flight</prop></props></property></bean>    ...</beans>
[Warning]Warning

By default, XStream allows for arbitrary classes to be unmarshalled, which can lead tounsafe Java serialization effects. As such, it isnot recommended to use theXStreamMarshaller to unmarshal XML from external sources (i.e. the Web), as this canresult insecurity vulnerabilities.

If you choose to use theXStreamMarshaller to unmarshal XML from an external source,set thesupportedClasses property on theXStreamMarshaller, like as follows:

<beanid="xstreamMarshaller"class="org.springframework.oxm.xstream.XStreamMarshaller"><propertyname="supportedClasses"value="org.springframework.oxm.xstream.Flight"/>    ...</bean>

This will make sure that only the registered classes are eligible for unmarshalling.

Additionally, you can registercustomconverters to make sure that only your supported classes can be unmarshalled. You mightwant to add aCatchAllConverter as the last converter in the list, in addition toconverters that explicitly support the domain classes that should be supported. As aresult, default XStream converters with lower priorities and possible securityvulnerabilities do not get invoked.

[Note]Note

Note that XStream is an XML serialization library, not a data binding library.Therefore, it has limited namespace support. As such, it is rather unsuitable for usagewithin Web services.


Prev Up Next
20. Object Relational Mapping (ORM) Data Access Home Part VI. The Web

[8]ページ先頭

©2009-2025 Movatter.jp