我在使用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>
如果有人已经遇到过这类问题并成功解决了问题,我会感激不尽。
答案 0 :(得分:1)
我可以给你提示解决问题。
使用soapUI工具创建具有相同WSDL的Web服务项目(非常简单快捷)。
将您的请求转储与soapUI生成的soap body进行比较。你会发现差异和
因此解决方案。
答案 1 :(得分:0)
@Rajnikant把它发现了。如果您的wcf Web服务无法正常工作,请使用SOAPui导入wsdl端点。这将为方法创建一个测试工具,然后您可以使用它来调用wcf方法并查看请求转储。将此与来自移动设备的请求转储(使用androidHttpTransport.requestDump)进行比较.....注意传递的参数及其命名空间....这非常重要