Android ksoap2可为null的类型



我正试图使用Ksoap2库从Android设备连接到WCF.Net Web服务。一切都很好,到目前为止,我已经能够发送和接收复杂的对象(经过大量的故障排除)。然而,我现在遇到了可为null的类型的问题。在服务器端,我将要发送的许多属性都可以为null。当我试图从Android端将这些作为null发送时,我会收到一个反序列化错误,因为ksoap将null设置为true,而不是nil=true。以下是一些来自测试驱动程序的工作SOAPXML,以及来自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"。

如有任何帮助,我们将不胜感激!

我遇到了同样的问题。在深入了解Ksoap2源代码之后,我发现了这个问题。您有两种可能的解决方案,第一种简单的解决方案是在SoapSerializationEnvelope中使用VER12。由于Ksoap2自VER12及以上版本以来仅使用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);
}}

如果你知道你的网络服务总是使用nil,你可以跳过这个检查,直接使用:

    @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);
}

Workaround方法使用参数skipNullProperties忽略此"<element type>",如下所示:

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.skipNullProperties=true;

解决了问题

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);
        }
    }
}

相关内容

最新更新