Spring Web服务解组没有正确发生

时间:2014-11-21 13:15:29

标签: spring web-services jaxb unmarshalling spring-ws

我一直在尝试集成spring WS来测试SOAP webservice.Integration遇到了障碍,因为我无法在unmarshelled对象中收到正确的响应。 以下是详细信息:

应用程序上下文如下:

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

下面是调用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();
}

GetFSChildrenResponse类如下:

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

}

类FSChild如下:

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

}

我觉得非常接近让它发挥作用.. 请求被正确编组,甚至请求被正确发送到webservice,webservice记录响应并正确返回。 但是当试图提取如下的响应时:

GetFSChildrenResponse response = (GetFSChildrenResponse) webServiceTemplate.marshalSendAndReceive( getFSChildren);

现在,在我调试时,我发现响应对象已填充,它包含1个getHSChildrenReturn列表,其中包含一个预期的项目,但fschild中的代码和描述设置为null。

我甚至为消息打开了TRACE日志。我看到响应xml正确返回数据,如下所示:

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

请在下面找到生成类的wsdl:

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

1 个答案:

答案 0 :(得分:2)

在数小时沮丧之后回答我自己的问题。在wsdl中,名字命名空间似乎有问题。我在wsdl中的2things后发生了变化,并再次生成了类,从而产生了正确的响应。 xmlns:tns1="http://fs.uk.com"xmlns:tns1="http://service.fs.uk.com"

targetNamespace="http://fs.uk.com"targetNamespace="http://service.fs.uk.com" 对于元素FSChild。 这对我来说有点令人惊讶,因为没有更改的原始wsdl与SOAPUI完美配合。如果有人能够解释这一点,我将奖励他赏金