Java Webservice将null对象返回到.net客户端

时间:2010-07-01 12:31:26

标签: java .net web-services

任何人都能弄明白我的问题是......

我正在从.Net客户端调用Java Webservice(Axis 1.4)的web方法。该方法返回一个Map对象,如果我从Axis客户端调用它可以正常工作,但在我的c#代码中它总是为null。

这是WSDL:

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:http.service.enlaces.portlet.ext.com" xmlns:intf="urn:http.service.enlaces.portlet.ext.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://model.enlaces.portlet.ext.com" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:http.service.enlaces.portlet.ext.com">

<wsdl:types>

<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.apache.org/xml-soap">
<import namespace="urn:http.service.enlaces.portlet.ext.com"/>
<import namespace="http://model.enlaces.portlet.ext.com"/>
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="mapItem">
   <sequence>
 <element name="key" nillable="true" type="xsd:anyType"/>
 <element name="value" nillable="true" type="xsd:anyType"/>
   </sequence>
</complexType>
<complexType name="Map">
   <sequence>
   <element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
   </sequence>
</complexType>   
</schema>
 </wsdl:types>

<wsdl:message name="getFoldersAndBookmarksRequest" />
<wsdl:message name="getFoldersAndBookmarksResponse">
    <wsdl:part name="getFoldersAndBookmarksReturn" type="apachesoap:Map" />
</wsdl:message>

<wsdl:portType name="BookmarksEntryServiceSoap">
<wsdl:operation name="getFoldersAndBookmarks">
      <wsdl:input name="getFoldersAndBookmarksRequest"  message="intf:getFoldersAndBookmarksRequest" />
      <wsdl:output name="getFoldersAndBookmarksResponse" message="intf:getFoldersAndBookmarksResponse" />
    </wsdl:operation>
  </wsdl:portType>

<wsdl:binding name="Portlet_Bookmarks_BookmarksEntryServiceSoapBinding" type="intf:BookmarksEntryServiceSoap">
    <wsdlsoap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />
  <wsdl:operation name="getFoldersAndBookmarks">
      <wsdlsoap:operation soapAction="" />
      <wsdl:input name="getFoldersAndBookmarksRequest">
        <wsdlsoap:body use="encoded" namespace="urn:http.service.enlaces.portlet.ext.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </wsdl:input>
      <wsdl:output name="getFoldersAndBookmarksResponse">
        <wsdlsoap:body use="encoded" namespace="urn:http.service.enlaces.portlet.ext.com" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

和我的c#自动生成的代码:

[System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:http.service.enlaces.portlet.ext.com", ResponseNamespace="urn:http.service.enlaces.portlet.ext.com")]
[return: System.Xml.Serialization.SoapElementAttribute("getFoldersAndBookmarksReturn")]
public Map getFoldersAndBookmarks() {
    object[] results = this.Invoke("getFoldersAndBookmarks", new object[0]);
    return ((Map)(results[0]));
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace="http://xml.apache.org/xml-soap")]
public partial class Map {

    private mapItem[] itemField;

    /// <comentarios/>
    public mapItem[] item {
        get {
            return this.itemField;
        }
        set {
            this.itemField = value;
        }
    }
}

我,不幸地到处都看到了,我找不到解决办法。 拜托,有人知道吗?

5 个答案:

答案 0 :(得分:1)

所以帮助你很晚,但我最近遇到了同样的问题。

首先,我使用Eclipse创建Web服务。对我来说问题是生成的wsdd使用的是&#39; document / literal(包装)&#39;样式。将其更改为“RPC&#39;解决了这个问题。没有更多的空白。

因此,如果您将编码更改为RPC,也可能会解决您的问题。

答案 1 :(得分:0)

这就是为什么从代码生成的Web服务几乎从不可互操作的原因:)

解决这个问题的一个好方法是首先制作wsdl,并定义一个很好的清晰的XSD,它应该很好地映射到.Net和java。如果您对服务器有任何控制权,那么另一种选择就是服务器的轴1.4(yech,痛苦)以外的其他选择。

最后,尝试按摩java代码中的签名,尝试用MapItem []替换List,反之亦然,确保在返回对象或参数中没有Map。

再次检查生成的wsdl,我想这可能是因为mapItem的键/值部分的xsd:anyType。

我认为如果你在参数中有一个java对象,那就是由轴生成的。相信我,你不要那样。使它成为一个字符串,或一个复杂的类型,或一个整数,但一个对象只能暗示开放式结束的xml(xsd:anyType),而不是很多客户端没有如何解析它。

答案 2 :(得分:0)

我前一段时间遇到过同样的问题。当您尝试通过带有.net客户端的轴Web服务获取元素数组时会发生这种情况。

问题是“ name = item ”这一行的一部分:

<element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>

尝试将该特定行“item”更改为“mapItem”。尝试其中之一:

<element maxOccurs="unbounded" minOccurs="0" name="mapItem" type="apachesoap:mapItem"/>

<element maxOccurs="unbounded" minOccurs="0" name="key" type="apachesoap:mapItem"/>

<element maxOccurs="unbounded" minOccurs="0" name="value" type="apachesoap:mapItem"/>

答案 3 :(得分:0)

我遇到了这个问题,我不得不改变WSDL文件:

<wsdlsoap:body use="encoded" ... 

<wsdlsoap:body use="literal" ... 

仅执行代理生成。

答案 4 :(得分:0)

我遇到了同样的问题。我的解决方案是在自动生成的函数中删除命名空间。 这是我的功能:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://www.service-now.com/incident/getRecords", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlArrayAttribute("getRecordsResponse", Namespace = "")]
[return: System.Xml.Serialization.XmlArrayItemAttribute("getRecordsResult", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
public getRecordsResponseGetRecordsResult[] getRecords([System.Xml.Serialization.XmlElementAttribute("getRecords", Namespace = "http://www.service-now.com/incident")] getRecords getRecords1)
{
    object[] results = this.Invoke("getRecords", new object[] {
                getRecords1});
    return ((getRecordsResponseGetRecordsResult[])(results[0]));
}

我在此行中删除了命名空间。因为当我通过SoapUI测试Web服务时,我意识到响应对象没有命名空间。但是自动生成的代码具有命名空间。

[return: System.Xml.Serialization.XmlArrayAttribute("getRecordsResponse", Namespace = "")]

SoapUI响应如下:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <SOAP-ENV:Body>
      <getRecordsResponse>
         <getRecordsResult>
            <active>0</active>
         </getRecordsResult>
      </getRecordsResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>