Search code examples
springweb-serviceswsdlspring-wswebservicetemplate

How to consume third party WSDL services in Spring MVC


I wrote some services (used by an Android app) which takes a request and sends th response in json. Now I have a scenario where I have to consume a third party web service, through a provided WSDL file. I don't know how to do this, can anyone help?

This is my dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans ">

    <context:property-placeholder location="classpath:jdbc.properties" />   
    <context:component-scan base-package="com.srihari" />

    <tx:annotation-driven transaction-manager="hibernateTransactionManager" /> 

    <mvc:annotation-driven />

    <bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/view/" />
        <property name="suffix" value=".jsp" />
    </bean>

     <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>              
                <value>com.srihari.model.User</value>                       
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
               <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean> 
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

//This is used to convert my requests and responses into json automatically

    <bean id="jacksonMessageChanger" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes" value="application/json"/>
    </bean>

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <util:list id="beanList">
                <ref bean="jacksonMessageChanger"/>
            </util:list>
        </property>
    </bean>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json"/>
                <entry key="html" value="text/html"></entry>
                <entry key="xml" value="application/xml"></entry>
            </map>
        </property>
    </bean>

</beans>

This is my simple controller: These services are working fine

@Controller
@RequestMapping("/home")
public class UserController {

    @RequestMapping(value="/getallusers",method = RequestMethod.GET)
    public @ResponseBody List<User> getallusers() 
    {
        List<User> allUsersDetails =userServices.getAllUsers();
        return allUsersDetails;
    }
}

This is the WSDL file provided by the third party

POST /someservices/otherService.asmx HTTP/1.1
Host: sriharicorp.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/CreateCard"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <UserCredentials xmlns="http://tempuri.org/">
      <Password>string</Password>
      <Username>string</Username>
    </UserCredentials>
  </soap:Header>
  <soap:Body>

Example String Request 

    <CreateCard xmlns="http://tempuri.org/">
      <request>
        <DePpAcctCreationDate>string</DePpAcctCreationDate>
        <DePpAcctCreationTime>string</DePpAcctCreationTime>
        //Some other fields also
      </request>
    </CreateCard>
  </soap:Body>
</soap:Envelope>

Example String Response

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <CreateCardResponse xmlns="http://tempuri.org/">
      <CreateCardResult>
        <RequestType>string</RequestType>
        <ProductType>string</ProductType>
        <ResponseCode>string</ResponseCode>
        <ReasonDescription>string</ReasonDescription>
      </CreateCardResult>
    </CreateCardResponse>
  </soap:Body>
</soap:Envelope>

Solution

  • Finally I'm able to access Third services.

    This is my method to access service

       public void createSoapActionCallBack(ValidateCardRequest validateCardRequest) {
    
            //This is used to send header message
            SoapActionCallback actionCallBack=new SoapActionCallback(soapAction);
            try{
    
                actionCallBack = new SoapActionCallback(ResponseConstants.SOAPACTION_DEFAULT_URL) {
                public void doWithMessage(WebServiceMessage msg) {
                        SoapMessage smsg = (SoapMessage)msg;                
                        SoapHeader soapHeader = smsg.getSoapHeader();
    
                        try{
                            //To send header message
                            StringSource headerSource = new StringSource("<UserCredentials xmlns='URL'>\n" +
                                            "<userid>"+"ABCD"+"</userid>\n" +
                                            "<password>"+"ABCD"+"</password>\n" +
                                            "</UserCredentials>");
                            Transformer transformer = TransformerFactory.newInstance().newTransformer();
                            transformer.transform(headerSource, soapHeader.getResult());
    
                            smsg.setSoapAction(soapAction);
                        }catch(Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                    }; 
                   validateCardResponse = (FVValidateCardResponse) webServiceTemplate.marshalSendAndReceive(URL, validateCardRequest, actionCallBack);  
    
                } catch (Exception e) {
                    e.printStackTrace();
                }       
    }
    

    This is my configuration xml file:

    <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
            <property name="soapVersion">
                <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
            </property>
        </bean>
    
        <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <!-- If we want to use contextPath then we mush create ObjectFactory class in the described Package-->
            <!-- <property name="contextPath" value="com.waleteros.firstviewmodel" /> -->
    
            <property name="classesToBeBound">
                <list>
                    <value>com.waleteros.firstviewmodel.FVValidateCardRequest</value>
                    <value>com.waleteros.firstviewmodel.FVValidateCardResponse</value>               
                </list>
            </property>
        </bean>
    
        <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
            <constructor-arg ref="messageFactory" />
            <property name="marshaller" ref="marshaller"></property>
            <property name="unmarshaller" ref="marshaller"></property>
            <property name="messageSender">
                <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender"/>            
            </property>
            <!-- <property name="defaultUri" value="https://www.firstviewcorp.com/dbbapplications/ServicesSS/Selfservice.asmx?wsdl"/> -->
        </bean>
    

    Create pojo's according to your xmls Here is example

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "CardUpdateResponse",namespace="http://www.corecard.com/Prepaid")
    public class FVCardUpdateResponse {
    
        @XmlElement(name="CARDUPDATE_RET", namespace="http://www.corecard.com/Prepaid")
        private CARDUPDATE_RET response;
        //Getters and Setters   
    
        public static class CARDUPDATE_RET{
    
            @XmlElement(name = "ACCOUNTNUMBER", namespace="http://www.corecard.com/Prepaid")
            private String AccountNumber;
    
            @XmlElement(name = "ResCode", namespace="http://www.corecard.com/Prepaid")
            private String ResCode;
    
            @XmlElement(name = "ResErrorCode", namespace="http://www.corecard.com/Prepaid")
            private String ResErrorCode;
    
            @XmlElement(name = "ResErrorMsg", namespace="http://www.corecard.com/Prepaid")
            private String ResErrorMsg;
            //Getters and Setters
        }
    }