How to consume third party WSDL services in Spring

2020-04-15 14:35发布

问题:

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>

回答1:

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
    }
}