added the OXM chapter from Spring WS

This commit is contained in:
Thomas Risberg 2009-04-06 19:43:18 +00:00
parent a9f30fe377
commit eb90bbeadc
2 changed files with 691 additions and 6 deletions

View File

@ -0,0 +1,680 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="oxm">
<title>Marshalling XML using O/X Mappers</title>
<section id="oxm-introduction">
<title>Introduction</title>
<para>
In this chapter, we will describe Spring's Object/XML Mapping support. Object/XML Mapping, or O/X mapping
for short, is the act of converting an XML document to and from an object. This conversion process is also
known as XML Marshalling, or XML Serialization. This chapter uses these terms interchangeably.
</para>
<para>
Within the field of O/X mapping, a <emphasis>marshaller</emphasis> is responsible for serializing an
object (graph) to XML. In similar fashion, an <emphasis>unmarshaller</emphasis> deserializes the XML to an
object graph. This XML can take the form of a DOM document, an input or output stream, or a SAX handler.
</para>
<para>Some of the benefits of using Spring for your O/X mapping needs are:</para>
<formalpara>
<title>Ease of configuration</title>
<para>
Spring's bean factory makes it easy to configure marshallers, without needing to construct JAXB context,
JiBX binding factories, etc. The marshallers can be configured as any other bean in your application
context. Additionally, XML Schema-based configuration is available for a number of marshallers, making
the configuration even simpler.
</para>
</formalpara>
<formalpara>
<title>Consistent Interfaces</title>
<para>
Spring's O/X mapping operates through two global interfaces: the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
These abstractions allow you to switch O/X mapping
frameworks with relative ease, with little or no changes required on the classes that do the
marshalling. This approach has the additional benefit of making it possible to do XML marshalling 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 each technology.
</para>
</formalpara>
<formalpara>
<title>Consistent Exception Hierarchy</title>
<para>
Spring provides a conversion from exceptions from the underlying O/X mapping tool to its own exception
hierarchy with the <classname>XmlMappingException</classname> as the root exception. As can be expected,
these runtime exceptions wrap the original exception so no information is lost.
</para>
</formalpara>
</section>
<section id="oxm-marshaller-unmarshaller">
<title>Marshaller and Unmarshaller</title>
<para>
As stated in the introduction, a <emphasis>marshaller</emphasis> serializes an object to XML, and an
<emphasis>unmarshaller</emphasis> deserializes XML stream to an object. In this section, we will describe
the two Spring interfaces used for this purpose.
</para>
<section>
<title>Marshaller</title>
<para>
Spring abstracts all marshalling operations behind the
<interfacename>org.springframework.oxm.Marshaller</interfacename> interface, the main methods of which
is listed below.
<programlisting><![CDATA[
public interface Marshaller {
/**
* Marshals the object graph with the given root into the provided Result.
*/
void marshal(Object graph, Result result)
throws XmlMappingException, IOException;
}]]></programlisting>
The <interfacename>Marshaller</interfacename> interface has one main method, which marshals the given
object to a given <interfacename>javax.xml.transform.Result</interfacename>. Result is a tagging
interface that basically represents an XML output abstraction: concrete implementations wrap various XML
representations, as indicated in the table below.
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry><interfacename>javax.xml.transform.Result</interfacename> implementation</entry>
<entry>Wraps XML representation</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>javax.xml.transform.dom.DOMResult</classname></entry>
<entry><interfacename>org.w3c.dom.Node</interfacename></entry>
</row>
<row>
<entry><classname>javax.xml.transform.sax.SAXResult</classname></entry>
<entry><interfacename>org.xml.sax.ContentHandler</interfacename></entry>
</row>
<row>
<entry><interfacename>javax.xml.transform.stream.StreamResult</interfacename></entry>
<entry>
<classname>java.io.File</classname>,
<classname>java.io.OutputStream</classname>, or
<classname>java.io.Writer</classname>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<note>
<para>
Although the <methodname>marshal</methodname> method accepts a plain object as its first
parameter, most <classname>Marshaller</classname> implementations cannot handle arbitrary
objects. Instead, an object class must be mapped in a mapping file, registered with the
marshaller, or have a common base class. Refer to the further sections in this chapter to
determine how your O/X technology of choice manages this.
</para>
</note>
</para>
</section>
<section>
<title>Unmarshaller</title>
<para>
Similar to the <interfacename>Marshaller</interfacename>, there is the
<interfacename>org.springframework.oxm.Unmarshaller</interfacename> interface.
<programlisting><![CDATA[
public interface Unmarshaller {
/**
* Unmarshals the given provided Source into an object graph.
*/
Object unmarshal(Source source)
throws XmlMappingException, IOException;
}]]></programlisting>
This interface also has one method, which reads from the given
<interfacename>javax.xml.transform.Source</interfacename> (an XML input abstraction), and returns the
object read. As with Result, Source is a tagging interface that has three concrete implementations. Each
wraps a different XML representation, as indicated in the table below.
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry><interfacename>javax.xml.transform.Source</interfacename> implementation</entry>
<entry>Wraps XML representation</entry>
</row>
</thead>
<tbody>
<row>
<entry><classname>javax.xml.transform.dom.DOMSource</classname></entry>
<entry><interfacename>org.w3c.dom.Node</interfacename></entry>
</row>
<row>
<entry><classname>javax.xml.transform.sax.SAXSource</classname></entry>
<entry>
<classname>org.xml.sax.InputSource</classname>, and
<interfacename>org.xml.sax.XMLReader</interfacename>
</entry>
</row>
<row>
<entry><classname>javax.xml.transform.stream.StreamSource</classname></entry>
<entry>
<classname>java.io.File</classname>,
<classname>java.io.InputStream</classname>, or
<classname>java.io.Reader</classname>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
<para>
Even though there are two separate marshalling interfaces (<interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>), 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 a marshaller and an
unmarshaller in your <filename>applicationContext.xml</filename>.
</para>
<section>
<title>XmlMappingException</title>
<para>
Spring converts exceptions from the underlying O/X mapping tool to its own exception hierarchy with the
<classname>XmlMappingException</classname> as the root exception. As can be expected, these runtime
exceptions wrap the original exception so no information will be lost.
</para>
<para>
Additionally, the <classname>MarshallingFailureException</classname> and
<classname>UnmarshallingFailureException</classname> provide a distinction between marshalling and
unmarshalling operations, even though the underlying O/X mapping tool does not do so.
</para>
<para>
The O/X Mapping exception hierarchy is shown in the following figure:
<mediaobject>
<imageobject role="fo">
<imagedata fileref="src/docbkx/resources/images/oxm-exceptions.svg"
format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
<imagedata fileref="images/oxm-exceptions.png"
format="PNG" align="center"/>
</imageobject>
<caption>
<para>
O/X Mapping exception hierarchy
</para>
</caption>
</mediaobject>
</para>
</section>
</section>
<section id="oxm-usage">
<title>Using Marshaller and Unmarshaller</title>
<para>
Spring's OXM can be used for a wide variety of situations. In the following example, we will use it to
marshal the settings of a Spring-managed application as an XML file. We will use a simple JavaBean to
represent the settings:
<programlisting><![CDATA[
public class Settings {
private boolean fooEnabled;
public boolean isFooEnabled() {
return fooEnabled;
}
public void setFooEnabled(boolean fooEnabled) {
this.fooEnabled = fooEnabled;
}
}]]></programlisting>
</para>
<para>
The application class uses this bean to store its settings. Besides a main method, the class has two
methods: <methodname>saveSettings</methodname> saves the settings bean to a file named
<filename>settings.xml</filename>, and <methodname>loadSettings</methodname> loads these settings again. A
<methodname>main</methodname> method constructs a Spring application context, and calls these two methods.
<programlisting><![CDATA[
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;
public class Application {
private static final String FILE_NAME = "settings.xml";
private Settings settings = new Settings();
private Marshaller marshaller;
private Unmarshaller unmarshaller;
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}
public void 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();
}
}
}
public void 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();
}
}
}
public static void main(String[] args) throws IOException {
ApplicationContext appContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
Application application = (Application) appContext.getBean("application");
application.saveSettings();
application.loadSettings();
}
}]]></programlisting>
The <classname>Application</classname> requires both a <property>marshaller</property>
and <property>unmarshaller</property> property to be set. We can do so using the following
<filename>applicationContext.xml</filename>:
<programlisting><![CDATA[
<beans>
<bean id="application" class="Application">
<property name="marshaller" ref="castorMarshaller" />
<property name="unmarshaller" ref="castorMarshaller" />
</bean>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
</beans>
]]></programlisting>
This application context uses Castor, but we could have used any of the other marshaller instances described
later in this chapter. Note that Castor does not require any further configuration by default, so the bean
definition is rather simple. Also note that the <classname>CastorMarshaller</classname> implements both
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>, so we can refer
to the <varname>castorMarshaller</varname> bean in both the <property>marshaller</property> and
<property>unmarshaller</property> property of the application.
</para>
<para>
This sample application produces the following <filename>settings.xml</filename> file:
<programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<settings foo-enabled="false"/>
]]></programlisting>
</para>
</section>
<section>
<title>XML Schema-based Configuration</title>
<para>
Marshallers could be configured more concisely using tags from the OXM namespace.
To make these tags available, the appropriate schema has to be referenced first in the preamble of the XML configuration file.
The emboldened text in the below snippet references the OXM schema:
</para>
<programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
]]><emphasis role="bold"><![CDATA[xmlns:oxm="http://www.springframework.org/schema/oxm"]]></emphasis>
<![CDATA[xsi:schemaLocation="http://www.springframework.org/schema/beans
]]><![CDATA[http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
]]><emphasis role="bold"><![CDATA[http://www.springframework.org/schema/oxm
]]><![CDATA[http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd"]]></emphasis><![CDATA[>
]]></programlisting>
<para>
Currently, the following tags are available:
<itemizedlist>
<listitem>
<para><link linkend="oxm-jaxb2-xsd"><literal>jaxb2-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-xmlbeans-xsd"><literal>xmlbeans-marshaller</literal></link></para>
</listitem>
<listitem>
<para><link linkend="oxm-jibx-xsd"><literal>jibx-marshaller</literal></link></para>
</listitem>
</itemizedlist>
</para>
<para>
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:
</para>
<programlisting><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
</section>
<section id="oxm-jaxb">
<title>JAXB</title>
<para>
The JAXB binding compiler translates a W3C XML Schema into one or more Java classes, a
<filename>jaxb.properties</filename> file, and possibly some resource files. JAXB also offers a
way to generate a schema from annotated Java classes.
</para>
<para>
Spring supports the JAXB 2.0 API as XML marshalling strategies, following the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>
interfaces described in <xref linkend="oxm-marshaller-unmarshaller"/>. The corresponding integration
classes reside in the <package>org.springframework.oxm.jaxb</package> package.
</para>
<section id="oxm-jaxb2">
<title>Jaxb2Marshaller</title>
<para>
The <classname>Jaxb2Marshaller</classname> class implements both the Spring
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>interface. It
requires a context path to operate, which you can set using the <property>contextPath</property>
property. The context path is a list of colon (:) separated Java package names that contain schema
derived classes. It also offers a <property>classesToBeBound</property> property, which allows you to set an array of
classes to be supported by the marshaller. Schema validation is performed by specifying one or more
schema resource to the bean, like so:
</para>
<programlisting><![CDATA[
<beans>
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.oxm.jaxb.Flight</value>
<value>org.springframework.oxm.jaxb.Flights</value>
</list>
</property>
<property name="schema" value="classpath:org/springframework/oxm/schema.xsd"/>
</bean>
...
</beans>]]></programlisting>
<section id="oxm-jaxb2-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jaxb2-marshaller</literal> tag configures a <classname>org.springframework.oxm.jaxb.Jaxb2Marshaller</classname>.
Here is an example:
</para>
<programlisting><![CDATA[<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.ws.samples.airline.schema"/>]]></programlisting>
<para>
Alternatively, the list of classes to bind can be provided to the marshaller via the <literal>class-to-be-bound</literal> child tag:
</para>
<programlisting><![CDATA[<oxm:jaxb2-marshaller id="marshaller">
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Airport"/>
<oxm:class-to-be-bound name="org.springframework.ws.samples.airline.schema.Flight"/>
...
</oxm:jaxb2-marshaller>
]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>Description</entry>
<entry>Required</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>id</literal></entry>
<entry>the id of the marshaller</entry>
<entry>no</entry>
</row>
<row>
<entry><literal>contextPath</literal></entry>
<entry>the JAXB Context path</entry>
<entry>no</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</section>
</section>
<section id="oxm-castor">
<title>Castor</title>
<para>
Castor XML mapping is an open source XML binding framework. It allows you to transform the data contained in
a java object model into/from an XML document. By default, it does not require any further configuration,
though a mapping file can be used to have more control over the behavior of Castor.
</para>
<para>
For more information on Castor, refer to the <ulink url="http://castor.org/xml-framework.html">
<citetitle>Castor web site</citetitle></ulink>. The Spring integration classes reside in the
<package>org.springframework.oxm.castor</package> package.
</para>
<section>
<title>CastorMarshaller</title>
<para>
As with JAXB, the <classname>CastorMarshaller</classname> implements both the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
It can be wired up as follows:
</para>
<programlisting><![CDATA[
<beans>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" />
...
</beans>]]></programlisting>
</section>
<section>
<title>Mapping</title>
<para>
Although it is possible to rely on Castor's default marshalling behavior, it might be necessary to have
more control over it. This can be accomplished using a Castor mapping file. For more information, refer
to <ulink url="http://castor.org/xml-mapping.html">Castor XML Mapping</ulink>.
</para>
<para>
The mapping can be set using the <property>mappingLocation</property> resource property, indicated
below with a classpath resource.
</para>
<programlisting><![CDATA[
<beans>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" >
<property name="mappingLocation" value="classpath:mapping.xml" />
</bean>
</beans>
]]></programlisting>
</section>
</section>
<section id="oxm-xmlbeans">
<title>XMLBeans</title>
<para>
XMLBeans is an XML binding tool that has full XML Schema support, and offers full XML Infoset
fidelity. It takes a different approach to that of most other O/X mapping frameworks, in that
all classes that are generated from an XML Schema are all derived from
<interfacename>XmlObject</interfacename>, and contain XML binding information in them.
</para>
<para>
For more information on XMLBeans, refer to the <ulink url="http://xmlbeans.apache.org/">
<citetitle>XMLBeans web site </citetitle></ulink>. The Spring-WS integration classes reside
in the <package>org.springframework.oxm.xmlbeans</package> package.
</para>
<section>
<title>XmlBeansMarshaller</title>
<para>
The <classname>XmlBeansMarshaller</classname>
implements both the <interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>
interfaces. It can be configured as follows:
</para>
<programlisting><![CDATA[
<beans>
<bean id="xmlBeansMarshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />
...
</beans>]]></programlisting>
<note>
<para>
Note that the <classname>XmlBeansMarshaller</classname>
can only marshal objects of type <interfacename>XmlObject</interfacename>,
and not every <classname>java.lang.Object</classname>.
</para>
</note>
<section id="oxm-xmlbeans-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>xmlbeans-marshaller</literal> tag configures a <classname>org.springframework.oxm.xmlbeans.XmlBeansMarshaller</classname>.
Here is an example:
</para>
<programlisting><![CDATA[<oxm:xmlbeans-marshaller id="marshaller"/>]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>Description</entry>
<entry>Required</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>id</literal></entry>
<entry>the id of the marshaller</entry>
<entry>no</entry>
</row>
<row>
<entry><literal>options</literal></entry>
<entry>the bean name of the XmlOptions that is to be used for this marshaller. Typically a
<classname>XmlOptionsFactoryBean</classname> definition</entry>
<entry>no</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</section>
</section>
<section id="oxm-jibx">
<title>JiBX</title>
<para>
The JiBX framework offers a solution similar to that which JDO provides for ORM: a binding definition defines the
rules for how your Java objects are converted to or from XML. After preparing the binding and compiling the
classes, a JiBX binding compiler enhances the class files, and adds code to handle converting instances of
the classes from or to XML.
</para>
<para>
For more information on JiBX, refer to the <ulink url="http://jibx.sourceforge.net/">
<citetitle>JiBX web site</citetitle></ulink>. The Spring integration classes reside in the
<package>org.springframework.oxm.jibx</package> package.
</para>
<section>
<title>JibxMarshaller</title>
<para>
The <classname>JibxMarshaller</classname> class implements both the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename> interface.
To operate, it requires the name of the class to marshall in, which you can set using the
<property>targetClass</property> property. Optionally, you can set the binding name using the
<property>bindingName</property> property. In the next sample, we bind the
<classname>Flights</classname> class:
</para>
<programlisting><![CDATA[
<beans>
<bean id="jibxFlightsMarshaller" class="org.springframework.oxm.jibx.JibxMarshaller">
<property name="targetClass">org.springframework.oxm.jibx.Flights</property>
</bean>
...
]]></programlisting>
<para>
A <classname>JibxMarshaller</classname> is configured for a single class. If you want to marshal
multiple classes, you have to configure multiple <classname>JibxMarshaller</classname>s with
different <property>targetClass</property> property values.
</para>
<section id="oxm-jibx-xsd">
<title>XML Schema-based Configuration</title>
<para>
The <literal>jibx-marshaller</literal> tag configures a <classname>org.springframework.oxm.jibx.JibxMarshaller</classname>.
Here is an example:
</para>
<programlisting><![CDATA[<oxm:jibx-marshaller id="marshaller" target-class="org.springframework.ws.samples.airline.schema.Flight"/>]]></programlisting>
<para>
Available attributes are:
<informaltable>
<tgroup cols="3">
<colspec colwidth="1.5*"/>
<colspec colwidth="4*"/>
<colspec colwidth="1*"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>Description</entry>
<entry>Required</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>id</literal></entry>
<entry>the id of the marshaller</entry>
<entry>no</entry>
</row>
<row>
<entry><literal>target-class</literal></entry>
<entry>the target class for this marshaller</entry>
<entry>yes</entry>
</row>
<row>
<entry><literal>bindingName</literal></entry>
<entry>the binding name used by this marshaller</entry>
<entry>no</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
</section>
</section>
<section id="oxm-xstream">
<title>XStream</title>
<para>
XStream is a simple library to serialize objects to XML and back again. It does not require any mapping, and
generates clean XML.
</para>
<para>
For more information on XStream, refer to the <ulink url="http://xstream.codehaus.org/">
<citetitle>XStream web site</citetitle></ulink>. The Spring integration classes reside in the
<package>org.springframework.oxm.xstream</package> package.
</para>
<section>
<title>XStreamMarshaller</title>
<para>
The <classname>XStreamMarshaller</classname> does not require any configuration, and can be configured
in an application context directly. To further customize the XML, you can set an
<emphasis>alias map</emphasis>, which consists of string aliases mapped to classes:
</para>
<programlisting><![CDATA[
<beans>
<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="aliases">
<props>
<prop key="Flight">org.springframework.oxm.xstream.Flight</prop>
</props>
</property>
</bean>
...
</beans>]]></programlisting>
<note>
<para>
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 usage within Web services.
</para>
</note>
</section>
</section>
</chapter>

View File

@ -16,6 +16,7 @@
<!ENTITY dao SYSTEM "dao.xml">
<!ENTITY jdbc SYSTEM "jdbc.xml">
<!ENTITY orm SYSTEM "orm.xml">
<!ENTITY oxm SYSTEM "oxm.xml">
<!ENTITY mvc SYSTEM "mvc.xml">
<!ENTITY view SYSTEM "view.xml">
<!ENTITY web-integration SYSTEM "web-integration.xml">
@ -221,18 +222,18 @@
&aop-api;
&testing;
</part>
<part id="spring-middle-tier">
<title>Middle Tier Data Access</title>
<partintro id="spring-middle-tier-intro">
<part id="spring-data-tier">
<title>Data Access</title>
<partintro id="spring-data-tier-intro">
<para>
This part of the reference documentation is concerned
with the middle tier, and specifically the data access
responsibilities of said tier.
with data access and the interaction between the data access
layer and the business or service layer.
</para>
<para>
Spring's comprehensive transaction management support is
covered in some detail, followed by thorough coverage of
the various middle tier data access frameworks and
the various data access frameworks and
technologies that the Spring Framework integrates with.
</para>
<itemizedlist>
@ -248,12 +249,16 @@
<listitem>
<para><xref linkend="orm"/></para>
</listitem>
<listitem>
<para><xref linkend="oxm"/></para>
</listitem>
</itemizedlist>
</partintro>
&transaction;
&dao;
&jdbc;
&orm;
&oxm;
</part>
<part id="spring-web">
<title>The Web</title>