6 Feb 2013

Spring Web Service

Create a Contract-First Spring Web Service
Contract-First Web Service is to develop web services by starting with the XML Schema/WSDL contract first followed by the Java code second.

Implementation

  1. Create the XML Schema.
    1. Define the XML Schema for the Request and Response messages.
    2. Save the XML Schema as "lucky.xsd" under the folder "WEB-INF/xsd".
    <?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://com.blogspot.adaprognotebook/LuckyService/" elementFormDefault="qualified"> <xsd:element name="LuckyRequest"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="LuckyResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="message" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
  2. Create and define the service interface in Java.

    LuckyService.java

    package main.java.com.blogspot.adaprognotebook.service; public interface LuckyService { String sayLuckyMessage(String name); }

    LuckyServiceImpl.java

    package main.java.com.blogspot.adaprognotebook.service; public class LuckyServiceImpl implements LuckyService { @Override public String sayLuckyMessage(String name) { if (name == null || name.trim().isEmpty()) { return "Tell me you name~~~"; } int number = (int)(Math.random()*100); return "Hello : " + name + "! Your lucky number is " + number + "."; } }
  3. Create the Object/XML binding.
    1. Create POJO classes for the Request (LuckyRequest.java) and Response (LuckyResponse.java) in Java.

      LuckyRequest.java

      package com.blogspot.adaprognotebook.message; public class LuckyRequest { private String name; public LuckyRequest() { super(); } public LuckyRequest(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

      LuckyResponse.java

      package com.blogspot.adaprognotebook.message; public class LuckyResponse { private String message; public LuckyResponse() { super(); } public LuckyResponse(String message) { this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
    2. Define the Object/XML binding using JiBX for the purpose of marshalling and unmarshalling for the above model classes.
    3. binding.xml

      <binding name="binding" package="com.blogspot.adaprognotebook.message" trim-whitespace="true"> <namespace uri="http://localhost:8080/luckyservice/" default="elements"/> <mapping class="com.blogspot.adaprognotebook.message.LuckyRequest" name="LuckyRequest"> <value style="element" name="name" get-method="getName" set-method="setName"/> </mapping> <mapping class="com.blogspot.adaprognotebook.message.LuckyResponse" name="LuckyResponse"> <value style="element" name="message" get-method="getMessage" set-method="setMessage"/> </mapping>
  4. Configure Spring's Application Context.

    WEB-INF/spring/applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"? <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"> <property name="endpointMap"> <map> <entry key="{http://localhost:8080/luckyservice/}/LuckyRequest" value-ref="luckyServiceEndpoint" /> </map> </property> </bean> <bean id="luckyService" class="com.blogspot.adaprognotebook.service.LuckyServiceImpl" /> <bean id="luckyServiceEndpoint" class="com.blogspot.adaprognotebook.endpoint.LuckyServiceEndpoint"> <property name="marshaller" ref="marshaller" /> <property name="unmarshaller" ref="unmarshaller" /> <property name="luckyService" ref="luckyService" /> </bean> <bean id="marshaller" class="org.springframework.oxm.jibx.JibxMarshaller"> <property name="targetClass" value="com.blogspot.adaprognotebook.message.LuckyResponse" /> </bean> <bean id="unmarshaller" class="org.springframework.oxm.jibx.JibxMarshaller"> <property name="targetClass" value="com.blogspot.adaprognotebook.message.LuckyRequest" /> </bean> <bean id="LuckyRequest" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition"> <property name="schema" ref="schema" /> <property name="portTypeName" value="Hello" /> <property name="locationUri" value="http://localhost:8080/luckyservice/services/LuckyRequest" /> </bean> <bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema"> <property name="xsd" value="/WEB-INF/xsd/lucky.xsd" /> </bean> </beans>
  5. Define the Endpoint.
    package com.blogspot.adaprognotebook.endpoint; import com.blogspot.adaprognotebook.message.HelloRequest; import com.blogspot.adaprognotebook.message.HelloResponse; import com.blogspot.adaprognotebook.service.HelloService; import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint; @SuppressWarnings("deprecation") public class HelloServiceEndpoint extends AbstractMarshallingPayloadEndpoint { private HelloService helloService; protected Object invokeInternal(Object requestObject) throws Exception { HelloRequest request = (HelloRequest) requestObject; String name = request.getName(); return new HelloResponse(helloService.sayhello(name)); } public HelloService getHelloService() { return helloService; } public void setHelloService(HelloService helloService) { this.helloService = helloService; } }
  6. Deploy the web service to Web Server like Jetty.
  7. View the generated WSDL at http://localhost:8080/luckyservice/LuckyRequest.wsdl.
    <?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace="http://localhost:8080/luckyservice/" xmlns:sch="http://localhost:8080/luckyservice/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://localhost:8080/luckyservice/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <xsd:schema elementFormDefault="qualified" targetNamespace="http://localhost:8080/luckyservice/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="LuckyRequest"> <xsd:complexType> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="LuckyResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="message" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="LuckyResponse"> <wsdl:part element="sch:LuckyResponse" name="LuckyResponse"> </wsdl:part> </wsdl:message> <wsdl:message name="LuckyRequest"> <wsdl:part element="sch:LuckyRequest" name="LuckyRequest"> </wsdl:part> </wsdl:message> <wsdl:portType name="Lucky"> <wsdl:operation name="Lucky"> <wsdl:input message="sch:LuckyRequest" name="LuckyRequest"> </wsdl:input> <wsdl:output message="sch:LuckyResponse" name="LuckyResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="LuckySoap11" type="sch:Lucky"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="Lucky"> <soap:operation soapAction=""/> <wsdl:input name="LuckyRequest"> <soap:body use="literal"/> </wsdl:input> <wsdl:output name="LuckyResponse"> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="LuckyService"> <wsdl:port binding="sch:LuckySoap11" name="LuckySoap11"> <soap:address location="http://localhost:8080/luckyservice/services/LuckyRequest"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
  8. Test the web service using tools like SOAP UI.

No comments: