我正在使用ksoap2库连接到wcf Web服务。当我尝试发送原始类型时,服务器获取这些值并发送正确的响应。但是,如果我尝试发送一个复杂类型(一个KVMSerilizable子类型的对象),服务器将收到null。 下面是我要发送的对象的类定义。
import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class TwoIntegerWrapper implements KvmSerializable {
private int Num1;
private int Num2;
public TwoIntegerWrapper() {
super();
}
TwoIntegerWrapper(int number1, int number2) {
super();
this.Num1 = number1;
this.Num2 = number2;
}
public int getNumber1() {
return Num1;
}
public void setNumber1(int number1) {
this.Num1 = number1;
}
public int getNumber2() {
return Num2;
}
public void setNumber2(int number2) {
this.Num2 = number2;
}
public Object getProperty(int propertyNumber) {
Object property = null;
switch (propertyNumber) {
case 0:
property = this.Num1;
break;
case 1:
property = this.Num2;
break;
}
return property;
}
public int getPropertyCount() {
return 2;
}
public void getPropertyInfo(int propertyNumber, Hashtable arg1,
PropertyInfo propertyInfo) {
switch (propertyNumber) {
case 0:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "Num1";
break;
case 1:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "Num2";
break;
}
}
public void setProperty(int propertyNumber, Object data) {
switch (propertyNumber) {
case 0:
this.Num1 = Integer.parseInt(data.toString());
break;
case 1:
this.Num2 = Integer.parseInt(data.toString());
break;
}
}
}
以下是我称之为网络服务的方式。
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo property = new PropertyInfo();
TwoIntegerWrapper tiw = new TwoIntegerWrapper(num1Value, num2Value);
property.setName("TwoIntegerWrapper");
property.setType(tiw.getClass());
property.setValue(tiw);
request.addProperty(property);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, tiw.getClass().getSimpleName(), TwoIntegerWrapper.class);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try {
androidHttpTransport.call(Add_SOAP_ACTION, envelope);
Log.d(logtag + " request dump", androidHttpTransport.requestDump);
Log.d(logtag + " response dump", androidHttpTransport.responseDump);
SoapPrimitive sp = (SoapPrimitive) envelope.getResponse();
result = Integer.parseInt(sp.toString());
}
可能的原因是什么?
答案 0 :(得分:1)
这方面的一个常见问题是,假设您在线路上发送XML,则XML位于错误的命名空间中。在这种情况下,WCF解串器将决定它在XML中没有任何知道并返回null
答案 1 :(得分:0)
答案 2 :(得分:0)
你的实现kvmserializable的类是基于 xsd2 准确的。
但是, AddNumbers2,AddNumbers3 的方法(消息)具有第一个AN ELEMENT,它具有元素类型复杂类型,例如:
<xs:element name="AddNumbers2">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="obj" nillable="true" type="q1:TwoIntegerWrapper"/>
</xs:sequence>
</xs:complexType>
</xs:element>
所以你应该做的是:
property.setName("AddNumbers2");//not TwoIntegerWrapper, coz the main property is AddNumbers2
property.setType(tiw.getClass());
property.setValue(tiw);
request.addProperty(property);
答案 3 :(得分:0)
我通过更改 TwoIntegerWrapper 类的 getPropertyInfo 函数找到了解决方案。我还为这个类中的每个属性设置了名称空间。新的实施如下:
public void getPropertyInfo(int propertyNumber, Hashtable arg1,
PropertyInfo propertyInfo) {
switch (propertyNumber) {
case 0:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "Num1";
propertyInfo.setNamespace(TWO_INTEGER_WRAPPER_NAMESPACE);
break;
case 1:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "Num2";
propertyInfo.setNamespace(TWO_INTEGER_WRAPPER_NAMESPACE);
break;
}
}
即使我从信封中删除了映射,它也能正常工作。我不明白为什么会这样,但它确实有效。如果有人解释原因我很感激。 Wsdl文件,xsd0,xsd1和xsd2文件位于链接http://www.ceng.metu.edu.tr/~e1559897/
顺便说一句,我也改变了
property.setName("TwoIntegerWrapper");
到
property.setName("obj");