<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
        "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="client">
    <title>Using Spring Web Services on the Client</title>
    <section>
        <title>Introduction</title>
        <para>
            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 <link linkend="oxm">marshallers and unmarshallers</link>
            so that your service tier code can deal exclusively with Java objects.
        </para>
        <para>
            The <package>org.springframework.ws.client.core</package> 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 <classname>JdbcTemplate</classname> 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.
        </para>
    </section>
    <section>
        <title>Using the client-side API</title>
        <section id="client-web-service-template">
            <title><classname>WebServiceTemplate</classname></title>
            <para>
                The <classname>WebServiceTemplate</classname> is the core class for client-side Web service
                access in Spring-WS. It contains methods for sending <classname>Source</classname> objects,
                and receiving response messages as either <classname>Source</classname> or
                <classname>Result</classname>. Additionally, it can marshal objects to XML before sending
                them across a transport, and unmarshal any response XML into an object again.
            </para>
            <section id="client-transports">
                <title>URIs and Transports</title>
                <para>
                    The <classname>WebServiceTemplate</classname> class uses an URI as the message destination.
                    You can either set a <property>defaultUri</property> property on the template itself,
                    or supply an URI explicitly when calling a method on the template. The URI will be
                    resolved into a <interfacename>WebServiceMessageSender</interfacename>, which is
                    responsible for sending the XML message across a transport layer. You can set one or
                    more message senders using the <property>messageSender</property> or
                    <property>messageSenders</property> properties of the
                    <classname>WebServiceTemplate</classname> class.
                </para>
                <section>
                    <title>HTTP transports</title>
                    <para>
                        There are two implementations of the <classname>WebServiceMessageSender</classname>
                        interface for sending messages via HTTP. The default implementation is the
                        <classname>HttpUrlConnectionMessageSender</classname>, which uses the facilities provided
                        by Java itself. The alternative is the <classname>CommonsHttpMessageSender</classname>,
                        which uses the
                        <ulink url="http://jakarta.apache.org/commons/httpclient/">Jakarta Commons HttpClient</ulink>.
                        Use the latter if you need more advanced and easy-to-use functionality (such as authentication,
                        HTTP connection pooling, and so forth).
                    </para>
                    <para>
                        To use the HTTP transport, either set the <property>defaultUri</property> to something like
                        <uri>http://example.com/services</uri>, or supply the <parameter>uri</parameter> parameter
                        for one of the methods.
                    </para>
                    <para>
                        The following example shows how the default configuration can be used for HTTP transports:
                        <programlisting><![CDATA[<beans>

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <constructor-arg ref="messageFactory"/>
        <property name="defaultUri" value="http://example.com/WebService"/>
    </bean>

</beans>]]></programlisting>
                    </para>
                    <para>
                        The folowing example shows how override the default configuration, and to use Commons Http to
                        authenticate using HTTP authentication:
                        <programlisting><![CDATA[<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="messageSender">
        <bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
            <property name="credentials">
                <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
                    <constructor-arg value="john"/>
                    <constructor-arg value="secret"/>
                </bean>
            </property>
        </bean>
    </property>
    <property name="defaultUri" value="http://example.com/WebService"/>
</bean>]]></programlisting>
                    </para>
                </section>
                <section>
                    <title>JMS transport</title>
                    <para>
                        For sending messages over JMS, Spring Web Services provides the
                        <classname>JmsMessageSender</classname>. This class uses the facilities of the Spring framework
                        to transform the <interfacename>WebServiceMessage</interfacename> into a JMS
                        <interfacename>Message</interfacename>, send it on its way on a
                        <interfacename>Queue</interfacename> or <interfacename>Topic</interfacename>, and receive a
                        response (if any).
                    </para>
                    <para>
                        To use the <classname>JmsMessageSender</classname>, you need to set the
                        <property>defaultUri</property> or <parameter>uri</parameter> parameter to a JMS URI, which - at a
                        minimum - consists of the <literal>jms:</literal> prefix and a destination name. Some examples of
                        JMS URIs are: <uri>jms:SomeQueue</uri>,
                        <uri>jms:SomeTopic?priority=3&amp;deliveryMode=NON_PERSISTENT</uri>, and
                        <uri>jms:RequestQueue?replyToName=ResponseName</uri>.
                        For more information on this URI syntax, refer to the class level Javadocs of the
                        <classname>JmsMessageSender</classname>.
                    </para>
                    <para>
                        By default, the <classname>JmsMessageSender</classname> send JMS
                        <interfacename>BytesMessage</interfacename>, but
                        this can be overriden to use <interfacename>TextMessages</interfacename> by using the
                        <literal>messageType</literal> parameter on the JMS URI. For example:
                        <uri>jms:Queue?messageType=TEXT_MESSAGE</uri>.
                        Note that <interfacename>BytesMessages</interfacename> are the prefered type, because 
                        <interfacename>TextMessages</interfacename> do not support attachments and charactering
                        encodings reliably.
                    </para>
                    <para>
                        The following example shows how to use the JMS transport in combination with an ActiceMQ
                        connection factory:<programlisting><![CDATA[<beans>

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

    <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="vm://localhost?broker.persistent=false"/>
    </bean>

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <constructor-arg ref="messageFactory"/>
        <property name="messageSender">
            <bean class="org.springframework.ws.transport.jms.JmsMessageSender">
                <property name="connectionFactory" ref="connectionFactory"/>
            </bean>
        </property>
        <property name="defaultUri" value="jms:RequestQueue?deliveryMode=NON_PERSISTENT"/>
    </bean>

</beans>]]></programlisting>
                    </para>
                </section>
                <section>
                    <title>Email transport</title>
                    <para>
                        Spring Web Services also provides an email transport, which can be used to send web service
                        messages via SMTP, and retrieve them via either POP3 or IMAP. The client-side email
                        functionality is contained in the <classname>MailMessageSender</classname> class.
                        This class creates an email message from the request
                        <interfacename>WebServiceMessage</interfacename>, and sends it via SMTP. It then waits for a
                        response message to arrive in the incoming POP3 or IMAP server.
                    </para>
                    <para>
                        To use the <classname>MailMessageSender</classname>, set the <property>defaultUri</property> or
                        <parameter>uri</parameter> parameter to a <literal>mailto</literal> URI. Here are some URI
                        examples: <uri>mailto:john@example.com</uri>, and
                        <uri>mailto:server@localhost?subject=SOAP%20Test</uri>. Make sure that the message sender is
                        properly configured with a <property>transportUri</property>, which indicates the server to use for
                        sending requests (typically a SMTP server), and a <property>storeUri</property>, which indicates
                        the server to poll for responses (typically a POP3 or IMAP server).
                    </para>
                    <para>
                        The following example shows how to use the email transport:<programlisting><![CDATA[<beans>

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>

    <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
        <constructor-arg ref="messageFactory"/>
        <property name="messageSender">
            <bean class="org.springframework.ws.transport.mail.MailMessageSender">
                <property name="from" value="Spring-WS SOAP Client &lt;client@example.com&gt;"/>
                <property name="transportUri" value="smtp://client:s04p@smtp.example.com"/>
                <property name="storeUri" value="imap://client:s04p@imap.example.com/INBOX"/>
            </bean>
        </property>
        <property name="defaultUri" value="mailto:server@example.com?subject=SOAP%20Test"/>
    </bean>

</beans>]]></programlisting>
                    </para>
                </section>
            </section>
            <section>
                <title>Message factories</title>
                <para>
                    In addition to a message sender, the <classname>WebServiceTemplate</classname> requires a Web
                    service message factory. There are two message factories for SOAP:
                    <classname>SaajSoapMessageFactory</classname> and <classname>AxiomSoapMessageFactory</classname>.
                    If no message factory is specified (via the <property>messageFactory</property> property),
                    Spring-WS will use the <classname>SaajSoapMessageFactory</classname> by default.
                </para>
            </section>
        </section>
        <section>
            <title>Sending and receiving a <interfacename>WebServiceMessage</interfacename>
            </title>
            <para>
                The <classname>WebServiceTemplate</classname> contains many convenience methods to send and receive
                web service messages. There are methods that accept and return a <interfacename>Source</interfacename>
                and those that return a <interfacename>Result</interfacename>. 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.
            </para>

            <programlisting><![CDATA[
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);
    }

    ]]><lineannotation>// send to the configured default URI</lineannotation><![CDATA[
    public void simpleSendAndReceive() {
        StreamSource source = new StreamSource(new StringReader(MESSAGE));
        StreamResult result = new StreamResult(System.out);
        webServiceTemplate.sendSourceAndReceiveToResult(source, result);
    }

    ]]><lineannotation>// send to an explicit URI</lineannotation><![CDATA[
    public void customSendAndReceive() {
        StreamSource source = new StreamSource(new StringReader(MESSAGE));
        StreamResult result = new StreamResult(System.out);
        webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:8080/AnotherWebService",
            source, result);
    }

}]]></programlisting>
            <programlisting><![CDATA[
<beans xmlns="http://www.springframework.org/schema/beans">

    <bean id="webServiceClient" class="WebServiceClient">
        <property name="defaultUri" value="http://localhost:8080/WebService"/>
    </bean>

</beans>]]></programlisting>
            <para>
                The above example uses the <classname>WebServiceTemplate</classname> to send a hello
                world message to the web service located at <uri>http://localhost:8080/WebService</uri>
                (in the case of the <methodname>simpleSendAndReceive()</methodname> method),
                and writes the result to the console. The <classname>WebServiceTemplate</classname> is
                injected with the default URI, which is used because no URI was supplied explicitly
                in the Java code.
            </para>
            <para>
                Please note that the <classname>WebServiceTemplate</classname> 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 <classname>WebServiceTemplate</classname> instance if so desired.
                The <classname>WebServiceTemplate</classname> exposes a zero argument constructor and
                <property>messageFactory</property>/<property>messageSender</property> 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 <classname>WebServiceGatewaySupport</classname>
                convenience base class, which exposes convenient bean properties to enable easy configuration.
                (You do <emphasis>not</emphasis> have to extend this base class... it is provided as a convenience
                class only.)
            </para>
        </section>
        <section>
            <title>Sending and receiving POJOs - marshalling and unmarshalling</title>
            <para>
                In order to facilitate the sending of plain Java objects, the
                <classname>WebServiceTemplate</classname> has a number of <literal>send(..)</literal> methods
                that take an <classname>Object</classname> as an argument for a message's data content.
                The method <methodname>marshalSendAndReceive(..)</methodname> in the
                <classname>WebServiceTemplate</classname> class delegates the conversion of the request object
                to XML to a <interfacename>Marshaller</interfacename>, and the conversion of the response
                XML to an object to an <interfacename>Unmarshaller</interfacename>. (For more information
                about marshalling and unmarshaller, refer to <xref linkend="oxm"/>.) 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
                <property>marshaller</property>/<property>unmarshaller</property> properties of the
                <classname>WebServiceTemplate</classname> class.
            </para>
        </section>
        <section>
            <title>
                <interfacename>WebServiceMessageCallback</interfacename>
            </title>
            <para>
                To accommodate the setting of SOAP headers and other settings on the message, the
                <interfacename>WebServiceMessageCallback</interfacename> interface gives you access to the
                message <emphasis>after</emphasis> it has been created, but <emphasis>before</emphasis> it
                is sent. The example below demonstrates how to set the SOAP Action header on a message
                that is created by marshalling an object.
            </para>
            <programlisting><![CDATA[
public void marshalWithSoapActionHeader(MyObject o) {

    webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {

        public void doWithMessage(WebServiceMessage message) {
            ((SoapMessage)message).setSoapAction("http://tempuri.org/Action");
        }
    });
}]]></programlisting>
            <note>
                <para>
                    Note that you can also use the
                    <classname>org.springframework.ws.soap.client.core.SoapActionCallback</classname> to set the SOAP
                    Action header.
                </para>
            </note>
            <section>
                <title>WS-Addressing</title>
                <para>
                    In addition to the <link linkend="server-ws-addressing">server-side WS-Addressing</link> support,
                    Spring Web Services also has support for this specification on the client-side.
                </para>
                <para>
                    For setting WS-Addressing headers on the client, you can use the
                    <classname>org.springframework.ws.soap.addressing.client.ActionCallback</classname>. This callback
                    takes the desired Action header as a parameter. It also has constructors for specifying the
                    WS-Addressing version, and a <literal>To</literal> header. If not specified, the
                    <literal>To</literal> header will default to the URL of the connection being made.
                </para>
                <para>
                    Here is an example of setting the <literal>Action</literal> header to
                    <uri>http://samples/RequestOrder</uri>:<programlisting><![CDATA[
