Saturday, December 3, 2011

Web Services using Spring-WS Part 1

Sample Web Service example using Spring-WS


  1. Since Spring-WS uses contract-first style of developing web services, starting with WSDL contract and using Java to implement it (for more detail visit Spring-WS site), we will start with defining a simple XML schema.
    Location: WEB-INF

    Based on above Schema, the XML document can have 2 possible root elements:
    1. PersonRequest element which contains a Person element with FirstName and LastName
    2. PersonResponse element with FullName and SSN
    Here are sample XMLs



  2. Create an Endpoint class to handle XML requests. getPerson() takes JDOM Element as a parameter. Using XPath we can execute queries on the element, selecting specific parts of the XML JDOM tree. In later sections we will explore different parameters.


    1. Line 1 - @Endpoint annotates that this is a web service endpoint
    2. Line 4 - Namespace defined in your XML Schema
    3. Line 11 - @Autowired annotates that this constructor is to be autowired. Spring will scan beans defined in configuration files and match them by data types. Once found, an instance of that class is created and injected.
    4. Line 22 - @PayloadRoot marks an endpoint method as the handler for an incoming request. Any request of 'PersonRequest' root element will be handled by getPerson method
    5. Line 23 - @ResponsePayload annotates that the method return value should be bound to response payload. For void methods, remove the annotation.
    6. Line 24 - @RequestPayload annotates that method parameter should be bound to request payload.
    The rest of the logic calls a service and then builds a JDOM element that gets returned.
  3. Now we need Spring-WS configuration file. You can name the file anything, as long as it matches servlet-name defined in web.xml and ends with "-servlet.xml". More on that in Step 4.
    Location : WEB-INF


    1. Line 5 - Defines a package to scan for components and beans annotated with @Repository, @Component, @Service, or @Controller and would automatically get registered in the application context. PersonService class is annotated with @Component (or can be @Service).
    2. Line 7 - Instruct Spring-WS to use annotation-driven endpoints
  4. Configurations are need in web.xml file to add Spring-WS Servlet. This example uses MessageDispatcherServlet and can be configured to map any type of request (i.e. /ws/* requests). Because this servlet is a standard DispatcherServlet, it will look for a file name [servlet-name]-servlet.xml (spring-ws-servlet.xml created in Step 3) in your WEB-INF and create beans defined in configuration file inside the Spring container.


  5. When using MessageDispatcherServlet, you get the benefit of automatic WSDL exposure. WSDL is used for describing the functionality of your Web Service. It's machine-readable description of how the service can be called, what parameters it expects and what data structures it returns. The MessageDispatcherServlet will automatically detect any WsdlDefinition beans defined in its Spring container and expose them. Add the following configuration to your spring-ws-servlet.xml and web.xml files:

    1. Line 1 - id determines the URL where the WSDL can be retrieved (person.wsdl)
    2. Line 2 - locationuri defines location where the service can be reached (/ws/PersonService/). Using relative URI, we instruct the framework to transform it dynamically to an absolute URI, this way if the service is deployed to different contexts we don't have to change the URI manually
    3. Line 3 - porttypename defines WSDL port type
    4. Line 4 - targetnamespace is not required and if not set will have the same namespace as the XSD schema.
    5. Line 5 - location of XML schema we define in Step 1
    For location transformation to work (mentioned under locationuri), we need to add the following init-param to our servlet in web.xml

  6. List of JARs


  7. Deploy Application to a Server
  8. Using a SOAP client, such as soapUI, you can test out your Web Service. To view your WSDL use the following URL : http://localhost:[port]/[project name]/[servlet-mapping]/[xml-schema].wsdl (i.e. http://localhost:9080/PersonServices/ws/person.wsdl). You can paste the URL in the browser to view generated file.
  9. JUnit Testing is easy with Spring. Create your Test class using SpringJUnit4ClassRunner. Since WEB-INF is never in your classpath, create a copy of your Spring configuration file and save it in the same package as your Test class.
    Here is a sample Test case :

  10. This concludes Part 1 of Spring-WS example.