<?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="tutorial">
    <title>Writing Contract-First Web Services</title>
    <section>
        <title>Introduction</title>
        <para>
            This tutorial shows you how to write
            <link linkend="why-contract-first">contract-first Web services</link>, that is,
            developing web services that start with the XML Schema/WSDL contract first
            followed by the Java code second. Spring-WS focuses on this development style,
            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 .
        </para>
        <para>
            The most important thing when doing contract-first Web service development is
            to try and think in terms of XML. This means that Java-language concepts are
            of lesser importance. It is the XML that is sent across the wire, and you
            should focus on that. The fact that Java is used to implement the Web service
            is an implementation detail. An important detail, but a detail nonetheless.
        </para>
        <para>
            In this tutorial, we will define a Web service that is created by a Human Resources
            department. Clients can send holiday request forms to this service to book a holiday.
        </para>
    </section>
    <section>
        <title>Messages</title>
        <para>
            In this section, we will focus on the actual XML messages that are sent to
            and from the Web service. We will start out by determining what these messages
            look like.
        </para>
        <section>
            <title>Holiday</title>
            <para>
                In the scenario, we have to deal with holiday requests, so it makes sense
                to determine what a holiday looks like in XML:
            </para>
            <programlisting><![CDATA[
<Holiday xmlns="http://mycompany.com/hr/schemas">
    <StartDate>2006-07-03</StartDate>
    <EndDate>2006-07-07</EndDate>
</Holiday>]]></programlisting>
            <para>
                A holiday consists of a start date and an end date. We have also decided to
                use the standard
                <ulink url="http://www.cl.cam.ac.uk/~mgk25/iso-time.html">ISO 8601</ulink>
                date format for the dates, because that will save a lot of parsing hassle.
                We have also added a namespace to the element, to make sure our elements
                can used within other XML documents.
            </para>
        </section>
        <section>
            <title>Employee</title>
            <para>
                There is also the notion of an employee in the scenario. Here is what it
                looks like in XML:
            </para>
            <programlisting><![CDATA[
<Employee xmlns="http://mycompany.com/hr/schemas">
    <Number>42</Number>
    <FirstName>Arjen</FirstName>
    <LastName>Poutsma</LastName>
</Employee>]]></programlisting>
            <para>
                We have used the same namespace as before. If this
                <literal>&lt;Employee/&gt;</literal> element could be used in other
                scenarios, it might make sense to use a different namespace, such as
                <literal>http://mycompany.com/employees/schemas</literal>.
            </para>
        </section>
        <section>
            <title>HolidayRequest</title>
            <para>
                Both the holiday and employee element can be put in a
                <literal>&lt;HolidayRequest/&gt;</literal>:
            </para>
            <programlisting><![CDATA[
<HolidayRequest xmlns="http://mycompany.com/hr/schemas">
    <Holiday>
        <StartDate>2006-07-03</StartDate>
        <EndDate>2006-07-07</EndDate>
    </Holiday>
    <Employee>
        <Number>42</Number>
        <FirstName>Arjen</FirstName>
        <LastName>Poutsma</LastName>
    </Employee>
</HolidayRequest>]]></programlisting>
            <para>
                The order of the two elements does not matter: <literal>&lt;Employee/&gt;</literal>
                could have been the first element just as well. What is important is
                that all of the data is there. In fact, the data is the only thing
                that is important: we are taking a <emphasis>data-driven</emphasis>
                approach.
            </para>
        </section>
    </section>
    <section id="tutorial.xsd">
        <title>Data Contract</title>
        <para>
            Now that we have seen some examples of the XML data that we will use,
            it makes sense to formalize this into a schema. This data contract
            defines the message format we accept. There are four different ways
            of defining such a contract for XML:
        </para>
        <itemizedlist>
            <listitem><para>DTDs</para></listitem>
            <listitem><para><ulink url="http://www.w3.org/XML/Schema">XML Schema (XSD)</ulink></para></listitem>
            <listitem><para><ulink url="http://www.relaxng.org/">RELAX NG</ulink></para></listitem>
            <listitem><para><ulink url="http://www.schematron.com/">Schematron</ulink></para></listitem>
        </itemizedlist>
        <para>
            DTDs have limited namespace support, so they are not suitable for Web
            services. Relax NG and Schematron certainly are easier than XML Schema.
            Unfortunately, they are not so widely supported across platforms. We
            will use XML Schema.
        </para>
        <para>
            By far the easiest way to create an XSD is to infer it from sample
            documents. Any good XML editor or Java IDE offers this functionality.
            Basically, these tools use some sample XML documents, and generate a
            schema from it that validates them all. The end result certainly needs
            to be polished up, but it's a great starting point.
        </para>
        <para>
            Using the sample described above, we end up with the following
            generated schema:
        </para>
        <programlisting><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified"
        targetNamespace="http://mycompany.com/hr/schemas"
        xmlns:hr="http://mycompany.com/hr/schemas">
    <xs:element name="HolidayRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="hr:Holiday"/>
                <xs:element ref="hr:Employee"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Holiday">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="hr:StartDate"/>
                <xs:element ref="hr:EndDate"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="StartDate" type="xs:NMTOKEN"/>
    <xs:element name="EndDate" type="xs:NMTOKEN"/>
    <xs:element name="Employee">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="hr:Number"/>
                <xs:element ref="hr:FirstName"/>
                <xs:element ref="hr:LastName"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="Number" type="xs:integer"/>
    <xs:element name="FirstName" type="xs:NCName"/>
    <xs:element name="LastName" type="xs:NCName"/>
