SWS-267
This commit is contained in:
@@ -11,14 +11,21 @@
|
||||
<section id="web-service-messages">
|
||||
<title>Web service messages</title>
|
||||
<section id="web-service-message">
|
||||
<title><interfacename>WebServiceMessage</interfacename></title>
|
||||
<title>
|
||||
<interfacename>WebServiceMessage</interfacename>
|
||||
</title>
|
||||
<para>
|
||||
One of the core interfaces of Spring Web Services is the <interfacename>WebServiceMessage</interfacename>.
|
||||
One of the core interfaces of Spring Web Services is the
|
||||
<interfacename>WebServiceMessage</interfacename>.
|
||||
This interface represents a protocol-agnostic XML message. The interface contains methods that provide
|
||||
access to the payload of the message, in the form of a
|
||||
<interfacename>javax.xml.transform.Source</interfacename> or a
|
||||
<interfacename>javax.xml.transform.Result</interfacename>. <interfacename>Source</interfacename> and
|
||||
<interfacename>Result</interfacename> are tagging interfaces that represent an abstraction over XML
|
||||
<interfacename>javax.xml.transform.Source</interfacename>
|
||||
or a
|
||||
<interfacename>javax.xml.transform.Result</interfacename>.
|
||||
<interfacename>Source</interfacename>
|
||||
and
|
||||
<interfacename>Result</interfacename>
|
||||
are tagging interfaces that represent an abstraction over XML
|
||||
input and output. Concrete implementations wrap various XML representations, as indicated in the
|
||||
following table.
|
||||
<informaltable>
|
||||
@@ -31,27 +38,45 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><classname>javax.xml.transform.dom.DOMSource</classname></entry>
|
||||
<entry><interfacename>org.w3c.dom.Node</interfacename></entry>
|
||||
<entry>
|
||||
<classname>javax.xml.transform.dom.DOMSource</classname>
|
||||
</entry>
|
||||
<entry>
|
||||
<interfacename>org.w3c.dom.Node</interfacename>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><classname>javax.xml.transform.dom.DOMResult</classname></entry>
|
||||
<entry><interfacename>org.w3c.dom.Node</interfacename></entry>
|
||||
<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.SAXSource</classname></entry>
|
||||
<entry><classname>org.xml.sax.InputSource</classname> and
|
||||
<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.sax.SAXResult</classname></entry>
|
||||
<entry><interfacename>org.xml.sax.ContentHandler</interfacename></entry>
|
||||
<entry>
|
||||
<classname>javax.xml.transform.sax.SAXResult</classname>
|
||||
</entry>
|
||||
<entry>
|
||||
<interfacename>org.xml.sax.ContentHandler</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>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>
|
||||
@@ -60,7 +85,7 @@
|
||||
<classname>javax.xml.transform.stream.StreamResult</classname>
|
||||
</entry>
|
||||
<entry>
|
||||
<classname>java.io.File</classname>, <classname>java.io.OutputStream</classname>, or
|
||||
<classname>java.io.File</classname>,<classname>java.io.OutputStream</classname>, or
|
||||
<classname>java.io.Writer</classname>
|
||||
</entry>
|
||||
</row>
|
||||
@@ -72,40 +97,63 @@
|
||||
</para>
|
||||
</section>
|
||||
<section id="soap-message">
|
||||
<title><interfacename>SoapMessage</interfacename></title>
|
||||
<title>
|
||||
<interfacename>SoapMessage</interfacename>
|
||||
</title>
|
||||
<para>
|
||||
The <interfacename>SoapMessage</interfacename> is a subclass of
|
||||
The
|
||||
<interfacename>SoapMessage</interfacename>
|
||||
is a subclass of
|
||||
<interfacename>WebServiceMessage</interfacename>. It contains SOAP-specific methods, such as getting
|
||||
SOAP Headers, SOAP Faults, etc. Generally, your code should not be dependent on
|
||||
<interfacename>SoapMessage</interfacename>, because the content of the SOAP Body can be obtained via
|
||||
<methodname>getPayloadSource()</methodname> and <methodname>getPayloadResult()</methodname> in the
|
||||
<methodname>getPayloadSource()</methodname>
|
||||
and
|
||||
<methodname>getPayloadResult()</methodname>
|
||||
in the
|
||||
<interfacename>WebServiceMessage</interfacename>. Only when it is necessary to perform SOAP-specific
|
||||
actions, such as adding a header, get an attachment, etc., should you need to cast
|
||||
<interfacename>WebServiceMessage</interfacename> to <interfacename>SoapMessage</interfacename>.
|
||||
<interfacename>WebServiceMessage</interfacename>
|
||||
to<interfacename>SoapMessage</interfacename>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="message-factories">
|
||||
<title>Message Factories</title>
|
||||
<para>
|
||||
Concrete message implementations are created by a <interfacename>WebServiceMessageFactory</interfacename>.
|
||||
Concrete message implementations are created by a
|
||||
<interfacename>WebServiceMessageFactory</interfacename>.
|
||||
This factory can create an empty message, or read a message based on an input stream. There are two
|
||||
concrete implementations of <interfacename>WebServiceMessageFactory</interfacename>; one is based on
|
||||
concrete implementations of<interfacename>WebServiceMessageFactory</interfacename>; one is based on
|
||||
SAAJ, the SOAP with Attachments API for Java, the other based on Axis 2's AXIOM, the AXis Object Model.
|
||||
</para>
|
||||
<section>
|
||||
<title><classname>SaajSoapMessageFactory</classname></title>
|
||||
<title>
|
||||
<classname>SaajSoapMessageFactory</classname>
|
||||
</title>
|
||||
<para>
|
||||
The <classname>SaajSoapMessageFactory</classname> uses the SOAP with Attachments API for Java to
|
||||
create <classname>SoapMessage</classname> implementations. <acronym>SAAJ</acronym> is part of
|
||||
<acronym>J2EE</acronym> 1.4, so it should be supported under most modern application servers.
|
||||
Here is an overview of the <acronym>SAAJ</acronym> versions supplied
|
||||
The
|
||||
<classname>SaajSoapMessageFactory</classname>
|
||||
uses the SOAP with Attachments API for Java to
|
||||
create
|
||||
<classname>SoapMessage</classname>
|
||||
implementations.
|
||||
<acronym>SAAJ</acronym>
|
||||
is part of
|
||||
<acronym>J2EE</acronym>
|
||||
1.4, so it should be supported under most modern application servers.
|
||||
Here is an overview of the
|
||||
<acronym>SAAJ</acronym>
|
||||
versions supplied
|
||||
by common application servers:
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Application Server</entry>
|
||||
<entry><acronym>SAAJ</acronym> Version</entry>
|
||||
<entry>
|
||||
<acronym>SAAJ</acronym>
|
||||
Version
|
||||
</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -115,15 +163,22 @@
|
||||
</row>
|
||||
<row>
|
||||
<entry>BEA WebLogic 9</entry>
|
||||
<entry>1.1/1.2<footnote>
|
||||
<para>
|
||||
Weblogic 9 has a known bug in the <acronym>SAAJ</acronym> 1.2
|
||||
implementation: it implement all the 1.2 interfaces, but throws a
|
||||
<classname>UnsupportedOperationException</classname> when called.
|
||||
Spring Web Services has a workaround: it uses <acronym>SAAJ</acronym> 1.1
|
||||
when operating on WebLogic 9.
|
||||
</para>
|
||||
</footnote></entry>
|
||||
<entry>1.1/1.2
|
||||
<footnote>
|
||||
<para>
|
||||
Weblogic 9 has a known bug in the
|
||||
<acronym>SAAJ</acronym>
|
||||
1.2
|
||||
implementation: it implement all the 1.2 interfaces, but throws a
|
||||
<classname>UnsupportedOperationException</classname>
|
||||
when called.
|
||||
Spring Web Services has a workaround: it uses
|
||||
<acronym>SAAJ</acronym>
|
||||
1.1
|
||||
when operating on WebLogic 9.
|
||||
</para>
|
||||
</footnote>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>IBM WebSphere 6</entry>
|
||||
@@ -136,36 +191,53 @@
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
Additionally, Java SE 6 includes <acronym>SAAJ</acronym> 1.3.
|
||||
Additionally, Java SE 6 includes
|
||||
<acronym>SAAJ</acronym>
|
||||
1.3.
|
||||
You wire up a
|
||||
<classname>SaajSoapMessageFactory</classname> like so:
|
||||
<programlisting><![CDATA[<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />]]></programlisting>
|
||||
<classname>SaajSoapMessageFactory</classname>
|
||||
like so:
|
||||
<programlisting><![CDATA[<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />]]></programlisting>
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
<acronym>SAAJ</acronym> is based on DOM, the Document Object Model. This means that all SOAP messages are
|
||||
stored <emphasis>in memory</emphasis>. For larger SOAP messages, this may not be very performant.
|
||||
In that case, the <classname>AxiomSoapMessageFactory</classname> might be more applicable.
|
||||
<acronym>SAAJ</acronym>
|
||||
is based on DOM, the Document Object Model. This means that all SOAP messages are
|
||||
stored<emphasis>in memory</emphasis>. For larger SOAP messages, this may not be very performant.
|
||||
In that case, the
|
||||
<classname>AxiomSoapMessageFactory</classname>
|
||||
might be more applicable.
|
||||
</para>
|
||||
</note>
|
||||
</section>
|
||||
<section>
|
||||
<title><classname>AxiomSoapMessageFactory</classname></title>
|
||||
<title>
|
||||
<classname>AxiomSoapMessageFactory</classname>
|
||||
</title>
|
||||
<para>
|
||||
The <classname>AxiomSoapMessageFactory</classname> uses the AXis 2 Object Model to create
|
||||
<interfacename>SoapMessage</interfacename> implementations. <acronym>AXIOM</acronym> is based on
|
||||
The
|
||||
<classname>AxiomSoapMessageFactory</classname>
|
||||
uses the AXis 2 Object Model to create
|
||||
<interfacename>SoapMessage</interfacename>
|
||||
implementations.
|
||||
<acronym>AXIOM</acronym>
|
||||
is based on
|
||||
<acronym>StAX</acronym>, the Streaming API for XML. StAX provides a pull-based mechanism for
|
||||
reading XML messages, which can be more efficient for larger messages.
|
||||
</para>
|
||||
<para>
|
||||
To increase reading performance on the <classname>AxiomSoapMessageFactory</classname>,
|
||||
you can set the <property>payloadCaching</property> property to false (default is true).
|
||||
To increase reading performance on the<classname>AxiomSoapMessageFactory</classname>,
|
||||
you can set the
|
||||
<property>payloadCaching</property>
|
||||
property to false (default is true).
|
||||
This will read the contents of the SOAP body directly from the stream.
|
||||
When this setting is enabled, the payload can only be read once.
|
||||
This means that you have to make sure that any preprocessing of the message does not consume it.
|
||||
</para>
|
||||
<para>
|
||||
You use the <classname>AxiomSoapMessageFactory</classname> as follows:
|
||||
You use the
|
||||
<classname>AxiomSoapMessageFactory</classname>
|
||||
as follows:
|
||||
<programlisting><![CDATA[
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
|
||||
<property name="payloadCaching" value="true"/>
|
||||
@@ -173,11 +245,21 @@
|
||||
</para>
|
||||
</section>
|
||||
<section id="soap_11_or_12">
|
||||
<title><acronym>SOAP</acronym> 1.1 or 1.2</title>
|
||||
<title>
|
||||
<acronym>SOAP</acronym>
|
||||
1.1 or 1.2
|
||||
</title>
|
||||
<para>
|
||||
Both the <classname>SaajSoapMessageFactory</classname> and the
|
||||
<classname>AxiomSoapMessageFactory</classname> have a <property>soapVersion</property> property,
|
||||
where you can inject a <interfacename>SoapVersion</interfacename> constant. By default, the version
|
||||
Both the
|
||||
<classname>SaajSoapMessageFactory</classname>
|
||||
and the
|
||||
<classname>AxiomSoapMessageFactory</classname>
|
||||
have a
|
||||
<property>soapVersion</property>
|
||||
property,
|
||||
where you can inject a
|
||||
<interfacename>SoapVersion</interfacename>
|
||||
constant. By default, the version
|
||||
is 1.1, but you can set it to 1.2 like so:
|
||||
</para>
|
||||
<programlisting><![CDATA[
|
||||
@@ -197,50 +279,73 @@
|
||||
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
In the example above, we define a <classname>SaajSoapMessageFactory</classname> that only accepts
|
||||
<acronym>SOAP</acronym> 1.2 messages.
|
||||
In the example above, we define a
|
||||
<classname>SaajSoapMessageFactory</classname>
|
||||
that only accepts
|
||||
<acronym>SOAP</acronym>
|
||||
1.2 messages.
|
||||
</para>
|
||||
<caution>
|
||||
<para>
|
||||
Even though both versions of <acronym>SOAP</acronym> are quite similar in format, the 1.2
|
||||
Even though both versions of
|
||||
<acronym>SOAP</acronym>
|
||||
are quite similar in format, the 1.2
|
||||
version is not backwards compatible with 1.1 because it uses a different XML namespace.
|
||||
Other major differences between <acronym>SOAP</acronym> 1.1 and 1.2 include the different structure
|
||||
of a Fault, and the fact that <literal>SOAPAction</literal> HTTP headers are deprecated, which
|
||||
means that you cannot use the <link linkend="server-soap-action-endpoint-mapping">
|
||||
<classname>SoapActionEndpointMapping</classname></link> or the
|
||||
Other major differences between
|
||||
<acronym>SOAP</acronym>
|
||||
1.1 and 1.2 include the different structure
|
||||
of a Fault, and the fact that
|
||||
<literal>SOAPAction</literal>
|
||||
HTTP headers are deprecated, which
|
||||
means that you cannot use the
|
||||
<link linkend="server-soap-action-endpoint-mapping">
|
||||
<classname>SoapActionEndpointMapping</classname>
|
||||
</link>
|
||||
or the
|
||||
<classname>SoapActionAnnotationMethodEndpointMapping</classname>.
|
||||
</para>
|
||||
<para>
|
||||
One important thing to note with <acronym>SOAP</acronym> version numbers, or WS-* specification
|
||||
One important thing to note with
|
||||
<acronym>SOAP</acronym>
|
||||
version numbers, or WS-* specification
|
||||
version numbers in general, is that the latest version of a specification is
|
||||
generally not the most popular version.
|
||||
For <acronym>SOAP</acronym>, this means that currently, the best version to use is 1.1.
|
||||
For<acronym>SOAP</acronym>, this means that currently, the best version to use is 1.1.
|
||||
Version 1.2 might become more popular in the future, but currently 1.1 is the safest bet.
|
||||
</para>
|
||||
</caution>
|
||||
</section>
|
||||
</section>
|
||||
<section id="message-context">
|
||||
<title><interfacename>MessageContext</interfacename></title>
|
||||
<para>
|
||||
Typically, messages come in pairs: a request and a response. A request is created on the client-side,
|
||||
<title>
|
||||
<interfacename>MessageContext</interfacename>
|
||||
</title>
|
||||
<para>
|
||||
Typically, messages come in pairs: a request and a response. A request is created on the client-side,
|
||||
which is sent over some transport to the server-side, where a response is generated. This response gets
|
||||
sent back to the client, where it is read.
|
||||
</para>
|
||||
<para>
|
||||
In Spring Web Services, such a conversation is contained in a
|
||||
<interfacename>MessageContext</interfacename>, which has properties to get request and response
|
||||
messages.
|
||||
On the client-side, the message context is created by the <link linkend="client-web-service-template">
|
||||
<classname>WebServiceTemplate</classname></link>.
|
||||
On the server-side, the message context is read from the transport-specific input stream.
|
||||
For example, in HTTP, it is read from the <interfacename>HttpServletRequest</interfacename> and the
|
||||
response is written back to the <interfacename>HttpServletResponse</interfacename>.
|
||||
</para>
|
||||
sent back to the client, where it is read.
|
||||
</para>
|
||||
<para>
|
||||
In Spring Web Services, such a conversation is contained in a
|
||||
<interfacename>MessageContext</interfacename>, which has properties to get request and response
|
||||
messages.
|
||||
On the client-side, the message context is created by the
|
||||
<link linkend="client-web-service-template">
|
||||
<classname>WebServiceTemplate</classname>
|
||||
</link>
|
||||
.
|
||||
On the server-side, the message context is read from the transport-specific input stream.
|
||||
For example, in HTTP, it is read from the
|
||||
<interfacename>HttpServletRequest</interfacename>
|
||||
and the
|
||||
response is written back to the<interfacename>HttpServletResponse</interfacename>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="transport-context">
|
||||
<title><interfacename>TransportContext</interfacename></title>
|
||||
<title>
|
||||
<interfacename>TransportContext</interfacename>
|
||||
</title>
|
||||
<para>
|
||||
One of the key properties of the SOAP protocol is that it tries to be transport-agnostic. This is why, for
|
||||
instance, Spring-WS does not support mapping messages to endpoints by HTTP request URL, but
|
||||
@@ -248,10 +353,15 @@
|
||||
</para>
|
||||
<para>
|
||||
However, sometimes it is necessary to get access to the underlying transport, either on the client or server
|
||||
side. For this, Spring Web Services has the <interfacename>TransportContext</interfacename>. The transport
|
||||
context allows access to the underlying <interfacename>WebServiceConnection</interfacename>, which typically
|
||||
is a <classname>HttpServletConnection</classname> on the server side; or a
|
||||
<classname>HttpUrlConnection</classname> or <classname>CommonsHttpConnection</classname> on the client side.
|
||||
side. For this, Spring Web Services has the<interfacename>TransportContext</interfacename>. The transport
|
||||
context allows access to the underlying<interfacename>WebServiceConnection</interfacename>, which typically
|
||||
is a
|
||||
<classname>HttpServletConnection</classname>
|
||||
on the server side; or a
|
||||
<classname>HttpUrlConnection</classname>
|
||||
or
|
||||
<classname>CommonsHttpConnection</classname>
|
||||
on the client side.
|
||||
For example, you can obtain the IP address of the current request in a server-side endpoint or
|
||||
interceptor like so:
|
||||
</para>
|
||||
@@ -265,7 +375,7 @@ String ipAddress = request.getRemoteAddr();]]></programlisting>
|
||||
<title>Handling XML With XPath</title>
|
||||
<para>
|
||||
One of the best ways to handle XML is to use XPath.
|
||||
Quoting <xref linkend="effective-xml"/>, item 35:
|
||||
Quoting<xref linkend="effective-xml"/>, item 35:
|
||||
</para>
|
||||
<blockquote>
|
||||
<para>
|
||||
@@ -282,14 +392,20 @@ String ipAddress = request.getRemoteAddr();]]></programlisting>
|
||||
</blockquote>
|
||||
<para>
|
||||
Spring Web Services has two ways to use XPath within your application: the faster
|
||||
<interfacename>XPathExpression</interfacename> or the more flexible <classname>XPathTemplate</classname>.
|
||||
<interfacename>XPathExpression</interfacename>
|
||||
or the more flexible<classname>XPathTemplate</classname>.
|
||||
</para>
|
||||
<section id="xpath-expression">
|
||||
<title><interfacename>XPathExpression</interfacename></title>
|
||||
<title>
|
||||
<interfacename>XPathExpression</interfacename>
|
||||
</title>
|
||||
<para>
|
||||
The <interfacename>XPathExpression</interfacename> is an abstraction over a compiled XPath expression,
|
||||
such as the Java 5 <interfacename>javax.xml.xpath.XPathExpression</interfacename>, or the Jaxen
|
||||
<classname>XPath</classname> class.
|
||||
The
|
||||
<interfacename>XPathExpression</interfacename>
|
||||
is an abstraction over a compiled XPath expression,
|
||||
such as the Java 5<interfacename>javax.xml.xpath.XPathExpression</interfacename>, or the Jaxen
|
||||
<classname>XPath</classname>
|
||||
class.
|
||||
To construct an expression in an application context, there is the
|
||||
<classname>XPathExpressionFactoryBean</classname>. Here is an example which uses this factory bean:
|
||||
</para>
|
||||
@@ -309,7 +425,8 @@ String ipAddress = request.getRemoteAddr();]]></programlisting>
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
The expression above does not use namespaces, but we could set those using the
|
||||
<property>namespaces</property> property of the factory bean. The expression
|
||||
<property>namespaces</property>
|
||||
property of the factory bean. The expression
|
||||
can be used in the code as follows:
|
||||
</para>
|
||||
<programlisting><![CDATA[package sample;
|
||||
@@ -329,8 +446,10 @@ public class MyXPathClass {
|
||||
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
For a more flexible approach, you can use a <interfacename>NodeMapper</interfacename>, which is similar
|
||||
to the <interfacename>RowMapper</interfacename> in Spring's JDBC support. The following
|
||||
For a more flexible approach, you can use a<interfacename>NodeMapper</interfacename>, which is similar
|
||||
to the
|
||||
<interfacename>RowMapper</interfacename>
|
||||
in Spring's JDBC support. The following
|
||||
example shows how we can use it:
|
||||
</para>
|
||||
<programlisting><![CDATA[package sample;
|
||||
@@ -344,7 +463,7 @@ public class MyXPathClass {
|
||||
}
|
||||
|
||||
public void doXPath(Document document) {
|
||||
List contacts = nameExpression.evaluate(requestElement,
|
||||
List contacts = contactExpression.evaluate(document,
|
||||
new NodeMapper() {
|
||||
public Object mapNode(Node node, int nodeNum) throws DOMException {
|
||||
Element contactElement = (Element) node;
|
||||
@@ -353,20 +472,32 @@ public class MyXPathClass {
|
||||
return new Contact(nameElement.getTextContent(), phoneElement.getTextContent());
|
||||
}
|
||||
});
|
||||
]]><lineannotation>// do something with list of <classname>Contact</classname> objects</lineannotation><![CDATA[
|
||||
]]>
|
||||
<lineannotation>// do something with list of
|
||||
<classname>Contact</classname>
|
||||
objects
|
||||
</lineannotation>
|
||||
<![CDATA[
|
||||
}
|
||||
}]]></programlisting>
|
||||
}]]>
|
||||
</programlisting>
|
||||
<para>
|
||||
Similar to mapping rows in Spring JDBC's <interfacename>RowMapper</interfacename>, each result node is
|
||||
mapped using an anonymous inner class. In this case, we create a <classname>Contact</classname> object,
|
||||
Similar to mapping rows in Spring JDBC's<interfacename>RowMapper</interfacename>, each result node is
|
||||
mapped using an anonymous inner class. In this case, we create a
|
||||
<classname>Contact</classname>
|
||||
object,
|
||||
which we use later on.
|
||||
</para>
|
||||
</section>
|
||||
<section id="xpath-template">
|
||||
<title><classname>XPathTemplate</classname></title>
|
||||
<title>
|
||||
<classname>XPathTemplate</classname>
|
||||
</title>
|
||||
<para>
|
||||
The <interfacename>XPathExpression</interfacename> only allows you to evaluate a single, pre-compiled
|
||||
expression. A more flexible, though slower, alternative is the <classname>XpathTemplate</classname>.
|
||||
The
|
||||
<interfacename>XPathExpression</interfacename>
|
||||
only allows you to evaluate a single, pre-compiled
|
||||
expression. A more flexible, though slower, alternative is the<classname>XpathTemplate</classname>.
|
||||
This class follows the common template pattern used throughout Spring (JdbcTemplate, JmsTemplate, etc.).
|
||||
Here is an example:
|
||||
</para>
|
||||
@@ -381,7 +512,8 @@ public class MyXPathClass {
|
||||
]]><lineannotation>// do something with name</lineannotation><![CDATA[
|
||||
}
|
||||
|
||||
}]]></programlisting>
|
||||
}]]>
|
||||
</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user