Spring-ws API works on the principal of contract first SOAP webservice. In this type of webservice implementation the wsdl is created first. In contract last SOAP webservice the JAVA code is created first which inturns creates the wsdl. The contract first webservice is a bit difficult to implement as compared to contract last webservice as the xsd and wsdl needs to be created manually. Contract first webservice is more advantageous though as it eliminates the impedance mismatch problem. Below code snippets explains how to use spring-ws to implement the SOAP based webservice.
The first thing to do is to identify the request and response xml and to create the XSD. The xsd can be created using any online tools.
Since Spring-ws is a contract first API we have to come up with the xsd.
The XSD will be used to generate the wsdl in later sections.
The next thing is to create the web.xml file.
web.xml
spring-ws-servlet.xml
This file below dynamic-wsdl tag which uses the xsd to create the wsdl. Also 2 interceptors are mentioned. One to validate the request/response messages and the other one to print the request/response on console.
Next is to create the request and response classes. This can be done by using the xjc command in JAVA_HOME\bin folder. What it needs is just the xsd. Go to the folder where the xsd is saved and type the below command.
Now finally we create the endpoint class. The actual webservice. This class used JAXB marshaller to marshall and unmarshall the request/response objects.
Once the services is UP, you can test the webservice using any webservice client like jax-ws or any other tool.
Below is the sample request and response tested in SOAPUI
SOAP Request
SOAP Response
Below is the structure of the application for your reference
For Web Service Introduction click here
Below are some posts that explain how to implement and test SOAP/REST Webservices
The first thing to do is to identify the request and response xml and to create the XSD. The xsd can be created using any online tools.
Since Spring-ws is a contract first API we have to come up with the xsd.
The XSD will be used to generate the wsdl in later sections.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:login="http://mycompany.com/login/schemas" elementFormDefault="qualified" targetNamespace="http://mycompany.com/login/schemas"> <xs:element name="LoginRequest"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="username" /> <xs:element type="xs:string" name="password" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Response"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="message" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>Next create a Maven web application with dependencies as mentioned below
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.ws</groupId> <artifactId>spring-ws-core</artifactId> <version>2.1.3.RELEASE</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> </dependencies>
The next thing is to create the web.xml file.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <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>Live Restaurant</display-name> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>1000</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> <init-param> <param-name>transformWsdlLocations</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>spring-ws</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>Above here MessageDispatcherServlet is defined which is the entry point of the SOAP webservice. As in Spring MVC the servlet looks for spring-ws-servlet.xml file.
spring-ws-servlet.xml
This file below dynamic-wsdl tag which uses the xsd to create the wsdl. Also 2 interceptors are mentioned. One to validate the request/response messages and the other one to print the request/response on console.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <context:component-scan base-package="com.login" /> <sws:annotation-driven /> <sws:dynamic-wsdl id="login" portTypeName="SocialNetwork" locationUri="/loginService/" targetNamespace="http://mycompany.com/login/definitions"> <sws:xsd location="/WEB-INF/login.xsd" /></sws:dynamic-wsdl> <sws:interceptors> <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"> <property name="schema" value="/WEB-INF/login.xsd" /> <property name="validateRequest" value="true" /> <property name="validateResponse" value="true" /> </bean> <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"> </bean> </sws:interceptors> </beans>
Next is to create the request and response classes. This can be done by using the xjc command in JAVA_HOME\bin folder. What it needs is just the xsd. Go to the folder where the xsd is saved and type the below command.
C:\Softwares\xsd>xjc . parsing a schema... compiling a schema... com\mycompany\login\schemas\LoginRequest.java com\mycompany\login\schemas\ObjectFactory.java com\mycompany\login\schemas\Response.java com\mycompany\login\schemas\package-info.java
Now finally we create the endpoint class. The actual webservice. This class used JAXB marshaller to marshall and unmarshall the request/response objects.
package com.login; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.util.JAXBSource; import javax.xml.transform.Source; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import org.springframework.ws.server.endpoint.annotation.ResponsePayload; @Endpoint public class LoginEndpoint { private static final String NAMESPACE_URI = "http://mycompany.com/login/schemas"; @PayloadRoot(namespace = NAMESPACE_URI, localPart = "LoginRequest") public @ResponsePayload Source handleHolidayRequest(@RequestPayload Source source) throws Exception { System.out.println("in here called"); LoginRequest loginRequest = (LoginRequest)unmarshal(source,LoginRequest.class); Response response = new Response(); response.setMessage("welcome user " + loginRequest.getUsername()); return marshal(response); } private Source marshal(Object obj) throws JAXBException { JAXBContext context = JAXBContext.newInstance(obj.getClass()); return new JAXBSource(context, obj); } private Object unmarshal(Source source, Class clazz) throws JAXBException { JAXBContext context; try { context = JAXBContext.newInstance(clazz); Unmarshaller um = context.createUnmarshaller(); return um.unmarshal(source); } catch (JAXBException e) { e.printStackTrace(); throw e; } } }After the webapplication is deployed correctly, you can view the wsdl by hitting the below URL on browser:
http://localhost:8080/Login_Simple/login.wsdl
Once the services is UP, you can test the webservice using any webservice client like jax-ws or any other tool.
Below is the sample request and response tested in SOAPUI
SOAP Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://mycompany.com/login/schemas"> <soapenv:Header/> <soapenv:Body> <sch:LoginRequest> <sch:username>Hunaid</sch:username> <sch:password>password@123</sch:password> </sch:LoginRequest> </soapenv:Body> </soapenv:Envelope>
SOAP Response
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <Response xmlns="http://mycompany.com/login/schemas"> <message>welcome user Hunaid</message> </Response> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Below is the structure of the application for your reference
For Web Service Introduction click here
Below are some posts that explain how to implement and test SOAP/REST Webservices
Host | |
SOAP | REST |
JAX-WS | JAX-RS |
Spring-ws | Spring-MVC-REST |
Client | |
SOAP | REST |
JAX-WS(wsimport) | Google REST APP |
SOAP UI | Apache REST |