Spring-WS provides a client-side Web service API that allows for consistent, XML-driven access to Web services. It also caters for the use of marshallers and unmarshallers so that your service tier code can deal exclusively with Java objects.
The org.springframework.ws.client.core package provides the core functionality
for using the client-side access API. It contains template classes that simplify the use of Web
services, much like the core Spring JdbcTemplate
does for JDBC. The
design principle common to Spring template classes is to provide helper methods to perform common
operations, and for more sophisticated usage, delegate to user implemented callback interfaces.
The Web service template follows the same design. The classes offer various convenience methods
for the sending and receiving of XML messages, marshalling objects to XML before sending, and
allows for multiple transport options.
The WebServiceTemplate
is the core class for client-side Web service
access in Spring-WS. It contains methods for sending Source
objects,
and receiving response messages as either Source
or
Result
. Additionally, it can marshal objects to XML before sending
them across a transport, and unmarshal any response XML into an object again.
The WebServiceTemplate
class uses an URI as the message destination.
You can either set a defaultUri property on the template itself,
or supply an URI explicitly when calling a method on the template. The URI will be
resolved into a WebServiceMessageSender
, which is
responsible for sending the XML message across a transport layer. You can set one or
more message senders using the messageSender or
messageSenders properties of the
WebServiceTemplate
class.
There are two implementations of the WebServiceMessageSender
interface for sending messages via HTTP. The default implementation is the
HttpUrlConnectionMessageSender
, which uses the facilities provided
by Java itself. The alternative is the CommonsHttpMessageSender
,
which uses the
Jakarta Commons HttpClient.
Use the latter if you need more advanced and easy-to-use functionality (such as authentication,
HTTP connection pooling, and so forth).
In addition to a message sender, the WebServiceTemplate
requires a Web
service message factory. There are two message factories for SOAP:
SaajSoapMessageFactory
and AxiomSoapMessageFactory
.
If no message factory is specified (via the 'messageFactory
' property),
Spring-WS will use the SaajSoapMessageFactory
by default.
The WebServiceTemplate
contains many convenience methods to send and receive
web service messages. There are methods that accept and return a Source
and those that return a Result
. Additionally, there are methods which
marshal and unmarshal objects to XML. Here is an example that sends a simple XML message to a Web
service.
import java.io.StringReader; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.springframework.ws.WebServiceMessageFactory; import org.springframework.ws.client.core.WebServiceTemplate; import org.springframework.ws.transport.WebServiceMessageSender; public class WebServiceClient { private static final String MESSAGE = "<message xmlns=\"http://tempuri.org\">Hello Web Service World</message>"; private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate(); public void setDefaultUri(String defaultUri) { webServiceTemplate.setDefaultUri(defaultUri); } // send to the configured default URI public void simpleSendAndReceive() { StreamSource source = new StreamSource(new StringReader(MESSAGE)); StreamResult result = new StreamResult(System.out); webServiceTemplate.sendSourceAndReceiveToResult(source, result); } // send to an explicit URI public void customSendAndReceive() { StreamSource source = new StreamSource(new StringReader(MESSAGE)); StreamResult result = new StreamResult(System.out); webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:8080/AnotherWebService", source, result); } }
<beans xmlns="http://www.springframework.org/schema/beans"> <bean id="webServiceClient" class="WebServiceClient"> <property name="defaultUri" value="http://localhost:8080/WebService"/> </bean> </beans>
The above example uses the WebServiceTemplate
to send a hello
world message to the web service located at http://localhost:8080/WebService
(in the case of the simpleSendAndReceive()
method),
and writes the result to the console. The WebServiceTemplate
is
injected with the default URI, which is used because no URI was supplied explicitly
in the Java code.
Please note that the WebServiceTemplate
class is threadsafe once
configured (assuming that all of it's dependencies are threadsafe too, which is the case for
all of the dependencies that ship with Spring-WS), and so multiple objects can use the same
shared WebServiceTemplate
instance if so desired.
The WebServiceTemplate
exposes a zero argument constructor and
messageFactory/messageSender bean properties which
can be used for constructing the instance (using a Spring container or plain Java code).
Alternatively, consider deriving from Spring-WS's WebServiceGatewaySupport
convenience base class, which exposes convenient bean properties to enable easy configuration.
(You do not have to extend this base class... it is provided as a convenience
class only.)
In order to facilitate the sending of plain Java objects, the
WebServiceTemplate
has a number of send(..)
methods
that take an Object
as an argument for a message's data content.
The method marshalSendAndReceive(..)
in the
WebServiceTemplate
class delegates the conversion of the request object
to XML to a Marshaller
, and the conversion of the response
XML to an object to an Unmarshaller
. (For more information
about marshalling and unmarshaller, refer to Chapter 8, Marshalling XML using O/X Mappers.) By using the
marshallers, your application code can focus on the business object that is being sent or
received and not be concerned with the details of how it is represented as XML. In order to
use the marshalling functionality, you have to set a marshaller and unmarshaller with the
marshaller/unmarshaller properties of the
WebServiceTemplate
class.
To accommodate the setting of SOAP headers and other settings on the message, the
WebServiceMessageCallback
interface gives you access to the
message after it has been created, but before it
is sent. The example below demonstrates how to set the SOAP Action header on a message
that is created by marshalling an object.
public void marshalWithSoapActionHeader(MyObject o) { webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() { public void doInMessage(WebServiceMessage message) { ((SoapMessage)message).setSoapAction("http://tempuri.org/Action"); } }); }
The WebServiceMessageExtractor
interface is a low-level
callback interface that allows you to have full control over the process to extract an
Object
from a received WebServiceMessage
.
The WebServiceTemplate
will invoke the extractData(..)
method on a supplied WebServiceMessageExtractor
while the underlying connection to the serving resource is still open.
The following example illustrates the WebServiceMessageExtractor
in action:
public void marshalWithSoapActionHeader(final Source s) { final Transformer transformer = transformerFactory.newTransformer(); webServiceTemplate.sendAndReceive(new WebServiceMessageCallback() { public void doInMessage(WebServiceMessage message) { transformer.transform(s, message.getPayloadResult()); }, new WebServiceMessageExtractor() { public Object extractData(WebServiceMessage message) throws IOException // do your own transforms with message.getPayloadResult() // or message.getPayloadSource() } }); }