webServiceTemplate.marshalSendAndReceive(o, new ActionCallback("http://samples/RequestOrder"));
]]></programlisting>

                </para>
            </section>
        </section>
        <section>
            <title>
                <interfacename>WebServiceMessageExtractor</interfacename>
            </title>
            <para>
                The <interfacename>WebServiceMessageExtractor</interfacename> interface is a low-level
                callback interface that allows you to have full control over the process to extract an
                <classname>Object</classname> from a received <interfacename>WebServiceMessage</interfacename>.
                The <classname>WebServiceTemplate</classname> will invoke the <methodname>extractData(..)</methodname>
                method on a supplied <interfacename>WebServiceMessageExtractor</interfacename>
                <emphasis>while the underlying connection to the serving resource is still open</emphasis>.
                The following example illustrates the <interfacename>WebServiceMessageExtractor</interfacename>
                in action:
            </para>
            <programlisting><![CDATA[
public void marshalWithSoapActionHeader(final Source s) {
    final Transformer transformer = transformerFactory.newTransformer();
    webServiceTemplate.sendAndReceive(new WebServiceMessageCallback() {
        public void doWithMessage(WebServiceMessage message) {
            transformer.transform(s, message.getPayloadResult());
        },
        new WebServiceMessageExtractor() {
            public Object extractData(WebServiceMessage message) throws IOException
                ]]><lineannotation>// do your own transforms with message.getPayloadResult()</lineannotation><![CDATA[
                ]]><lineannotation>//     or message.getPayloadSource()</lineannotation><![CDATA[
            }
        });
}]]></programlisting>
        </section>
    </section>
</chapter>