使用kso​​ap2将一组复杂对象发送到.NET Web服务

时间:2010-09-02 07:34:00

标签: .net web-services java-me ksoap2

我在使用KSOAP到.net Web服务(Soap服务)从J2ME客户端发送复杂对象数组时遇到问题。

我的TestSoap.java文件有一个setArr()方法,该方法接受PropHeaderMapBin对象的数组并将其发送到返回整数的Web服务(PropHeaderMapBin对象的数量)

TestSoap.java

package org.tempuri;

    import com.n9ciphers.test.Constants;
    import java.util.Vector;
    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.PropertyInfo;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransport;
    import org.tempuri.PropHeaderMapBin;

    public final class TestSoap {

        public int setArr(PropHeaderMapBin[] inArr) throws Exception {

            SoapObject _client = new SoapObject("http://tempuri.org/", "SetArr");
            SoapObject[] _propHeaderMapBinSO = new SoapObject[inArr.length];

            PropHeaderMapBin[] prop = inArr;
            //PropHeaderMapBin[] prop = new PropHeaderMapBin[inArr.length];
            Vector _propVector = new Vector(inArr.length);
            if (inArr != null) {

                //System.out.println("_len  " + inArr.length );

                for (int i = 0; i < inArr.length; i++) {
                    _propHeaderMapBinSO[i] = new SoapObject("http://tempuri.org/", "PropHeaderMapBin");
                    _propHeaderMapBinSO[i].addProperty("PropertyName", prop[i].getPropertyName());
                    _propHeaderMapBinSO[i].addProperty("value", prop[i].getValue());
                    _propHeaderMapBinSO[i].addProperty("HeaderText", prop[i].getHeaderText());
                    _propHeaderMapBinSO[i].addProperty("label", prop[i].getLabel());

                    _propVector.addElement(_propHeaderMapBinSO[i]);
                }
            }

            _client.addProperty(pi, _propVector);

            SoapSerializationEnvelope _envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            _envelope.addMapping("http://www.tempuri.org/", "PropHeaderMapBin", new PropHeaderMapBin().getClass());
            //_envelope.addTemplate (_client);
            _envelope.bodyOut = _client;
            _envelope.dotNet = true;

            HttpTransport _ht = new HttpTransport(Constants.endPoint + "Test.asmx");
            _ht.debug = true;
            _ht.call("http://tempuri.org/SetArr", _envelope);

            //System.out.println("response: " + result.toString());

            System.out.println("Request Dump:" + _ht.requestDump);
            //Dialog.show("Request Dump", _ht.requestDump, Dialog.TYPE_INFO, null, "OK", null);
            System.out.println("Response Dump:" + _ht.responseDump);
            //Dialog.show("Response Dump", _ht.responseDump, Dialog.TYPE_INFO, null, "OK", null);

            return Integer.parseInt(_envelope.getResponse().toString());
            //return 0;
        }
    }

输出setArr()方法调用。服务器无法识别数组中对象的数据类型,它将arraytype设置为anytype [3]并返回0而不是3.

Request Dump:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
    <v:Header />
    <v:Body>
        <SetArr xmlns="http://tempuri.org/" id="o0" c:root="1">
            <inArr i:type="c:Array" c:arrayType="d:anyType[3]">
                <item i:type="n0:PropHeaderMapBin" xmlns:n0="http://tempuri.org/">
                    <PropertyName i:type="d:string">1</PropertyName>
                    <value i:type="d:string">1</value>
                    <HeaderText i:type="d:string">Pradhan</HeaderText>
                    <label i:type="d:string">Pradhan</label>
                </item>
                <item i:type="n1:PropHeaderMapBin" xmlns:n1="http://tempuri.org/">
                    <PropertyName i:type="d:string">2</PropertyName>
                    <value i:type="d:string">2</value>
                    <HeaderText i:type="d:string">Kavya</HeaderText>
                    <label i:type="d:string">Kavya</label>
                </item>
                <item i:type="n2:PropHeaderMapBin" xmlns:n2="http://tempuri.org/">
                    <PropertyName i:type="d:string">3</PropertyName>
                    <value i:type="d:string">3</value>
                    <HeaderText i:type="d:string">Puchi</HeaderText>
                    <label i:type="d:string">Puchi</label>
                </item>
            </inArr>
        </SetArr>
    </v:Body>
</v:Envelope>


