我正在尝试使用Ksoap2库从Android设备连接到WCF .Net Web服务。一切正常,到目前为止,我已经能够发送和接收复杂的对象(经过大量的故障排除后)。但是,我现在遇到了可空类型的问题。在服务器端,我将发送的许多属性都可以为空。当我尝试从Android端发送这些为空时,我得到反序列化错误,因为ksoap put null = true而不是nil = true。以下是来自测试驱动程序的一些有效的SOAP XML以及来自Android客户端的当前XML。
工作测试驱动程序XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<AddNullables xmlns="http://TJIsGhey/Tester">
<NumbersToAdd xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Input1>7</Input1>
<Input2 i:nil="true" />
</NumbersToAdd>
</AddNullables>
</s:Body>
</s:Envelope>
Android客户端XML
<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>
<AddNullables xmlns="http://TJIsGhey/Tester" id="o0" c:root="1">
<NumbersToAdd i:type="n0:NullablesIn" xmlns:n0="http://TJIsGhey/Tester">
<Input1 i:type="d:int">6</Input1>
<Input2 i:null="true" />
</NumbersToAdd>
</AddNullables>
</v:Body>
</v:Envelope>
以下是我收到的错误消息:
反序列化Tester.NullablesIn类型的对象时出错。值''无法解析为'Int32'类型。
非常感谢任何帮助!
答案 0 :(得分:2)
我有同样的问题。 我在Ksoap2源代码中钻取后发现了这个问题。 第一个有2个可能的解决方案,在SoapSerializationEnvelope上使用VER12很容易。 因为自从VER12及以后Ksoap2仅使用nil属性。 但是,您可能会受到此更改的影响,因此您有另一种选择: 继承SoapSerializationEnvelope并覆盖此类的writeProperty方法。 如此:
public class ExtendedSoapSerializationEnvelope extends
SoapSerializationEnvelope {
public ExtendedSoapSerializationEnvelope(int version) {
super(version);
}
@Override
protected void writeProperty(XmlSerializer writer, Object obj,
PropertyInfo type) throws IOException {
if (obj == null) {
if (!(obj instanceof SoapObject)) {
// assuming object implements KvmSerializable or other type of
// Serialization interface
writer.attribute(xsi, version >= VER11 ? "nil" : "null", "true");
} else {
// assuming SoapObject being used with VER12 and up
writer.attribute(xsi, version >= VER12 ? "nil" : "null", "true");
}
return;
}
super.writeProperty(writer, obj, type);
}}
如果您知道您的webService始终使用nil,则可以跳过此检查altogther并使用:
@Override
protected void writeProperty(XmlSerializer writer, Object obj,
PropertyInfo type) throws IOException {
if (obj == null) {
writer.attribute(xsi, "nil", "true");
return;
}
super.writeProperty(writer, obj, type);
}
答案 1 :(得分:1)
解决方法方法使用参数"<element type>"
忽略此skipNullProperties
,如下所示:
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.skipNullProperties=true;
答案 2 :(得分:0)
问题解决了
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpsTransportSE;
import java.net.URISyntaxException;
public class MainActivity extends AppCompatActivity {
private static final String URL = "https://services.rs.ge/WayBillService/WayBillService.asmx?WSDL";
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
String[] params = new String[]{"save_waybill","s22:12345678910","123456"};
new MyAsyncTasc().execute(params);
setContentView(tv);
}
class MyAsyncTasc extends AsyncTask<String,Void,String> {
@Override
protected String doInBackground(String... params) {
String SOAP_ACTION="http://tempuri.org/"+params[0];
int timeOut = 60000;
SoapSerializationEnvelope __envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
SoapObject request = new SoapObject("http://tempuri.org/", params[0]);
__envelope.dotNet = true;
__envelope.setOutputSoapObject(request);
request.addProperty("su", params[1]);
request.addProperty("sp", params[2]);
//------------------ SoapObject
SoapObject waybill1 = new SoapObject("", "WAYBILL");
SoapObject goods1 = new SoapObject("", "GOODS");
SoapObject good_list1 = new SoapObject("", "GOODS_LIST");
waybill1.addProperty("SELER_UN_ID", 1149251);
waybill1.addProperty("ID", 0);
waybill1.addProperty("TYPE", 1);
waybill1.addProperty("STATUS", 1);
waybill1.addProperty("START_ADDRESS", "START_ADDRESS");
waybill1.addProperty("END_ADDRESS", "END_ADDRESS");
waybill1.addProperty("DRIVER_TIN", "61007004242");
waybill1.addProperty("CAR_NUMBER", "AAA000");
waybill1.addProperty("CHEK_DRIVER_TIN", 1);
waybill1.addProperty("TRANSPORT_COAST", 0);
waybill1.addProperty("TRAN_COST_PAYER", 2);
waybill1.addProperty("TRANS_ID", 1);
goods1.addProperty("ID", 0);
goods1.addProperty("W_NAME", "W_NAME");
goods1.addProperty("UNIT_ID", 1);
goods1.addProperty("QUANTITY", 2);
goods1.addProperty("PRICE", 1);
goods1.addProperty("AMOUNT", 2);
goods1.addProperty("BAR_CODE", "1");
good_list1.addProperty("GOODS", goods1);
goods1 = new SoapObject("", "GOODS");
goods1.addProperty("ID", 0);
goods1.addProperty("W_NAME", "W_NAME2");
goods1.addProperty("UNIT_ID", 1);
goods1.addProperty("QUANTITY", 4);
goods1.addProperty("PRICE", 1);
goods1.addProperty("AMOUNT",4);
goods1.addProperty("BAR_CODE", "2");
good_list1.addProperty("GOODS", goods1);
waybill1.addProperty("GOODS_LIST", good_list1);
SoapObject wib_send = new SoapObject("", "waybill");
wib_send.addProperty("WAYBILL", waybill1);
request.addProperty("waybill", wib_send);
java.net.URI uri = null;
try {
uri = new java.net.URI(URL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
int port=uri.getPort()>0?uri.getPort():443;
HttpsTransportSE httpTransport= new HttpsTransportSE(uri.getHost(), port, uri.getPath(), timeOut);
httpTransport.debug = true;
try {
httpTransport.call(SOAP_ACTION, __envelope);
SoapObject resultRequestSOAP = (SoapObject) __envelope.bodyIn;
return resultRequestSOAP.toString();
} catch(Exception exp){
return "Error";
}
}
@Override
protected void onPostExecute(final String result) {
tv.setText(result);
}
}
}
&#13;