I have been trying to integrate the spring WS to test a SOAP webservice.Integration has hit a roadblock as I am not able receive the proper response in the unmarshelled object. Below are the details:
Application Context is below:
<!-- Define the SOAP version used by the WSDL -->
<bean id="soapMessageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
</property>
</bean>
<!-- The location of the generated Java files -->
<oxm:jaxb2-marshaller id="marshaller" contextPath="com.uk.fs.generatedsources"/>
<!-- Configure Spring Web Services -->
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="soapMessageFactory"/>
<property name="marshaller" ref="marshaller"/>
<property name="unmarshaller" ref="marshaller"/>
<property name="defaultUri" value="http://192.168.243.21/test/services/testservice?wsdl"/>
</bean>
Below is the method which invokes marshalSendAndReceive:
public List<FSChild> getFSChildren() {
GetFSChildren getFSChildren= new ObjectFactory().createGetFSChildren();
getFSChildren.setCountry("CA");
getFSChildren.setFsCode("5010");
getFSChildren.setLimit(6);
GetFSChildrenResponse response = (GetFSChildrenResponse) webServiceTemplate.marshalSendAndReceive(
getFSChildren);
return response.getGetFSChildrenReturn();
}
Class GetFSChildrenResponse is as below:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"getHSChildrenReturn"
})
@XmlRootElement(name = "getFSChildrenResponse")
public class GetFSChildrenResponse {
@XmlElement(required = true)
protected List<FSChild> getFSChildrenReturn;
public List<FSChild> getGetFSChildrenReturn() {
if (getFSChildrenReturn == null) {
getFSChildrenReturn = new ArrayList<FSChild>();
}
return this.getFSChildrenReturn;
}
}
class FSChild is as below:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FSChild", namespace = "http://hs.uk.com", propOrder = {
"description",
"fsCode"
})
public class FSChild {
@XmlElement(required = true, nillable = true)
protected String description;
@XmlElement(required = true, nillable = true)
protected String fsCode;
public String getDescription() {
return description;
}
public void setDescription(String value) {
this.description = value;
}
public String getFsCode() {
return hsCode;
}
public void setFsCode(String value) {
this.hsCode = value;
}
}
I feel like quite close to get it working.. Request is properly marshalled and even request is sent properly to webservice which logs the response and returns it properly. but when try to extract the response like below:
GetFSChildrenResponse response = (GetFSChildrenResponse) webServiceTemplate.marshalSendAndReceive( getFSChildren);
now at this point when I debug,I find that response object is populated and it contains 1 getHSChildrenReturn
list containing one item which was expected but code and description in fschild is set to null.
I have even turned on TRACE logs for messages.I see response xml properly returning data which is as below:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getHSChildrenResponse xmlns="http://service.hs.pb.com">
<getHSChildrenReturn>
<description>Silk: Silk-worm cocoons suitable for reeling.</description>
<fsCode>5001000000</hsCode>
</getFSChildrenReturn>
</getFSChildrenResponse>
</soapenv:Body>
</soapenv:Envelope>
Please find below the wsdl from which classes were generated:
<wsdl:definitions xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://service.fs.uk.com" xmlns:intf="http://service.fs.uk.com" xmlns:tns1="http://fs.uk.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.fs.uk.com">
<!--
WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)
-->
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://service.fs.uk.com">
<import namespace="http://fs.uk.com"/>
<element name="getCountries">
<complexType/>
</element>
<element name="getCountriesResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getCountriesReturn" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="getFSChildren">
<complexType>
<sequence>
<element name="fsCode" type="xsd:string"/>
<element name="country" type="xsd:string"/>
<element name="limit" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="getFSChildrenResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getFSChildrenReturn" type="tns1:FSChild"/>
</sequence>
</complexType>
</element>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://fs.uk.com">
<complexType name="FSChild">
<sequence>
<element name="description" nillable="true" type="xsd:string"/>
<element name="fsCode" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="getCountriesResponse">
<wsdl:part element="impl:getCountriesResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getCountriesRequest">
<wsdl:part element="impl:getCountries" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getFSChildrenRequest">
<wsdl:part element="impl:getFSChildren" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:message name="getFSChildrenResponse">
<wsdl:part element="impl:getFSChildrenResponse" name="parameters"></wsdl:part>
</wsdl:message>
<wsdl:portType name="FSService">
<wsdl:operation name="getCountries">
<wsdl:input message="impl:getCountriesRequest" name="getCountriesRequest"></wsdl:input>
<wsdl:output message="impl:getCountriesResponse" name="getCountriesResponse"></wsdl:output>
</wsdl:operation>
<wsdl:operation name="getFSChildren">
<wsdl:input message="impl:getFSChildrenRequest" name="getFSChildrenRequest"></wsdl:input>
<wsdl:output message="impl:getFSChildrenResponse" name="getFSChildrenResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="FSServiceSoapBinding" type="impl:FSService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getCountries">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getCountriesRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCountriesResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getFSChildren">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getFSChildrenRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getFSChildrenResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="testserviceService">
<wsdl:port binding="impl:FSServiceSoapBinding" name="testservice">
<wsdlsoap:address location="http://192.168.240.87/FSWS/testservice/FSService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Answering my own question after getting frustrated for hours.There seems to be problem with the namespaces in wsdl.I changed following 2things in wsdl and generated the classes again resulting in proper responses.
xmlns:tns1="http://fs.uk.com"
toxmlns:tns1="http://service.fs.uk.com"
targetNamespace="http://fs.uk.com"
totargetNamespace="http://service.fs.uk.com"
for element FSChild. It was little surprising for me as original wsdl without changes works perfectly with SOAPUI. If anyone can explain this,I will award him the bounty