Response Dump:<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <SetArrResponse xmlns="http://tempuri.org/">
            <SetArrResult>0</SetArrResult>
        </SetArrResponse>
    </soap:Body>
</soap:Envelope>
response = 0

我的wsdl文件供参考

<wsdl:definitions targetNamespace="http://tempuri.org/">
    <wsdl:types>
        <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
            <s:element name="GetArr">
                <s:complexType/>
            </s:element>
            <s:element name="GetArrResponse">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="0" maxOccurs="1" name="GetArrResult" type="tns:ArrayOfPropHeaderMapBin"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
            <s:complexType name="ArrayOfPropHeaderMapBin">
                <s:sequence>
                    <s:element minOccurs="0" maxOccurs="unbounded" name="PropHeaderMapBin" nillable="true" type="tns:PropHeaderMapBin"/>
                </s:sequence>
            </s:complexType>
            <s:complexType name="PropHeaderMapBin">
                <s:sequence>
                    <s:element minOccurs="0" maxOccurs="1" name="PropertyName" type="s:string"/>
                    <s:element minOccurs="0" maxOccurs="1" name="value" type="s:string"/>
                    <s:element minOccurs="0" maxOccurs="1" name="HeaderText" type="s:string"/>
                    <s:element minOccurs="0" maxOccurs="1" name="label" type="s:string"/>
                </s:sequence>
            </s:complexType>
            <s:element name="SetArr">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="0" maxOccurs="1" name="inArr" type="tns:ArrayOfPropHeaderMapBin"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
            <s:element name="SetArrResponse">
                <s:complexType>
                    <s:sequence>
                        <s:element minOccurs="1" maxOccurs="1" name="SetArrResult" type="s:int"/>
                    </s:sequence>
                </s:complexType>
            </s:element>
        </s:schema>
    </wsdl:types>
    <wsdl:message name="GetArrSoapIn">
        <wsdl:part name="parameters" element="tns:GetArr"/>
    </wsdl:message>
    <wsdl:message name="GetArrSoapOut">
        <wsdl:part name="parameters" element="tns:GetArrResponse"/>
    </wsdl:message>
    <wsdl:message name="SetArrSoapIn">
        <wsdl:part name="parameters" element="tns:SetArr"/>
    </wsdl:message>
    <wsdl:message name="SetArrSoapOut">
        <wsdl:part name="parameters" element="tns:SetArrResponse"/>
    </wsdl:message>
    <wsdl:portType name="TestSoap">
        <wsdl:operation name="GetArr">
            <wsdl:input message="tns:GetArrSoapIn"/>
            <wsdl:output message="tns:GetArrSoapOut"/>
        </wsdl:operation>
        <wsdl:operation name="SetArr">
            <wsdl:input message="tns:SetArrSoapIn"/>
            <wsdl:output message="tns:SetArrSoapOut"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="TestSoap" type="tns:TestSoap">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="HelloWorld">
            <soap:operation soapAction="http://tempuri.org/HelloWorld" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="GetArr">
            <soap:operation soapAction="http://tempuri.org/GetArr" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="SetArr">
            <soap:operation soapAction="http://tempuri.org/SetArr" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:binding name="TestSoap12" type="tns:TestSoap">
        <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="GetArr">
            <soap12:operation soapAction="http://tempuri.org/GetArr" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="SetArr">
            <soap12:operation soapAction="http://tempuri.org/SetArr" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="Test">
        <wsdl:port name="TestSoap" binding="tns:TestSoap">
            <soap:address location="http://xxx.xxx.xxx.xxx/Services/Test.asmx"/>
        </wsdl:port>
        <wsdl:port name="TestSoap12" binding="tns:TestSoap12">
            <soap12:address location="http://xxx.xxx.xxx.xxx/Services/Test.asmx"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

如果有人已经遇到过这类问题并成功解决了问题,我会感激不尽。

2 个答案:

答案 0 :(得分:1)

我可以给你提示解决问题。

使用soapUI工具创建具有相同WSDL的Web服务项目(非常简单快捷)。

将您的请求转储与soapUI生成的soap body进行比较。你会发现差异和

因此解决方案。

答案 1 :(得分:0)

@Rajnikant把它发现了。如果您的wcf Web服务无法正常工作,请使用SOAPui导入wsdl端点。这将为方法创建一个测试工具,然后您可以使用它来调用wcf方法并查看请求转储。将此与来自移动设备的请求转储(使用androidHttpTransport.requestDump)进行比较.....注意传递的参数及其命名空间....这非常重要