Docs
This commit is contained in:
@@ -33,11 +33,8 @@
|
||||
<outputDirectory>docs/api</outputDirectory>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>doc/target/docbkx</directory>
|
||||
<directory>target/site/reference</directory>
|
||||
<outputDirectory>docs/reference</outputDirectory>
|
||||
<excludes>
|
||||
<exclude>**/*.fo</exclude>
|
||||
</excludes>
|
||||
</fileSet>
|
||||
<!-- Samples -->
|
||||
<fileSet>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<chapter id="common">
|
||||
<title>Shared components</title>
|
||||
<para>
|
||||
In this chapter, we will explore the the components which are shared between client- and server side
|
||||
In this chapter, we will explore the the components which are shared between client- and server side
|
||||
Spring-WS development. These interfaces and classes represent the building blocks of Spring-WS, so
|
||||
it's important to understand what they do, even if you do not use them directly.
|
||||
</para>
|
||||
@@ -13,10 +13,10 @@
|
||||
<section id="web-service-message">
|
||||
<title><interfacename>WebServiceMessage</interfacename></title>
|
||||
<para>
|
||||
One of the core interfaces within Spring Web Services is the
|
||||
One of the core interfaces within 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
|
||||
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
|
||||
input and output. Concrete implementations wrap various XML representations, as indicated in the table
|
||||
@@ -74,39 +74,39 @@
|
||||
<section id="soap-message">
|
||||
<title><interfacename>SoapMessage</interfacename></title>
|
||||
<para>
|
||||
The <interfacename>SoapMessage</interfacename> is an extension of
|
||||
The <interfacename>SoapMessage</interfacename> is an extension of
|
||||
<interfacename>WebServiceMessage</interfacename>. It contains SOAP-specific methods, such as getting
|
||||
SOAP Headers, SOAP Faults, etc. Generally, your code should only not be dependent on
|
||||
SOAP Headers, SOAP Faults, etc. Generally, your code should only 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
|
||||
<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
|
||||
<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>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="message-factories">
|
||||
<title>Message Factories</title>
|
||||
<para>
|
||||
Concrete message implementation are created by a
|
||||
Concrete message implementation 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 SAAJ, the SOAP with Attachments API for Java, the other based on Axis 2's AXIOM, the
|
||||
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>
|
||||
<para>
|
||||
The <classname>SaajSoapMessageFactory</classname> uses the SOAP with Attachments API for Java to
|
||||
create <classname>SoapMessage</classname> implementations. SAAJ is part of J2EE 1.4, so it should be
|
||||
supported under most modern application servers. You wire up a
|
||||
The <classname>SaajSoapMessageFactory</classname> uses the SOAP with Attachments API for Java to
|
||||
create <classname>SoapMessage</classname> implementations. SAAJ is part of J2EE 1.4, so it should be
|
||||
supported under most modern application servers. You wire up a
|
||||
<classname>SaajSoapMessageFactory</classname> like so:
|
||||
<programlisting><![CDATA[
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />]]></programlisting>
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
SAAJ is based on DOM, the Document Object Model. This means that all SOAP messages are
|
||||
SAAJ is based on DOM, the Document Object Model. This means that all SOAP messages are
|
||||
stored in memory as a whole. For larger SOAP messages, this may not be very performant.
|
||||
In that case, the <classname>AxiomSoapMessageFactory</classname> might be more applicable.
|
||||
</para>
|
||||
@@ -115,15 +115,15 @@
|
||||
<section>
|
||||
<title><classname>AxiomSoapMessageFactory</classname></title>
|
||||
<para>
|
||||
The <classname>AxiomSoapMessageFactory</classname> uses the AXis 2 Object Model to create
|
||||
<interfacename>SoapMessage</interfacename> implementations. AXIOM is based on StAX, the Streaming
|
||||
API for XML. StAX provides a pull-based mechanism for reading XML messages, which can be more
|
||||
The <classname>AxiomSoapMessageFactory</classname> uses the AXis 2 Object Model to create
|
||||
<interfacename>SoapMessage</interfacename> implementations. AXIOM is based on StAX, 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>,
|
||||
To increase reading performance on the <classname>AxiomSoapMessageFactory</classname>,
|
||||
you can set the <property>payloadCaching</property> property to false (default is true).
|
||||
This this will read the contents of the SOAP body directly from the stream.
|
||||
This 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>
|
||||
@@ -133,7 +133,7 @@
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
|
||||
<property name="payloadCaching" value="true"/>
|
||||
</bean>]]></programlisting>
|
||||
</para>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="message-context">
|
||||
@@ -144,7 +144,7 @@
|
||||
sent back to the client, where it is read.
|
||||
</para>
|
||||
<para>
|
||||
In Spring Web Services, such a conversation is contained in a
|
||||
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">
|
||||
@@ -159,21 +159,30 @@
|
||||
<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:
|
||||
<blockquote>
|
||||
<para>
|
||||
XPath is a fourth generation declarative language that allows you to specify which nodes you want to
|
||||
process without specifying exactly how the processor is supposed to navigate to those nodes. XPath's
|
||||
data model is very well designed to support exactly what almost all developers want from XML. For
|
||||
instance, it merges all adjacent text including that in CDATA sections, allows values to be
|
||||
calculated that skip over comments and processing instructions` and include text from child and
|
||||
descendant elements, and requires all external entity references to be resolved. In practice, XPath
|
||||
expressions tend to be much more robust against unexpected but perhaps insignificant changes in the
|
||||
input document.
|
||||
</para>
|
||||
<attribution>Elliotte Rusty Harold</attribution>
|
||||
</blockquote>
|
||||
</para>
|
||||
<para>
|
||||
<sidebar>
|
||||
<title>What is XPath?</title>
|
||||
<para>
|
||||
XPath is a language for addressing parts of an XML document.
|
||||
For more information about XPath, refer to the
|
||||
<ulink url="http://www.w3.org/TR/xpath">XPath specification</ulink>, or read the
|
||||
<ulink url="http://www.w3schools.com/xpath/">XPath tutorial</ulink>
|
||||
</para>
|
||||
</sidebar>
|
||||
<blockquote>
|
||||
<para>
|
||||
XPath is a fourth generation declarative language that allows you to specify which nodes you want to
|
||||
process without specifying exactly how the processor is supposed to navigate to those nodes. XPath's
|
||||
data model is very well designed to support exactly what almost all developers want from XML. For
|
||||
instance, it merges all adjacent text including that in CDATA sections, allows values to be
|
||||
calculated that skip over comments and processing instructions` and include text from child and
|
||||
descendant elements, and requires all external entity references to be resolved. In practice, XPath
|
||||
expressions tend to be much more robust against unexpected but perhaps insignificant changes in the
|
||||
input document.
|
||||
</para>
|
||||
<attribution>Elliotte Rusty Harold</attribution>
|
||||
</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>.
|
||||
</para>
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
of course <classname>AbstractMarshallingPayloadEndpoint</classname>. Application endpoints will typically
|
||||
be subclasses of those.
|
||||
Alternatively, there is a endpoint development that uses Java 5 annotations, such as
|
||||
<literal>@Endpoint</literal> for marking a POJO as endpoint, and marking a method with
|
||||
<literal>@PayloadRoot</literal> or <literal>@SoapAction</literal>.
|
||||
<interfacename>@Endpoint</interfacename> for marking a POJO as endpoint, and marking a method with
|
||||
<interfacename>@PayloadRoot</interfacename> or <interfacename>@SoapAction</interfacename>.
|
||||
</para>
|
||||
<para>
|
||||
Spring-WS's XML handling is extremely flexible. An endpoint can choose from
|
||||
@@ -253,8 +253,10 @@ public class SampleEndpoint extends AbstractDomPayloadEndpoint {
|
||||
base classes which use alternative DOM APIs. Spring Web Services supports most DOM APIs, so that you
|
||||
can use the one you are familiar with. For instance, the
|
||||
<classname>AbstractJDomPayloadEndpoint</classname> allows you to use JDOM, and the
|
||||
<classname>AbstractXomPayloadEndpoint</classname> uses XOM to handle the XML. All endpoints have an
|
||||
<methodname>invokeInternal</methodname> method similar to above.
|
||||
<classname>AbstractXomPayloadEndpoint</classname> uses XOM to handle the XML. All of these endpoints
|
||||
have an <methodname>invokeInternal</methodname> method similar to above.
|
||||
Also, consider to use Spring-WS's XPath support to extract the information you need out of the payload,
|
||||
see <xref linkend="xpath"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
@@ -295,8 +297,7 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
|
||||
return order;
|
||||
}
|
||||
}]]></programlisting>
|
||||
<programlisting><![CDATA[
|
||||
<beans>
|
||||
<programlisting><![CDATA[<beans>
|
||||
<bean id="orderEndpoint" class="samples.MarshallingOrderEndpoint">
|
||||
<constructor-arg ref="orderService"/>
|
||||
<constructor-arg ref="marshaller"/>
|
||||
@@ -312,6 +313,8 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
|
||||
</bean>
|
||||
|
||||
<bean id="orderService" class="samples.DefaultOrderService"/>
|
||||
|
||||
<!-- Other beans, such as the endpoint mapping -->
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
In this sample, we configure a <link linkend="oxm-jaxb2">Jaxb2Marshaller</link> for the
|
||||
@@ -356,7 +359,74 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>@Endpoint</literal></title>
|
||||
<para/>
|
||||
<para>
|
||||
The previous two programming models were based on inheritance, and handled individual XML mesages.
|
||||
Spring Web Services offer another endpoint with which you aggregate multiple handling into one
|
||||
controller, thus grouping functionality together. This model is based on annotations, so you can only
|
||||
use it under Java 5 and higher. Here is an example that uses the same marshalled objects as above:
|
||||
</para>
|
||||
<programlisting><![CDATA[package samples;
|
||||
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
|
||||
@Endpoint
|
||||
public class AnnotationOrderEndpoint {
|
||||
private final OrderService orderService;
|
||||
|
||||
public AnnotationOrderEndpoint(OrderService orderService) {
|
||||
this.orderService = orderService;
|
||||
}
|
||||
|
||||
@PayloadRoot(localPart = "orderRequest", namespace = "http://samples")
|
||||
public Order getOrder(OrderRequest orderRequest) {
|
||||
return orderService.getOrder(orderRequest.getId());
|
||||
}
|
||||
|
||||
@PayloadRoot(localPart = "order", namespace = "http://samples")
|
||||
public void order(Order order) {
|
||||
orderService.createOrder(order);
|
||||
}
|
||||
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
By annotating the class with <interfacename>@Endpoint</interfacename>, you mark it as a Spring-WS
|
||||
endpoint. Because the endpoint class can have multiple request handling methods, we need to instruct
|
||||
Spring-WS which method to invoke for which request. This is done using the
|
||||
<interfacename>@PayloadRoot</interfacename> annotation: the <methodname>getOrder</methodname> method
|
||||
will be invoked for requests with a <literal>orderRequest</literal> local name, and a
|
||||
<uri>http://samples</uri> namespace URI; the <methodname>order</methodname> method for requests with
|
||||
a <literal>order</literal> local name. For more information about these annotations, refer to
|
||||
<xref linkend="server-method-endpoint-mapping"/>.
|
||||
Obviously, we also need to configure Spring-WS to support the JAXB objects
|
||||
<classname>OrderRequest</classname> and <classname>Order</classname> by defining a
|
||||
<classname>Jaxb2Marshaller</classname>. This is what the configuration
|
||||
looks like:
|
||||
</para>
|
||||
<programlisting><![CDATA[<beans>
|
||||
<bean id="orderEndpoint" class="samples.AnnotationOrderEndpoint">
|
||||
<constructor-arg ref="orderService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="orderService" class="samples.DefaultOrderService"/>
|
||||
|
||||
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
|
||||
<constructor-arg ref="marshaller"/>
|
||||
</bean>
|
||||
|
||||
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
|
||||
<property name="contextPath" value="samples"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
|
||||
|
||||
</beans>]]></programlisting>
|
||||
<para>
|
||||
The <classname>MarshallingMethodEndpointAdapter</classname> converts the incoming
|
||||
XML messages to marshalled objects used as parameters and return value; the
|
||||
<classname>PayloadRootAnnotationMethodEndpointMapping</classname> is the mapping that detects and
|
||||
handles the <interfacename>@PayloadRoot</interfacename> annotations.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="server-endpoint-mapping">
|
||||
@@ -411,66 +481,70 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
|
||||
<title>PayloadRootQNameEndpointMapping</title>
|
||||
<para/>
|
||||
</section>
|
||||
<section id="server-method-endpoint-mapping">
|
||||
<title><classname>MethodEndpointMapping</classname></title>
|
||||
<para/>
|
||||
</section>
|
||||
<section id="server-endpoint-interceptor">
|
||||
<title>Adding <interfacename>EndpointInterceptors</interfacename></title>
|
||||
<para/>
|
||||
</section>
|
||||
<section id="server-endpoint-exception-resolver">
|
||||
<title>Handling Exceptions</title>
|
||||
<para>
|
||||
Spring-WS provides
|
||||
<classname>EndpointExceptionResolvers</classname>
|
||||
to ease the pain of unexpected
|
||||
exceptions occurring while your message is being processed by an endpoint which matched the request.
|
||||
<classname>EndpointExceptionResolver</classname>
|
||||
s somewhat resemble the exception mappings that can be
|
||||
defined in the web application descriptor
|
||||
<filename>web.xml</filename>
|
||||
.
|
||||
Rather than expose the innards of your application by giving a client a full stack trace, you can handle
|
||||
the exception any way you want, e.g. return a SOAP fault with a specific fault code and string.
|
||||
Furthermore, a programmatic way of handling exceptions gives you many more options for how to respond
|
||||
appropriately.
|
||||
</para>
|
||||
<para>
|
||||
Besides implementing the
|
||||
<classname>HandlerExceptionResolver</classname>
|
||||
interface, which is only a
|
||||
matter of implementing the
|
||||
<methodname>resolveException(MessageContext, endpoint, Exception)</methodname>
|
||||
method and returning a
|
||||
boolean, you may also use the
|
||||
<classname>SoapFaultMappingExceptionResolver</classname>
|
||||
.
|
||||
This resolver enables you to take the class name of any exception that might be thrown and map it to a
|
||||
SOAP Fault, like so:
|
||||
<programlisting><![CDATA[
|
||||
</section>
|
||||
<section id="server-endpoint-exception-resolver">
|
||||
<title>Handling Exceptions</title>
|
||||
<para>
|
||||
Spring-WS provides
|
||||
<classname>EndpointExceptionResolvers</classname>
|
||||
to ease the pain of unexpected
|
||||
exceptions occurring while your message is being processed by an endpoint which matched the request.
|
||||
<classname>EndpointExceptionResolver</classname>
|
||||
s somewhat resemble the exception mappings that can be
|
||||
defined in the web application descriptor
|
||||
<filename>web.xml</filename>
|
||||
.
|
||||
Rather than expose the innards of your application by giving a client a full stack trace, you can handle
|
||||
the exception any way you want, e.g. return a SOAP fault with a specific fault code and string.
|
||||
Furthermore, a programmatic way of handling exceptions gives you many more options for how to respond
|
||||
appropriately.
|
||||
</para>
|
||||
<para>
|
||||
Besides implementing the
|
||||
<classname>HandlerExceptionResolver</classname>
|
||||
interface, which is only a
|
||||
matter of implementing the
|
||||
<methodname>resolveException(MessageContext, endpoint, Exception)</methodname>
|
||||
method and returning a
|
||||
boolean, you may also use the
|
||||
<classname>SoapFaultMappingExceptionResolver</classname>
|
||||
.
|
||||
This resolver enables you to take the class name of any exception that might be thrown and map it to a
|
||||
SOAP Fault, like so:
|
||||
<programlisting><![CDATA[
|
||||
<bean id="exceptionResolver"
|
||||
class="org.springframework.ws.soap.endpoint.SoapFaultMappingExceptionResolver">
|
||||
<property name="defaultFault" value="RECEIVER,Server error">
|
||||
</property>
|
||||
<property name="exceptionMappings">
|
||||
<props>
|
||||
<prop key="org.springframework.oxm.ValidationFailureException">
|
||||
SENDER,Invalid request
|
||||
</prop>
|
||||
</props>
|
||||
</property>
|
||||
class="org.springframework.ws.soap.endpoint.SoapFaultMappingExceptionResolver">
|
||||
<property name="defaultFault" value="RECEIVER,Server error">
|
||||
</property>
|
||||
<property name="exceptionMappings">
|
||||
<props>
|
||||
<prop key="org.springframework.oxm.ValidationFailureException">
|
||||
SENDER,Invalid request
|
||||
</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
This configuration will map exceptions of type
|
||||
<classname>ValidationFailureException</classname>
|
||||
to a
|
||||
sender side SOAP Fault with a fault string "Invalid request".
|
||||
If any other exception occurs, it will return the default fault: a server side fault with fault string
|
||||
"Server error".
|
||||
Refer to the Javadoc of
|
||||
<classname>SoapFaultDefinitionEditor</classname>
|
||||
to read more about the exact
|
||||
notation of the faults.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
This configuration will map exceptions of type
|
||||
<classname>ValidationFailureException</classname>
|
||||
to a
|
||||
sender side SOAP Fault with a fault string "Invalid request".
|
||||
If any other exception occurs, it will return the default fault: a server side fault with fault string
|
||||
"Server error".
|
||||
Refer to the Javadoc of
|
||||
<classname>SoapFaultDefinitionEditor</classname>
|
||||
to read more about the exact
|
||||
notation of the faults.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Similarities between Spring-MVC and Spring-WS</title>
|
||||
@@ -535,4 +609,4 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
|
||||
</informaltable>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
||||
@@ -379,7 +379,7 @@
|
||||
</wsdl:binding>
|
||||
<wsdl:service name="HumanResourceService">
|
||||
<wsdl:port binding="tns:HumanResourceBinding" name="HumanResourcePort">
|
||||
<soap:address location="http://mycompany.com/humanresources"/>
|
||||
<soap:address location="http://localhost:8080/holidayService/"/>
|
||||
</wsdl:port>
|
||||
</wsdl:service>
|
||||
</wsdl:definitions>]]></programlisting>
|
||||
@@ -431,7 +431,7 @@
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.address">
|
||||
<para>
|
||||
The <uri>http://mycompany.com/humanresources</uri> address is the URL where the Web
|
||||
The <uri>http://localhost:8080/holidayService/</uri> address is the URL where the Web
|
||||
service can be invoked.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
Reference in New Issue
Block a user