使用 Ksoap 发出复杂请求 Android

Making complex requests with Ksoap Android

我正在尝试使用嵌套对象数组发出请求,wsdl 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
  <SOAP-ENV:Body>
    <ns1:PopulateCart>
      <ns1:sc>
        <ns1:CustomerID>52</ns1:CustomerID>
        <ns1:Email>testing@gmail.com</ns1:Email>
        <ns1:Contact>0161234444</ns1:Contact>
        <ns1:RestaurantID>251</ns1:RestaurantID>
        <ns1:TimePickup>2015-03-21T23:59:00</ns1:TimePickup>
        <ns1:VoucherCode></ns1:VoucherCode>
        <ns1:FoodItems>
          <ns1:FoodMainItem>
            <ns1:product_id>20754</ns1:product_id>
            <ns1:qty>1</ns1:qty>
          </ns1:FoodMainItem>
        </ns1:FoodItems>
        <ns1:FoodItems>
          <ns1:FoodMainItem>
            <ns1:product_id>20754</ns1:product_id>
            <ns1:qty>2</ns1:qty>
          </ns1:FoodMainItem>
        </ns1:FoodItems>
      </ns1:sc>
    </ns1:PopulateCart>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我正在为 Android 使用 ksoap2 库,我尝试了:

    // ApiConstant.java
    public static final String NAMESPACE = "http://tempuri.org/";
    public static final String KSOAP_BASE_URL = "http://dedev.delivereat.my/Onappservice.asmx";

    //PopulateCartTask.java
    String METHOD_NAME = "PopulateCart";
    String SOAP_ACTION = ApiConstant.NAMESPACE + METHOD_NAME;
    String URL = ApiConstant.KSOAP_BASE_URL;

    SoapObject request = new SoapObject(ApiConstant.NAMESPACE, METHOD_NAME);
    SoapObject sc = new SoapObject(ApiConstant.NAMESPACE,"sc");

    //CHANGE2
    PropertyInfo pi = new PropertyInfo();
    pi.setName("CustomerID");
    pi.setValue(52); //1
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Email");
    pi.setValue("serene@greenroom.com.my"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Contact");
    pi.setValue("0161235555"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("RestaurantID");
    pi.setValue("251"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("Email");
    pi.setValue("serene@greenroom.com.my"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("TimePickup");
    pi.setValue("2015-03-21T23:59:00"); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("VoucherCode");
    pi.setValue(""); //2
    pi.setType(String.class);
    sc.addProperty(pi);

    SoapObject foodItems = new SoapObject(ApiConstant.NAMESPACE, "FoodItems");
    SoapObject FoodMainItem = new SoapObject(ApiConstant.NAMESPACE, "FoodMainItem");

    pi = new PropertyInfo();
    pi.setName("product_id");
    pi.setValue("20754"); //2
    pi.setType(String.class);
    FoodMainItem.addProperty(pi);

    pi = new PropertyInfo();
    pi.setName("qty");
    pi.setValue("1"); //2
    pi.setType(String.class);
    FoodMainItem.addProperty(pi);

    foodItems.addSoapObject(FoodMainItem);
    sc.addSoapObject(foodItems);
    request.addSoapObject(sc);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);

    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    androidHttpTransport.call(SOAP_ACTION, envelope);
    SoapObject response = (SoapObject) envelope.getResponse();

但我收到以下错误:

03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ SoapFault - faultcode: 'soap:Client' faultstring: 'Server was unable to read request. ---> There is an error in XML document (1, 294). ---> The specified type was not recognized: name='sc', namespace='http://tempuri.org/', at <sc xmlns='http://tempuri.org/'>.' faultactor: 'null' detail: org.kxml2.kdom.Node@28028932
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:147)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:140)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.Transport.parseResponse(Transport.java:118)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:275)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:118)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:113)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at com.deliver.eat.async.PopulateCartTask.doInBackground(PopulateCartTask.java:203)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at com.deliver.eat.async.PopulateCartTask.doInBackground(PopulateCartTask.java:20)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at android.os.AsyncTask.call(AsyncTask.java:288)
03-22 14:55:06.645    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-22 14:55:06.646    6282-6415/com.deliver.eat W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

我怀疑这与 SoapObject 名称空间有关,我检查了很多链接,并尝试了几种不同的方法,但没有一种方法有效:

问题:提出这个请求的正确方法是什么?

我被困了很长一段时间,非常感谢任何帮助!

我找不到关于如何使用 ksoap 库的答案,所以我最终使用 volley 库做了 POST 请求来实现相同的目的,在得到响应后,我手动解析了响应使用 xml 解析器。

所以这是我写的代码: https://gist.github.com/worker8/20eb5bd3400b88f10973

我如何使用这段代码:

PriceConfirmationTask.Callback callback = new PriceConfirmationTask.Callback(){
    @Override
    public void onResponse(PriceCheckResult result) {

    Log.d("ddw", "result: " + result.toString());

    if (result != null) {
        showPriceConfirmationDialog(result);
    } else {
        Toast.makeText(mActivity, "Sorry, something went wrong... ", Toast.LENGTH_LONG).show();
    }}};

PriceConfirmationTask task = new PriceConfirmationTask(mActivity, "2015-04-01T13:00:00", callback);
task.callEndpoint();

可能有更好的方法,但如果你像我一样被卡住了,这可能是一个很好的解决方案。

希望对您有所帮助!