dimarts, 5 de juliol del 2011

Creating Spring web services using annotations

In this entry, I'm about to show how easy it is to create a web service using Spring-WS using annotations. Spring-WS makes it very easy to publish webservices so that you can publish your already existing services. It is based on JAX-WS, so it is great for application servers like Weblogic, since it uses the same web service technology stack.

To create a Spring-WS based web service, we just need to implement one class: the endpoint. By the way, since we are using Spring, usually it'd be better to implement the logic for the web service in its own service class, so that's the way we're going to take...

To create the enpoint class we just need to create a class extending org.springframework.web.context.support.SpringBeanAutowiringSupport and annotated by javax.jws.WebService. Once we have this class, any method representing an operation in the service, will have to be annotated by javax.jws.WebMethod.

Supose we want to publish a web service called GreetingsService with an operation sayHi. In this case, we'd create the following endpoint class:

import javax.jws.WebMethod;
import javax.jws.WebService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

@WebService(serviceName="greetingsService")
public class GreetingsServiceEndpoint extends SpringBeanAutowiringSupport {

   @Autowired
   private GreetingsService greetingsService;

   @WebMethod
   public String sayHi() {
      return greetingsService.sayHi();
   }
}
Of course, we're not going into details about the GreetingService definition nor into how to configura my app to use Spring.

If we package and deploy this service, the url http://localhost:7001/springws-sample/greetingsService?wsdl (I'm currently using Weblogic), will return the following WSDL:
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
   Oracle JAX-WS 2.1.5. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
   Oracle JAX-WS 2.1.5. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:tns="http://endpoint.springws.aigloss.blogspot.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://endpoint.springws.aigloss.blogspot.com/"
   name="greetingsService">
   <types>
      <xsd:schema>
         <xsd:import namespace="http://endpoint.springws.aigloss.blogspot.com/"
            schemaLocation="http://localhost:7001/springws-sample/greetingsService?xsd=1" />
      </xsd:schema>
   </types>
   <message name="sayHi">
      <part name="parameters" element="tns:sayHi" />
   </message>
   <message name="sayHiResponse">
      <part name="parameters" element="tns:sayHiResponse" />
   </message>
   <portType name="GreetingsServiceEndpoint">
      <operation name="sayHi">
         <input message="tns:sayHi" />
         <output message="tns:sayHiResponse" />
      </operation>
   </portType>
   <binding name="GreetingsServiceEndpointPortBinding" type="tns:GreetingsServiceEndpoint">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"
         style="document" />
      <operation name="sayHi">
         <soap:operation soapAction="" />
         <input>
            <soap:body use="literal" />
         </input>
         <output>
            <soap:body use="literal" />
         </output>
      </operation>
   </binding>
   <service name="greetingsService">
      <port name="GreetingsServiceEndpointPort" binding="tns:GreetingsServiceEndpointPortBinding">
         <soap:address
            location="http://localhost:7001/springws-sample/greetingsService" />
      </port>
   </service>
</definitions>

In the following entry, I'll explain how add a handler to the web service so that we can, for example, extract the user from a SAML token sent within the request to the web service,

4 comentaris:

  1. Thanks for the example. Do you happen to know how to generate inline schemas in wsdl instead of references in the same example above.

    ResponElimina
  2. 10:37:44.788 [main] DEBUG org.springframework.web.context.support.SpringBeanAutowiringSupport - Current WebApplicationContext is not available for processing of : Make sure this class gets constructed in a Spring web application. Proceeding without injection.

    ResponElimina