diff --git a/src/docbkx/tutorial.xml b/src/docbkx/tutorial.xml index 795f2d51..1e6f5acc 100644 --- a/src/docbkx/tutorial.xml +++ b/src/docbkx/tutorial.xml @@ -273,74 +273,42 @@ Note that in Spring-WS, writing the WSDL by hand is not required. Based on the XSD and some conventions, Spring-WS can create the WSDL for you, as explained in . - You can skip to that section if you want to; the remainder of this section will show you how to write your - own WSDL by hand. + You can skip to the next section if you want to; the + remainder of this section will show you how to write your own WSDL by hand. 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: http://mycompany.com/hr/definitions. - -<wsdl:definitions name="HumanResources" - targetNamespace="http://mycompany.com/hr/definitions" - xmlns:tns="http://mycompany.com/hr/definitions" - xmlns:types="http://mycompany.com/hr/schemas"> - xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" - xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> - <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:definitions> - + + + + + + ]]> - Next, we define our messages based on the written schema. We only have one message: one with the + Next, we add our messages based on the written schema types. We only have one message: one with the HolidayRequest we put in the schema: - -<wsdl:definitions name="HumanResources" - targetNamespace="http://mycompany.com/hr/definitions" - xmlns:tns="http://mycompany.com/hr/definitions" - xmlns:types="http://mycompany.com/hr/schemas" - xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" - xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> - <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="RequestHolidayInput">> - <wsdl:part name="body" element="types:HolidayRequest" /> - </wsdl:message> -</wsdl:definitions> + + + ]]> We add the message to a port type as operation: - -<wsdl:definitions name="HumanResources" - targetNamespace="http://mycompany.com/hr/definitions" - xmlns:tns="http://mycompany.com/hr/definitions" - xmlns:types="http://mycompany.com/hr/schemas" - xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" - xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> - <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="RequestHolidayInput"> - <wsdl:part name="body" element="types:HolidayRequest" /> - </wsdl:message> - <wsdl:portType name="HumanResourcesPortType"> - <wsdl:operation name="RequestHoliday"> - <wsdl:input message="tns:RequestHolidayInput" /> - </wsdl:operation> - </wsdl:portType> -</wsdl:definitions> + + + + + ]]> That finished the abstract part of the WSDL (the interface, as it were), and leaves the concrete part. The concrete part consists of a binding, which tells the client how @@ -351,68 +319,67 @@ Adding a concrete part is pretty standard: just refer to the abstract part you defined previously, make sure you use document/literal for the soap:binding elements (rpc/encoded is deprecated), pick a soapAction for the operation - (in this case http://example.com/RequestHoliday, but any URI will do), and determine the + (in this case http://mycompany.com/RequestHoliday, but any URI will do), and determine the location URL where you want request to come in (in this case http://mycompany.com/humanresources): - + - - + + - + - - + + - - + + - - + + - - - + + + + - - + + - - - + + + - + - - - - - + transport="http://schemas.xmlsoap.org/soap/http"/> + + + + + - - - + + + ]]> @@ -424,7 +391,7 @@ - We define the RequestHolidayInput message, which gets used in the + We define the HolidayRequest message, which gets used in the portType. @@ -435,13 +402,13 @@ - We define the HumanResourcesPortType port type, which gets used in the + We define the HumanResource port type, which gets used in the binding. - We define the HumanResourcesBinding binding, which gets used in the + We define the HumanResourceBinding binding, which gets used in the port. @@ -474,7 +441,7 @@ This is the final WSDL. We will describe how to implement the resulting schema and WSDL in the next section. -
+
Creating the project In this section, we will be using Maven2 to create the @@ -489,9 +456,9 @@ ~/.m2/settings.xml in order to find the archetype: - springframework.org - Springframework Maven SNAPSHOT Repository - http://static.springframework.org/maven2-snapshots/ + spring-s3 + Spring S3 Maven SNAPSHOT Repository + http://s3.amazonaws.com/maven.springframework.org true @@ -511,26 +478,24 @@ which defines a Spring-WS MessageDispatcherServlet, and maps all incoming requests to this servlet: - -<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> + MyCompany HR Holiday Service - <servlet> - <servlet-name>spring-ws</servlet-name> - <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> - </servlet> + + spring-ws + org.springframework.ws.transport.http.MessageDispatcherServlet + - <servlet-mapping> - <servlet-name>spring-ws</servlet-name> - <url-pattern>/*</url-pattern> - </servlet-mapping> + + spring-ws + /* + -</web-app> - +]]> We could have made the servlet more restrictive by using the url pattern /humanresources, but this will suffice for now. @@ -553,10 +518,10 @@
Handling the XML Message - In this sample application, we are going to use JDom to handle the - XML message. We are also using XPath, because it - allows us to select particular parts of the XML JDOM tree, without requiring strict schema conformance. - We extend our endpoint from AbstractJDomPayloadEndpoint, + In this sample application, we are going to use JDom to handle + the XML message. We are also using XPath, because + it allows us to select particular parts of the XML JDOM tree, without requiring strict schema + conformance. We extend our endpoint from AbstractJDomPayloadEndpoint, because that will give us a JDOM element to execute the XPath queries on. @@ -598,7 +563,7 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint { startDateExpression.addNamespace(namespace); endDateExpression = XPath.newInstance("//hr:EndDate"); endDateExpression.addNamespace(namespace); - nameExpression = XPath.newInstance("//hr:FirstName|//hr:LastName"); + nameExpression = XPath.newInstance("concat(//hr:FirstName,' ',//hr:LastName)"); nameExpression.addNamespace(namespace); } @@ -626,8 +591,8 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint { using the JDOM API. There are three expressions: //hr:StartDate for extracting the >StartDate< text value, //hr:EndDate for - extracting the end date and //hr:FirstName|//hr:LastName - for extracting the name of the employee. + extracting the end date and concat(//hr:FirstName,' ',//hr:LastName) + for extracting and concatenating the names of the employee. @@ -659,33 +624,36 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint { root of our project directory. Here is the relevant section of the POM: - org.springframework.ws - spring-ws-core - 1.0-m3 - - - jdom - jdom - 1.0 - - - jaxen - jaxen - 1.1 - - - javax.xml.soap - saaj-api - 1.3 - runtime - - - com.sun.xml.messaging.saaj - saaj-impl - 1.3 - runtime -]]> + + + org.springframework.ws + spring-ws-core + 1.0-m3 + + + jdom + jdom + 1.0 + + + jaxen + jaxen + 1.1 + + + javax.xml.soap + saaj-api + 1.3 + runtime + + + com.sun.xml.messaging.saaj + saaj-impl + 1.3 + runtime + + +]]> Here's how we would wire up these classes in our spring-ws-servlet.xml application context: @@ -744,16 +712,18 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint { + - - - - - - - - - + + + + + + + + + ]]> @@ -778,8 +748,17 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint { - Finally, we set the location where the service can be reached: - http://localhost:8080/holidayService. + We set the location where the service can be reached: + http://localhost:8080/holidayService. For development, this will suffice, but + obviously we need to change this to http://mycompany.com/humanresources when going + live. One way to keep this to accomplish this would be to use Spring + PropertyPlaceholderConfigurer. + + + + + Finally, we define the target namespace and prefix for the WSDL definition itself. Setting these + is not required. If not set, we give the WSDL the same namespace as the schema. @@ -794,7 +773,8 @@ public class HolidayEndpoint extends AbstractJDomPayloadEndpoint {
- That concludes this tutorial. The next step would be to look at the echo sample application, that is part + 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.