Wednesday 3 September 2014

SOAP WebService Example Service using spring and apache cxf (Top To Bottom Approach)

=>Procedure
1)Add maven Dependencies for spring and apache cxf
2)Write wsdl and xsd 
3)Generate stubs(Generated java classes,use wsimport command)
4)Develope implementation class
5)Configue implementation class as spring bean in spring configuration file
6)Configure CXFServlet in web.xml file
7)Deploy the project into any web server

1)=>First add maven dependencies to your project

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>SoapBasicExampleTopToBottom</groupId>
    <artifactId>SoapBasicExampleTopToBottom</artifactId>
    <version>1</version>
    <packaging>war</packaging>
    <properties>
        <cxf.version>2.7.2</cxf.version>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-ws-addr</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-ws-security</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
    </dependencies>
  </project>


2)=> Write wsdl,xsd ,Here service name is DemoService,method name is Addition.

DemoService.wsdl

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:demoService="http://com.ram/services/demo"
targetNamespace="http://com.ram/services/demo">

    <wsdl:types>
        <xsd:schema>
            <xsd:import namespace="http://com.ram/services/demo" schemaLocation="DemoService.xsd"/>
        </xsd:schema>
    </wsdl:types>

    <wsdl:message name="AdditionInputMessage">
        <wsdl:part name="AdditionInputPart" element="demoService:AdditionRequest"/>
    </wsdl:message>
    <wsdl:message name="AdditionOutputMessage">
        <wsdl:part name="AdditionOutputPart" element="demoService:AdditionResponse"/>
    </wsdl:message>
    <wsdl:message name="AdditionFaultMessage">
        <wsdl:part name="AdditionFaultPart" element="demoService:AdditionFault"/>
    </wsdl:message>
   
    <wsdl:portType name="DemoServicePortType">
        <wsdl:operation name="Addition">
            <wsdl:input name="AdditionInput" message="demoService:AdditionInputMessage"/>
            <wsdl:output name="AdditionOutput" message="demoService:AdditionOutputMessage"/>
            <wsdl:fault name="AdditionFault" message="demoService:AdditionFaultMessage"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="DemoServiceBinding" type="demoService:DemoServicePortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Addition">
            <soap:operation soapAction="Addition"/>
            <wsdl:input name="AdditionInput">
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output name="AdditionOutput">
                <soap:body use="literal"/>
            </wsdl:output>
            <wsdl:fault name="AdditionFault">
                <soap:fault name="AdditionFault" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
    </wsdl:binding>

    <wsdl:service name="DemoService">
        <wsdl:port name="demoServicePort" binding="demoService:DemoServiceBinding">
            <soap:address location="No Target Adress"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>


DemoService.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://com.ram/services/demo" targetNamespace="http://com.ram/services/demo"
    elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="AdditionRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="value1" type="xs:integer"/>
                <xs:element name="value2" type="xs:integer"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="AdditionResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="result" type="xs:integer"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="AdditionFault">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Fault" type="xs:string">
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>


3)=> Generate stubs based on your wsdl

wsimport -keep -s yourProjectsrcLocation yourProjectWsdlUrl

4)=> Provide Implementation 

package com.iton.serviceimpl;

import java.math.BigInteger;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;

import ram.com.services.demo.AdditionFaultMessage;
import ram.com.services.demo.AdditionRequest;
import ram.com.services.demo.AdditionResponse;
import ram.com.services.demo.DemoServicePortType;

/**
 *
 * @author ramakrishna.v
 *
 */
public class ArithmeticServiceImpl implements DemoServicePortType {

    @Override
    @WebResult(name = "AdditionResponse", targetNamespace = "http://com.ram/services/demo", partName = "AdditionOutputPart")
    @WebMethod(operationName = "Addition", action = "Addition")
    public AdditionResponse addition(
            @WebParam(partName = "AdditionInputPart", name = "AdditionRequest", targetNamespace = "http://com.ram/services/demo") AdditionRequest additionInputPart)
            throws AdditionFaultMessage {
       
        BigInteger value1 = additionInputPart.getValue1();
        BigInteger value2 = additionInputPart.getValue2();
        BigInteger result =  value1.add(value2);
        System.out.println(result);
        AdditionResponse obj = new AdditionResponse();
        obj.setResult(result);
       
        return obj;
    }
}


 5)=>Configure this implementation class in spring configuration file

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" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:wsa="http://cxf.apache.org/ws/addressing"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
      http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://cxf.apache.org/jaxws
    http://cxf.apache.org/schemas/jaxws.xsd">

    <context:annotation-config />
   
    <bean id="demoService" class="com.iton.serviceimpl.ArithmeticServiceImpl"/>
   
    <jaxws:endpoint id="Demo" implementor="#demoService"
        address="/DemoService" xmlns:tns="http://com.ram/services/demo"
        serviceName="tns:DemoService" endpointName="tns:demoServicePort"
        wsdlLocation="wsdl/DemoService.wsdl">
    </jaxws:endpoint> 
</beans>


6)Configure CXFServlet in web.xml file

<web-app>
<display-name>SoapTopToBottomExample</display-name>
  <context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>WEB-INF/applicationContext.xml</param-value>
 </context-param>
<!-- <listener>
   <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener -->
       <listener>
               <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
       </listener>

       <servlet>
               <servlet-name>CXFServlet</servlet-name>
               <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
               <load-on-startup>1</load-on-startup>
       </servlet>
      
       <servlet-mapping>
               <servlet-name>CXFServlet</servlet-name>
               <url-pattern>/*</url-pattern>
       </servlet-mapping>
</web-app>



7)Deploy the project into web server.For example It will display the web service wsdl url as follows.

=>http://localhost:7777/SoapBasicExampleTopToBottom