</xs:schema>]]></programlisting>
        <para>
            This generated schema obviously can be improved. The first thing
            to notice is that every type has a root-level element declaration.
            This means that the Web service should be able to accept all of
            these elements as data. This is not desirable: we only want to
            accept a <literal>&lt;HolidayRequest/&gt;</literal>. By removing
            the wrapping element tags (thus keeping the types), and inlining
            the results, we can accomplish this.
        </para>
        <programlisting><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:hr="http://mycompany.com/hr/schemas"
        elementFormDefault="qualified"
        targetNamespace="http://mycompany.com/hr/schemas">
    <xs:element name="HolidayRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Holiday" type="hr:HolidayType"/>
                <xs:element name="Employee" type="hr:EmployeeType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="HolidayType">
        <xs:sequence>
            <xs:element name="StartDate" type="xs:NMTOKEN"/>
            <xs:element name="EndDate" type="xs:NMTOKEN"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="EmployeeType">
        <xs:sequence>
            <xs:element name="Number" type="xs:integer"/>
            <xs:element name="FirstName" type="xs:NCName"/>
            <xs:element name="LastName" type="xs:NCName"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>]]></programlisting>
        <para>
            The schema still has one problem: with a schema like this, you
            can expect the following messages to validate:
        </para>
        <programlisting>
