Documentation
This commit is contained in:
@@ -76,12 +76,14 @@
|
||||
<para>
|
||||
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
|
||||
SOAP Headers, SOAP Faults, etc.
|
||||
Generally, your code should not be dependent on <interfacename>SoapMessage</interfacename>, because
|
||||
the content of the SOAP Body (the payload of the message) 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
|
||||
<interfacename>WebServiceMessage</interfacename> to <interfacename>SoapMessage</interfacename>.
|
||||
<interfacename>WebServiceMessage</interfacename>.
|
||||
Only when it is necessary to perform SOAP-specific actions, such as adding a header, getting an
|
||||
attachment, etc., should you need to cast <interfacename>WebServiceMessage</interfacename> to
|
||||
<interfacename>SoapMessage</interfacename>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="message-factories">
|
||||
|
||||
@@ -10,15 +10,12 @@
|
||||
<classname>MessageDispatcher</classname> that dispatches incoming
|
||||
messages to endpoints, with configurable endpoint mappings, response
|
||||
generation, and endpoint interception.
|
||||
The simplest endpoint is a <interfacename>PayloadEndpoint</interfacename>, which just offers the
|
||||
<literal>Source invoke(Source request)</literal> method. You are of course free to
|
||||
implement this interface directly, but you will probably prefer to extend one of
|
||||
the included abstract implementations such as
|
||||
<classname>AbstractDomPayloadEndpoint</classname>, <classname>AbstractSaxPayloadEndpoint</classname>, and
|
||||
<classname>AbstractMarshallingPayloadEndpoint</classname>.
|
||||
Alternatively, there is a endpoint development that uses Java 5 annotations, such as
|
||||
<interfacename>@Endpoint</interfacename> for marking a POJO as endpoint, and marking a method with
|
||||
<interfacename>@PayloadRoot</interfacename> or <interfacename>@SoapAction</interfacename>.
|
||||
Endpoints are typically annotated with the <interfacename>@Endpoint</interfacename> annotation, and have
|
||||
one or more handling methods.
|
||||
These methods handle incoming XML request messages by inspecting parts of the message (typically the
|
||||
payload), and create some sort of response.
|
||||
You annotate the method with another annotation, typically <interfacename>@PayloadRoot</interfacename>,
|
||||
to indicate what sort of messages it can handle.
|
||||
</para>
|
||||
<para>
|
||||
Spring-WS's XML handling is extremely flexible. An endpoint can choose from
|
||||
@@ -62,8 +59,8 @@
|
||||
<listitem>
|
||||
<para>
|
||||
An appropriate endpoint is searched for using the configured <literal>EndpointMapping(s)</literal>.
|
||||
If an endpoint is found, the invocation chain associated with the endpoint (preprocessors,
|
||||
postprocessors, and endpoints) will be executed in order to create a response.
|
||||
If an endpoint is found, the invocation chain associated with the endpoint (pre-processors,
|
||||
post-processors, and endpoints) will be executed in order to create a response.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@@ -185,7 +182,7 @@
|
||||
</para>
|
||||
</note>
|
||||
<para>
|
||||
Another cool feature of the <classname>MessageDispatcherServlet</classname> (or more correctly the
|
||||
Another nice feature of the <classname>MessageDispatcherServlet</classname> (or more correctly the
|
||||
<classname>WsdlDefinitionHandlerAdapter</classname>) is that it is able to
|
||||
transform the value of the '<literal>location</literal>' of all the WSDL that it exposes to reflect
|
||||
the URL of the incoming request.
|
||||
@@ -257,9 +254,6 @@
|
||||
</para>
|
||||
<programlisting><![CDATA[
|
||||
<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
|
||||
<description>
|
||||
This bean wrap the messages.xsd (which imports types.xsd), and inlines them as a one.
|
||||
</description>
|
||||
<property name="xsds">
|
||||
<list>
|
||||
<value>/WEB-INF/xsds/Orders.xsd</value>
|
||||
@@ -281,7 +275,7 @@
|
||||
Refer to the class-level Javadoc of these classes to see how you can extend this mechanism,
|
||||
if necessary.
|
||||
</para>
|
||||
<note>
|
||||
<caution>
|
||||
<para>
|
||||
Even though it can be quite handy to create the WSDL at runtime from your XSDs, there
|
||||
are a couple of drawbacks to this approach. First off, though we try to keep the WSDL generation
|
||||
@@ -296,7 +290,7 @@
|
||||
<classname>SimpleWsdl11Definition</classname>. This is the only way to be really sure that
|
||||
the WSDL does not change over time.
|
||||
</para>
|
||||
</note>
|
||||
</caution>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
@@ -591,36 +585,123 @@
|
||||
request message and uses that input to invoke a method on the business service (typically). The result of that service
|
||||
invocation is represented as a response message. Spring-WS has a wide variety of endpoints, using various
|
||||
ways to handle the XML message, and to create a response.
|
||||
</para>
|
||||
<para>
|
||||
The basis for most endpoints in Spring Web Services is the
|
||||
<interfacename>org.springframework.ws.server.endpoint.PayloadEndpoint</interfacename> interface, the source
|
||||
code of which is listed below.
|
||||
</para>
|
||||
<programlisting><![CDATA[public interface PayloadEndpoint {
|
||||
<para>
|
||||
You create an endpoint by annotating a class with the <interfacename>@Endpoint</interfacename> annotation.
|
||||
In the class, you define one or more methods that handle the incoming XML request, by using a wide
|
||||
variety of parameter types (such as DOM elements, JAXB2 objects, etc).
|
||||
You indicate the sort of messages a method can handle by using another annotation (typically
|
||||
<interfacename>@PayloadRoot</interfacename>).
|
||||
</para>
|
||||
<para>
|
||||
Consider the following sample endpoint:
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area coords="9" id="server-endpoint-atEndpoint"/>
|
||||
<area coords="14" id="server-endpoint-constructor"/>
|
||||
<area coords="20" id="server-endpoint-order"/>
|
||||
<area coords="27" id="server-endpoint-getOrder"/>
|
||||
<areaset coords="" id="server-endpoint-payloadRoot">
|
||||
<area coords="19" id="server-endpoint-payloadRoot-1"/>
|
||||
<area coords="25" id="server-endpoint-payloadRoot-2"/>
|
||||
</areaset>
|
||||
</areaspec>
|
||||
<programlisting><![CDATA[package samples;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
|
||||
@Endpoint
|
||||
public class AnnotationOrderEndpoint {
|
||||
|
||||
private final OrderService orderService;
|
||||
|
||||
@Autowired
|
||||
public AnnotationOrderEndpoint(OrderService orderService) {
|
||||
this.orderService = orderService;
|
||||
}
|
||||
|
||||
@PayloadRoot(localPart = "order", namespace = "http://samples")
|
||||
public void order(@RequestPayload Element orderElement) {
|
||||
Order order = createOrder(orderElement);
|
||||
orderService.createOrder(order);
|
||||
}
|
||||
|
||||
@PayloadRoot(localPart = "orderRequest", namespace = "http://samples")
|
||||
@ResponsePayload
|
||||
public Order getOrder(@RequestPayload OrderRequest orderRequest) {
|
||||
return orderService.getOrder(orderRequest.getId());
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
]]><lineannotation>/**
|
||||
* Invokes an operation.
|
||||
*/</lineannotation><![CDATA[
|
||||
Source invoke(Source request) throws Exception;
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
As you can see, the <interfacename>PayloadEndpoint</interfacename> interface defines a single method that
|
||||
is invoked with the XML payload of a request (typically the contents of the SOAP Body, see
|
||||
<xref linkend="soap-message"/>). The returned <interfacename>Source</interfacename>, if any, is stored in the
|
||||
response XML message. While the <interfacename>PayloadEndpoint</interfacename> interface is quite abstract,
|
||||
Spring-WS offers a lot of endpoint implementations out of the box that already contain a lot of the
|
||||
functionality you might need. The <interfacename>PayloadEndpoint</interfacename> interface just defines the
|
||||
most basic responsibility required of every endpoint; namely handling a request and returning a response.
|
||||
<calloutlist>
|
||||
<callout arearefs="server-endpoint-atEndpoint">
|
||||
<para>
|
||||
The class is annotated with <interfacename>@Endpoint</interfacename>, marking it as a
|
||||
Spring-WS endpoint.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="server-endpoint-constructor">
|
||||
<para>
|
||||
The constructor is marked with <interfacename>@Autowired</interfacename>, so that the
|
||||
<classname>OrderService</classname> business service is injected into this endpoint.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="server-endpoint-order">
|
||||
<para>
|
||||
The <methodname>order</methodname> method takes a <interfacename>Element</interfacename>
|
||||
as a parameter, annotated with <interfacename>@RequestPayload</interfacename>.
|
||||
This means that the payload of the message is passed on this method as a DOM element.
|
||||
The method has a <literal>void</literal> return type, indicating that no response message
|
||||
is sent.
|
||||
</para>
|
||||
<para>
|
||||
For more information about endpoint methods, refer to
|
||||
<xref linkend="server-atEndpoint-methods"/>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="server-endpoint-getOrder">
|
||||
<para>
|
||||
The <methodname>getOrder</methodname> method takes a <classname>OrderRequest</classname>
|
||||
as a parameter, annotated with <interfacename>@RequestPayload</interfacename> as well.
|
||||
This parameter is a JAXB2-supported object (it is annotated with
|
||||
<interfacename>@XmlRootElement</interfacename>).
|
||||
This means that the payload of the message is passed on to this method as a unmarshalled
|
||||
object.
|
||||
The method is also annotated with <interfacename>@ResponseBody</interfacename>,
|
||||
indicating that the return value (the <classname>Order</classname>) is used as the payload
|
||||
of the response message.
|
||||
</para>
|
||||
<para>
|
||||
For more information about endpoint methods, refer to
|
||||
<xref linkend="server-atEndpoint-methods"/>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="server-endpoint-payloadRoot">
|
||||
<para>
|
||||
The two handling methods of this endpoint are marked with
|
||||
<interfacename>@PayloadRoot</interfacename>, indicating what sort of request messages
|
||||
can be handled by the method: 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.
|
||||
</para>
|
||||
<para>
|
||||
For more information about <interfacename>@PayloadRoot</interfacename>, refer to
|
||||
<xref linkend="server-endpoint-mapping"/>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</programlistingco>
|
||||
</para>
|
||||
<para>
|
||||
Alternatively, there is the <interfacename>MessageEndpoint</interfacename>, which operates on a
|
||||
whole <link linkend="message-context"><interfacename>MessageContext</interfacename></link> rather than just
|
||||
the payload. Typically, your code should not be dependent on messages, because the payload should
|
||||
contain the information of interest. Only when it is necessary to perform actions on the message as a whole,
|
||||
such as adding a SOAP header, get an attachment, and so forth, should you need to implement
|
||||
<interfacename>MessageEndpoint</interfacename>, though these actions are usually performed in an
|
||||
<link linkend="server-endpoint-interceptor">endpoint interceptor</link>.
|
||||
In the next couple of sections, a more elaborate description of the <interfacename>@Endpoint</interfacename>
|
||||
programming model is given.
|
||||
</para>
|
||||
<note>
|
||||
<para>
|
||||
@@ -631,10 +712,58 @@
|
||||
<ulink url="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes">Spring Reference documentation</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
Note that all abstract base classes provided in Spring-WS (like AbstractDomPayloadEndpoint etc) are
|
||||
thread safe.
|
||||
Note that all abstract base classes provided in Spring-WS are thread safe, unless otherwise indicated
|
||||
in the class-level Javadoc.
|
||||
</para>
|
||||
</note>
|
||||
<section id="server-atEndpoint-methods">
|
||||
<title><interfacename>@Endpoint</interfacename> handling methods</title>
|
||||
<para>
|
||||
In order for an endpoint to actually handle incoming XML messages, it needs to have one or more handling
|
||||
methods.
|
||||
Handling methods can take wide range of parameters and return types, but typically they have one
|
||||
parameter that will contain the message payload, and they return the payload of the response message
|
||||
(if any).
|
||||
You will learn which parameter and return types are supported in this section.
|
||||
</para>
|
||||
<para>
|
||||
To indicate what sort of messages a method can handle, the method is typically annotated with either the
|
||||
<interfacename>@PayloadRoot</interfacename> or <interfacename>@SoapAction</interfacename> annotation.
|
||||
You will learn more about these annotations in <xref linkend="server-endpoint-mapping"/>.
|
||||
</para>
|
||||
<para>
|
||||
Here is an example of a handling method:
|
||||
<programlisting>@PayloadRoot(localPart = "order", namespace = "http://samples")
|
||||
public void order(@RequestPayload Element orderElement) {
|
||||
Order order = createOrder(orderElement);
|
||||
orderService.createOrder(order);
|
||||
}</programlisting>
|
||||
The <methodname>order</methodname> method takes a <interfacename>Element</interfacename>
|
||||
as a parameter, annotated with <interfacename>@RequestPayload</interfacename>.
|
||||
This means that the payload of the message is passed on this method as a DOM element.
|
||||
The method has a <literal>void</literal> return type, indicating that no response message
|
||||
is sent.
|
||||
</para>
|
||||
<section>
|
||||
<title>Handling method parameters</title>
|
||||
<para>
|
||||
The handling method typically has one or more parameters that refer to various parts of the
|
||||
incoming XML message.
|
||||
Most commonly, the handling method will have a single parameter that will map to the payload of
|
||||
the message, but it is also possible to map to other parts of the message, such as a SOAP header.
|
||||
This section will describe the parameters you can use in your handling method signatures.
|
||||
</para>
|
||||
<para>
|
||||
One
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Handling method return types</title>
|
||||
<para>
|
||||
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title><classname>AbstractDomPayloadEndpoint</classname> and other DOM endpoints</title>
|
||||
<para>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
and this tutorial will help you get started. Note that the first part of this
|
||||
tutorial contains almost no Spring-WS specific information: it is mostly about
|
||||
XML, XSD, and WSDL. The <link linkend="tutorial-creating-project">second part</link>
|
||||
focusses on implementing this contract using Spring-WS .
|
||||
focuses on implementing this contract using Spring-WS .
|
||||
</para>
|
||||
<para>
|
||||
The most important thing when doing contract-first Web service development is
|
||||
@@ -678,7 +678,7 @@ public class HolidayEndpoint {
|
||||
<dependency>
|
||||
<groupId>org.springframework.ws</groupId>
|
||||
<artifactId>spring-ws-core</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.0.0-RC2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jdom</groupId>
|
||||
@@ -694,14 +694,21 @@ public class HolidayEndpoint {
|
||||
<para>
|
||||
Here is how we would configure these classes in our <filename>spring-ws-servlet.xml</filename>
|
||||
Spring XML configuration file, by using component scanning.
|
||||
We also instruct Spring-WS to use annotation-driven endpoints, with the
|
||||
<literal><sws:annotation-driven></literal> element.
|
||||
</para>
|
||||
<programlisting id="tutorial.example.sws-conf-file"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<programlisting id="tutorial.example.sws-conf-file"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:sws="http://www.springframework.org/schema/web-services"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<context:component-scan base-package="com.mycompany.hr"/>
|
||||
|
||||
<sws:annotation-driven/>
|
||||
|
||||
</beans>]]></programlisting>
|
||||
</section>
|
||||
<section>
|
||||
@@ -720,6 +727,8 @@ public class HolidayEndpoint {
|
||||
<literal>http://mycompany.com/hr/schemas</literal> and the
|
||||
<literal>HolidayRequest</literal> local name, it will be routed to the
|
||||
<methodname>handleHolidayRequest</methodname> method.
|
||||
By using the <literal><sws:annotation-driven></literal> element in our configuration, we
|
||||
enable the detection of the <interfacename>@PayloadRoot</interfacename> annotations.
|
||||
It is possible (and quite common) to have multiple, related handling methods in an endpoint, each
|
||||
of them handling different XML messages.
|
||||
</para>
|
||||
@@ -739,43 +748,29 @@ public class HolidayEndpoint {
|
||||
<programlistingco>
|
||||
<areaspec>
|
||||
<area id="tutorial.wsdl.gen.bean" coords="1"/>
|
||||
<areaset id="tutorial.wsdl.gen.schema" coords="">
|
||||
<area id="tutorial.wsdl.gen.schema.ref" coords="2"/>
|
||||
<area id="tutorial.wsdl.gen.schema.def" coords="8"/>
|
||||
</areaset>
|
||||
<area id="tutorial.wsdl.gen.portType" coords="3"/>
|
||||
<area id="tutorial.wsdl.gen.locationUri" coords="4"/>
|
||||
<area id="tutorial.wsdl.gen.tns" coords="5"/>
|
||||
<area id="tutorial.wsdl.gen.schema" coords="5"/>
|
||||
<area id="tutorial.wsdl.gen.portType" coords="2"/>
|
||||
<area id="tutorial.wsdl.gen.locationUri" coords="3"/>
|
||||
<area id="tutorial.wsdl.gen.tns" coords="4"/>
|
||||
</areaspec>
|
||||
<programlisting><![CDATA[<bean id="holiday" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
|
||||
<property name="schema" ref="schema"/>
|
||||
<property name="portTypeName" value="HumanResource"/>
|
||||
<property name="locationUri" value="/holidayService/"/>
|
||||
<property name="targetNamespace" value="http://mycompany.com/hr/definitions"/>
|
||||
</bean>
|
||||
|
||||
<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
|
||||
<property name="xsd" value="/WEB-INF/hr.xsd"/>
|
||||
</bean>]]></programlisting>
|
||||
<programlisting><![CDATA[<sws:dynamic-wsdl id="holiday"
|
||||
portTypeName="HumanResource"
|
||||
locationUri="/holidayService/"
|
||||
targetNamespace="http://mycompany.com/hr/definitions">
|
||||
<sws:xsd location="/WEB-INF/hr.xsd"/>
|
||||
</sws:dynamic-wsdl>]]></programlisting>
|
||||
<calloutlist>
|
||||
<callout arearefs="tutorial.wsdl.gen.bean">
|
||||
<para>
|
||||
The bean id determines the URL where the WSDL can be retrieved. In this case, the bean id is
|
||||
<varname>holiday</varname>, which means that the WSDL can be retrieved as
|
||||
<filename>holiday.wsdl</filename> in the servlet context. The full URL will typically be
|
||||
<uri>http://localhost:8080/holidayService/holiday.wsdl</uri>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.gen.schema">
|
||||
<para>
|
||||
The <varname>schema</varname> property refers to the human resource schema we defined in
|
||||
<xref linkend="tutorial.xsd"/>, wrapped in a <classname>SimpleXsdSchema</classname>. We simply
|
||||
placed the schema in the <filename>WEB-INF</filename> directory of the application.
|
||||
The id determines the URL where the WSDL can be retrieved.
|
||||
In this case, the id is <varname>holiday</varname>, which means that the WSDL can be retrieved
|
||||
as <filename>holiday.wsdl</filename> in the servlet context.
|
||||
The full URL will typically be <uri>http://localhost:8080/holidayService/holiday.wsdl</uri>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.gen.portType">
|
||||
<para>
|
||||
Next, we define the WSDL port type to be <literal>HumanResource</literal>.
|
||||
Next, we set the WSDL port type to be <literal>HumanResource</literal>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.gen.locationUri">
|
||||
@@ -798,8 +793,16 @@ public class HolidayEndpoint {
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.gen.tns">
|
||||
<para>
|
||||
Finally, we define the target namespace for the WSDL definition itself. Setting these
|
||||
is not required. If not set, we give the WSDL the same namespace as the schema.
|
||||
We define the target namespace for the WSDL definition itself.
|
||||
Setting this attribute is not required.
|
||||
If not set, the WSDL will have the same namespace as the XSD schema.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="tutorial.wsdl.gen.schema">
|
||||
<para>
|
||||
The <varname>xsd</varname> element refers to the human resource schema we defined in
|
||||
<xref linkend="tutorial.xsd"/>.
|
||||
We simply placed the schema in the <filename>WEB-INF</filename> directory of the application.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
|
||||
Reference in New Issue
Block a user