<![CDATA[<HolidayRequest xmlns="http://mycompany.com/hr/schemas">
    <Holiday>
        <StartDate>this is not a date</StartDate>
        <EndDate>neither is this</EndDate>
    </Holiday>
    ]]><lineannotation>&lt;!-- ... --&gt;</lineannotation><![CDATA[
</HolidayRequest>]]></programlisting>
        <para>
            Clearly, we must make sure that the start and end date are really dates.
            XML Schema has an excellent built-in <literal>date</literal> type which
            we can use. We also change the <literal>NCName</literal>s to
            <literal>string</literal>s. Finally, we change the <literal>sequence</literal> in
            <literal>&lt;HolidayRequest/&gt;</literal> to <literal>all</literal>.
            This tells the XML parser that the order of
            <literal>&lt;Holiday/&gt;</literal> and
            <literal>&lt;Employee/&gt;</literal> is not significant. Our final
            XSD now looks like this:
        </para>
        <programlistingco>
            <areaspec>
                <area id="tutorial.xsd.all" coords="8"/>
                <areaset id="tutorial.xsd.dates" coords="">
                    <area id="tutorial.xsd.dates.1" coords="16"/>
                    <area id="tutorial.xsd.dates.2" coords="17"/>
                </areaset>
                <areaset id="tutorial.xsd.strings" coords="">
                    <area id="tutorial.xsd.strings.1" coords="23"/>
                    <area id="tutorial.xsd.strings.2" coords="24"/>
                </areaset>
            </areaspec>
            <programlisting><![CDATA[<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:hr="http://mycompany.com/hr/schemas"
        elementFormDefault="qualified"
        targetNamespace="http://mycompany.com/hr/schemas">
    <xs:element name="HolidayRequest">
        <xs:complexType>
            <xs:all>
                <xs:element name="Holiday" type="hr:HolidayType"/>
                <xs:element name="Employee" type="hr:EmployeeType"/>
            </xs:all>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="HolidayType">
        <xs:sequence>
            <xs:element name="StartDate" type="xs:date"/>
            <xs:element name="EndDate" type="xs:date"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="EmployeeType">
        <xs:sequence>
            <xs:element name="Number" type="xs:integer"/>
            <xs:element name="FirstName" type="xs:string"/>
            <xs:element name="LastName" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>]]></programlisting>
            <calloutlist>
                <callout arearefs="tutorial.xsd.all">
                    <para>
                        <literal>all</literal> tells the XML parser that the order of
                        <literal>&lt;Holiday/&gt;</literal> and
                        <literal>&lt;Employee/&gt;</literal> is not significant.
                    </para>
                </callout>
                <callout arearefs="tutorial.xsd.dates">
                    <para>
                        We use the <literal>xsd:date</literal> data type, which consist of a year, month, and day, for
                        <literal>&lt;StartDate/&gt;</literal> and <literal>&lt;EndDate/&gt;</literal>.
                    </para>
                </callout>
                <callout arearefs="tutorial.xsd.strings">
                    <para>
                        <literal>xsd:string</literal> is used for the first and last name.
                    </para>
                </callout>
            </calloutlist>
        </programlistingco>
        <para>
            We store this file as <filename>hr.xsd</filename>.
        </para>
    </section>
    <section id="tutorial-service-contract">
        <title>Service contract</title>
        <para>
            A service contract is generally expressed as a <ulink url="http://www.w3.org/TR/wsdl">WSDL</ulink> file.
            Note that in Spring-WS, <emphasis>writing the WSDL by hand is not required</emphasis>. Based on the XSD and
            some conventions, Spring-WS can create the WSDL for you, as explained in the section entitled
            <xref linkend="tutorial.implementing.endpoint"/>.
            You can skip to <link linkend="tutorial-creating-project">the next section</link> if you want to; the
            remainder of this section will show you how to write your own WSDL by hand.
         </para>
         <para>
            We start our WSDL with the standard preamble, and by importing our existing XSD. To
            separate the schema from the definition, we will use a separate namespace for the WSDL definitions:
            <uri>http://mycompany.com/hr/definitions</uri>.
        </para>
        <programlisting><![CDATA[<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:schema="http://mycompany.com/hr/schemas"
                  xmlns:tns="http://mycompany.com/hr/definitions"
                  targetNamespace="http://mycompany.com/hr/definitions">
    <wsdl:types>
        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:import namespace="http://mycompany.com/hr/schemas" schemaLocation="hr.xsd"/>
        </xsd:schema>
    </wsdl:types>]]></programlisting>
        <para>
            Next, we add our messages based on the written schema types. We only have one message: one with the
            <literal>&lt;HolidayRequest/&gt;</literal> we put in the schema:
        </para>
        <programlisting><![CDATA[
    <wsdl:message name="HolidayRequest">
        <wsdl:part element="schema:HolidayRequest" name="HolidayRequest"/>
    </wsdl:message>]]></programlisting>
        <para>
            We add the message to a port type as an operation:
        </para>
        <programlisting><![CDATA[
    <wsdl:portType name="HumanResource">
        <wsdl:operation name="Holiday">
            <wsdl:input message="tns:HolidayRequest" name="HolidayRequest"/>
        </wsdl:operation>
    </wsdl:portType>]]></programlisting>
        <para>
            That finished the abstract part of the WSDL (the interface, as it were), and leaves the concrete part.
            The concrete part consists of a <literal>binding</literal>, which tells the client <emphasis>how</emphasis>
            to invoke the operations you've just defined; and a <literal>service</literal>, which tells it
            <emphasis>where</emphasis> to invoke it.
        </para>
        <para>
            Adding a concrete part is pretty standard: just refer to the abstract part you defined previously, make sure
            you use <emphasis>document/literal</emphasis> for the <literal>soap:binding</literal> elements
            (<literal>rpc/encoded</literal> is deprecated), pick a <literal>soapAction</literal> for the operation
            (in this case <uri>http://mycompany.com/RequestHoliday</uri>, but any URI will do), and determine the
            <literal>location</literal> URL where you want request to come in (in this case
            <uri>http://mycompany.com/humanresources</uri>):
        </para>
        <programlistingco>
            <areaspec>
                <area id="tutorial.wsdl.import" coords="9"/>
                <areaset id="tutorial.wsdl.message" coords="">
                    <area id="tutorial.wsdl.message.def" coords="13"/>
                    <area id="tutorial.wsdl.message.ref" coords="18"/>
                </areaset>
                <area id="tutorial.wsdl.message.part" coords="14"/>
                <areaset id="tutorial.wsdl.portType" coords="">
                    <area id="tutorial.wsdl.portType.def" coords="16"/>
                    <area id="tutorial.wsdl.portType.ref" coords="21"/>
                </areaset>
                <areaset id="tutorial.wsdl.binding" coords="">
                    <area id="tutorial.wsdl.binding.def" coords="21"/>
                    <area id="tutorial.wsdl.binding.ref" coords="32"/>
                </areaset>
                <areaset id="tutorial.wsdl.doclit" coords="">
                    <area id="tutorial.wsdl.doclit.doc" coords="22"/>
                    <area id="tutorial.wsdl.doclit.lit" coords="27"/>
                </areaset>
                <area id="tutorial.wsdl.transport" coords="23"/>
                <area id="tutorial.wsdl.soapAction" coords="25"/>
                <area id="tutorial.wsdl.address" coords="33"/>
            </areaspec>
            <programlisting><![CDATA[
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:schema="http://mycompany.com/hr/schemas"
                  xmlns:tns="http://mycompany.com/hr/definitions"
                  targetNamespace="http://mycompany.com/hr/definitions">
    <wsdl:types>
        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <xsd:import namespace="http://mycompany.com/hr/schemas"
                schemaLocation="hr.xsd"/>
        </xsd:schema>
    </wsdl:types>
    <wsdl:message name="HolidayRequest">
        <wsdl:part element="schema:HolidayRequest" name="HolidayRequest"/>
    </wsdl:message>
    <wsdl:portType name="HumanResource">
        <wsdl:operation name="Holiday">
            <wsdl:input message="tns:HolidayRequest" name="HolidayRequest"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="HumanResourceBinding" type="tns:HumanResource">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Holiday">
            <soap:operation soapAction="http://mycompany.com/RequestHoliday"/>
            <wsdl:input name="HolidayRequest">
                <soap:body use="literal"/>
            </wsdl:input>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="HumanResourceService">
        <wsdl:port binding="tns:HumanResourceBinding" name="HumanResourcePort">
            <soap:address location="http://localhost:8080/holidayService/"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>]]></programlisting>
            <calloutlist>
                <callout arearefs="tutorial.wsdl.import">
                    <para>
                        We import the schema defined in <xref linkend="tutorial.xsd"/>.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.message">
                    <para>
                        We define the <literal>HolidayRequest</literal> message, which gets used in the
                        <literal>portType</literal>.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.message.part">
                    <para>
                        The <literal>HolidayRequest</literal> type is defined in the schema.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.portType">
                    <para>
                        We define the <literal>HumanResource</literal> port type, which gets used in the
                        <literal>binding</literal>.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.binding">
                    <para>
                        We define the <literal>HumanResourceBinding</literal> binding, which gets used in the
                        <literal>port</literal>.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.doclit">
                    <para>
                        We use a document/literal style.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.transport">
                    <para>
                        The literal <uri>http://schemas.xmlsoap.org/soap/http</uri> signifies a
                        HTTP transport.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.soapAction">
                    <para>
                        The <literal>soapAction</literal> attribute signifies the <literal>SOAPAction</literal> HTTP
                        header that will be sent with every request.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.address">
                    <para>
                        The <uri>http://localhost:8080/holidayService/</uri> address is the URL where the Web
                        service can be invoked.
                    </para>
                </callout>
            </calloutlist>
        </programlistingco>
        <para>
            This is the final WSDL. We will describe how to implement the resulting schema and WSDL in the next section.
        </para>
    </section>
    <section id="tutorial-creating-project">
        <title>Creating the project</title>
        <para>
            In this section, we will be using <ulink url="http://maven.apache.org/">Maven2</ulink> to create the
            initial project structure for us. Doing so is not required, but greatly reduces the amount of code we
            have to write to setup our HolidayService.
        </para>
        <para>
            The following command creates a Maven2 web application project for us, using the Spring-WS archetype
            (that is, project template)
        </para>
<screen>mvn archetype:create -DarchetypeGroupId=org.springframework.ws \
  -DarchetypeArtifactId=spring-ws-archetype \
  -DarchetypeVersion=1.5.3 \
  -DgroupId=com.mycompany.hr \
  -DartifactId=holidayService
</screen>
        <para>
            This command will create a new directory called <filename>holidayService</filename>. In this directory,
            there is a <filename>'src/main/webapp'</filename> directory, which will contain the root of the WAR file.
            You will find the standard web application deployment descriptor <filename>'WEB-INF/web.xml'</filename>
            here, which defines a Spring-WS <classname>MessageDispatcherServlet</classname> and maps all incoming
            requests to this servlet:
        </para>
        <programlisting><![CDATA[
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <display-name>MyCompany HR Holiday Service</display-name>

    ]]><lineannotation>&lt;!-- take especial notice of the name of this servlet --&gt;</lineannotation><![CDATA[
    <servlet>
        <servlet-name>]]><lineannotation><emphasis role="bold">spring-ws</emphasis></lineannotation><![CDATA[</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>]]></programlisting>
        <para>
            In addition to the above <filename>'WEB-INF/web.xml'</filename> file, you will also need another,
            Spring-WS-specific configuration file, named <filename>'WEB-INF/spring-ws-servlet.xml'</filename>.
            This file contains all of the Spring-WS-specific beans such as <literal>EndPoints</literal>,
            <literal>WebServiceMessageReceivers</literal>, and suchlike, and is used to create a new Spring container.
            The name of this file is derived from the name of the attendant servlet (in this case
            <literal>'spring-ws'</literal>) with <literal>'-servlet.xml'</literal> appended to it. So if you defined a
            <classname>MessageDispatcherServlet</classname> with the name <literal>'dynamite'</literal>, the name of the
            Spring-WS-specific configuration file would be <filename>'WEB-INF/dynamite-servlet.xml'</filename>.
        </para>
        <para>
            (You can see the contents of the <filename>'WEB-INF/spring-ws-servlet.xml'</filename> file for this
            example in <xref linkend="tutorial.example.sws-conf-file"/>.)
        </para>
    </section>
    <section id="tutorial.implementing.endpoint">
        <title>Implementing the Endpoint</title>
        <para>
           In Spring-WS, you will implement <emphasis>Endpoints</emphasis> to handle incoming XML messages.
           There are two flavors of endpoints: <link linkend="message-endpoint">message endpoints</link> and
           <link linkend="payload-endpoint">payload endpoints</link>. <emphasis>Message endpoints</emphasis>
           give access to the entire XML message, including SOAP headers. Typically, the endpoint will only be
           interested in the <emphasis>payload</emphasis> of the message, that is the contents of the SOAP body.
           In that case, creating a <emphasis>payload endpoint</emphasis> makes more sense.
        </para>
        <section>
            <title>Handling the XML Message</title>
            <para>
                In this sample application, we are going to use <ulink url="http://www.jdom.org">JDom</ulink> to handle
                the XML message. We are also using <ulink url="http://www.w3schools.com/xpath/">XPath</ulink>, because
                it allows us to select particular parts of the XML JDOM tree, without requiring strict schema
                conformance. We extend our endpoint from <classname>AbstractJDomPayloadEndpoint</classname>,
                because that will give us a JDOM element to execute the XPath queries on.
            </para>
            <programlistingco>
                <areaspec>
                    <area id="tutorial.endpoint.constr" coords="24"/>
                    <area id="tutorial.endpoint.invokeInternal" coords="35"/>
                </areaspec>
                <programlisting>
package com.mycompany.hr.ws;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.mycompany.hr.service.HumanResourceService;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.xpath.XPath;
import org.springframework.ws.server.endpoint.AbstractJDomPayloadEndpoint;

public class HolidayEndpoint extends AbstractJDomPayloadEndpoint {

    private XPath startDateExpression;

    private XPath endDateExpression;

    private XPath nameExpression;

    private final HumanResourceService humanResourceService;

    public HolidayEndpoint(HumanResourceService humanResourceService) {
        this.humanResourceService = humanResourceService;
        Namespace namespace = Namespace.getNamespace("hr", "http://mycompany.com/hr/schemas");
        startDateExpression = XPath.newInstance("//hr:StartDate");
        startDateExpression.addNamespace(namespace);
        endDateExpression = XPath.newInstance("//hr:EndDate");
        endDateExpression.addNamespace(namespace);
        nameExpression = XPath.newInstance("concat(//hr:FirstName,' ',//hr:LastName)");
        nameExpression.addNamespace(namespace);
    }

    protected Element invokeInternal(Element holidayRequest) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = dateFormat.parse(startDateExpression.valueOf(holidayRequest));
        Date endDate = dateFormat.parse(endDateExpression.valueOf(holidayRequest));
        String name = nameExpression.valueOf(holidayRequest);

        humanResourceService.bookHoliday(startDate, endDate, name);
        return null;
    }
}</programlisting>
                <calloutlist>
                    <callout arearefs="tutorial.endpoint.constr">
                        <para>
                            The <classname>HolidayEndpoint</classname> requires the
                            <interfacename>HumanResourceService</interfacename> business service to operate, so we
                            inject the dependency via the constructor. Next, we set up XPath expressions
                            using the JDOM API. There are three expressions: <literal>//hr:StartDate</literal> for
                            extracting the <literal>&lt;StartDate&gt;</literal> text value,
                            <literal>//hr:EndDate</literal> for
                            extracting the end date and <literal>concat(//hr:FirstName,' ',//hr:LastName)</literal>
                            for extracting and concatenating the names of the employee.
                        </para>
                    </callout>
                    <callout arearefs="tutorial.endpoint.invokeInternal">
                        <para>
                            The <methodname>invokeInternal(..)</methodname> method is a template method, which gets passed
                            with the <literal>&lt;HolidayRequest/&gt;</literal> element from the incoming XML message. We
                            use the XPath expressions to extract the string values from the XML messages,
                            and convert these values to <classname>Date</classname> objects using a
                            <classname>SimpleDateFormat</classname>. With these values, we invoke a method on the
                            business service. Typically, this will result in a database transaction being
                            started, and some records being altered in the database. Finally, we return
                            <literal>null</literal>, which indicates to Spring-WS that we do not want to send a
                            response message. If we wanted a response message, we could have returned a JDOM Element
                            that represents the payload of the response message.
                        </para>
                    </callout>
                </calloutlist>
            </programlistingco>
            <para>
                 Using JDOM is just one of the options to handle the XML: other options include DOM, dom4j, XOM,
                 SAX, and StAX, but also <link linkend="oxm">marshalling techniques</link> like JAXB, Castor, XMLBeans,
                 JiBX, and XStream. We chose JDOM because it gives us access to the raw XML, and because it
                 is based on classes (not interfaces and factory methods as with W3C DOM and dom4j), which makes the
                 code less verbose. We use XPath because it is less fragile than marshalling technologies: we don't
                 care for strict schema conformance, as long as we can find the dates and the name.
             </para>
             <para>
                 Because we use JDOM, we must add some dependencies to the Maven <filename>pom.xml</filename>, which is in the
                 root of our project directory. Here is the relevant section of the POM:
             </para>
             <programlisting><![CDATA[<dependencies>
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>1.5.3</version>
    </dependency>
    <dependency>
        <groupId>jdom</groupId>
        <artifactId>jdom</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.soap</groupId>
        <artifactId>saaj-api</artifactId>
        <version>1.3</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.messaging.saaj</groupId>
        <artifactId>saaj-impl</artifactId>
        <version>1.3</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>]]></programlisting>
             <para>
                Here is how we would configure these classes in our <filename>spring-ws-servlet.xml</filename>
                Spring XML configuration file:
            </para>
            <programlisting id="tutorial.example.sws-conf-file"><![CDATA[
<beans xmlns="http://www.springframework.org/schema/beans">

    <bean id="holidayEndpoint" class="com.mycompany.hr.ws.HolidayEndpoint">
        <constructor-arg ref="hrService"/>
    </bean>

    <bean id="hrService" class="com.mycompany.hr.service.StubHumanResourceService"/>

</beans>]]></programlisting>
            </section>
            <section>
                <title>Routing the Message to the Endpoint</title>
                <para>
                    Now that we have written an endpoint that handles the message, we must define how incoming messages
                    are routed to that endpoint. In Spring-WS, this is the responsibility of an
                    <interfacename>EndpointMapping</interfacename>. In this tutorial, we will route messages based on
                    their content, by using a <classname>PayloadRootQNameEndpointMapping</classname>. Here is how we
                    configure a <classname>PayloadRootQNameEndpointMapping</classname> in <filename>spring-ws-servlet.xml</filename>:
                </para>
            <programlisting><![CDATA[
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
    <property name="mappings">
        <props>
            <prop key="{http://mycompany.com/hr/schemas}HolidayRequest">holidayEndpoint</prop>
        </props>
    </property>
    <property name="interceptors">
        <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
    </property>
</bean>]]></programlisting>
                <para>
                    This means that whenever an XML message is received with the namespace
                    <literal>http://mycompany.com/hr/schemas</literal> and the
                    <literal>HolidayRequest</literal> local name, it will be routed to the
                    <varname>holidayEndpoint</varname>.
                    (It also adds a <classname>PayloadLoggingInterceptor</classname>,
                    that dumps incoming and outgoing messages to the log.)
                </para>
        </section>
    </section>
    <section id="tutorial-publishing-wsdl">
        <title>Publishing the WSDL</title>
        <para>
            Finally, we need to publish the WSDL. As stated in <xref linkend="tutorial-service-contract"/>, we don't
            need to write a WSDL ourselves; Spring-WS can generate one for us based on some conventions.
            Here is how we define the generation:
        </para>
        <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"/>
            </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>
            <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.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.gen.portType">
                    <para>
                        Next, we define the WSDL port type to be <literal>HumanResource</literal>.
                    </para>
                </callout>
                <callout arearefs="tutorial.wsdl.gen.locationUri">
                    <para>
                        We set the location where the service can be reached:
                        <uri>/holidayService/</uri>. We use a a relative URI and we instruct the framework to transform it
                        dynamically to an absolute URI. Hence, if the service is deployed to different contexts we don't have
                        to change the URI manually. For more information, please refer to <xref linkend="server-automatic-wsdl-exposure"/>
                    </para>
                </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.
                    </para>
                </callout>
            </calloutlist>
        </programlistingco>
        <para>
            You can create a WAR file using <command>mvn install</command>.
            If you deploy the application (to Tomcat, Jetty, etc.), and point your browser at
            <ulink url="http://localhost:8080/holidayService/holiday.wsdl">this location</ulink>, you will
            see the generated WSDL. This WSDL is ready to be used by clients, such as
            <ulink url="http://www.soapui.org/">soapUI</ulink>, or other SOAP frameworks.
        </para>
    </section>
    <para>
        That concludes this tutorial. The tutorial code can be found in the full distribution of Spring-WS.
        The next step would be to look at the echo sample application that is part
        of the distribution. After that, look at the airline sample, which is a bit more complicated, because it
        uses JAXB, WS-Security, Hibernate, and a transactional service layer.
        Finally, you can read the rest of the reference documentation.
    </para>
</chapter>
