使用SOAP

时间:2015-06-20 08:31:59

标签: android asp.net vb.net web-services soap

我想将一个字符串数组返回给我的Android客户端并填充ListView。 我正在使用SOAP库(org.ksoap2。*)来调用ASP.NET Web服务。

以下是网络服务的代码:

1。 ASP Web服务

    Imports ...
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports ...

    <WebService(Namespace:="...")>_
    <WebService(ConformsTo:=...)> _
    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

    Public Class EnquiryWS
        Inherits System.Web.Services.WebService

    ' Web method
           <WebMethod()> _
           Public Function GetList() As String()
                  'Hardcoded list
                  Return New String() { "item1", "item2", "item3" }
           End Function

我通过访问asmx测试了Web服务,没有运行时错误。 我还用一个简单的字符串测试了它,Web服务将字符串返回给Android。像这样:

    ' Web method
    <WebMethod()> _
    Public Function GetString() As String
           Return "My string."
    End Function

2。 Android活动

其次,这是我的Android代码,它调用ASP.NET Web服务。

    import org.ksoap2.SoapEnvelope;
    import org.ksoap2.serialization.SoapObject;
    import org.ksoap2.serialization.SoapPrimitive;
    import org.ksoap2.serialization.SoapSerializationEnvelope;
    import org.ksoap2.transport.HttpTransportSE;

    public class MainActivity extends AppCompatActivity {

           private ArrayList<String> list;
           private ListView listview;
           private ArrayAdapter<String> adapter;

           @Override
           protected void onCreate(Bundle savedInstanceState) {
                     //...
                     new GetPersonList().execute("AsyncTask String");
                     //...
           }

           // Inner AsyncTask class
           private class GetPersonList extends AsyncTask<String,  Integer,String> {
                   private static final String SOAP_ACTION = "https://myNamespace/GetList";
                   private static final String METHOD_NAME = "GetList";
                   private static final String NAMESPACE = "https://myNamespace/";
                   private static final String URL =
            "https://myIISsite/myASMXfile.asmx";

                   @Override
                   protected void onPreExecute() {
                             super.onPreExecute();
                             // onPreExecute stuff
                   }

                   @Override
                   protected String doInBackground(String... arg) {
                             String result = null;

                             SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

                             //Create envelope
                             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

                             //Required for .net
                             envelope.dotNet = true;

                             //Set output SOAP object
                             envelope.setOutputSoapObject(request);

                             //Create HTTP call object
                             HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                             try {
                                  //Invoke web service
                                  androidHttpTransport.call(SOAP_ACTION, envelope);

                                  //Get the response
                                  SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
                                  //Assign it to response to a static variable
                                  result = response.toString();
                             } catch (Exception e) {
                                  result = "error " + e.getMessage();
                             }

                             return result;
                   }

                   @Override
                   protected void onPostExecute(String result) {
                             System.out.println("Returned SOAP XML: " + result);
                             MyFunction(result);
                   }
           }
    }

MyFunction是我创建的一种方法,可以做一些额外的工作。

第3。 MyFunction的

这是MyFunction方法代码:

    public void MyFunction(String s) {
           // Add Webservice response to list
           list.add(s);

           // Set adapter
           adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item1, list);
           listview.setAdapter(adapter);

    }

我传递给MyFunction的参数是SOAP响应,然后我将它添加到列表并设置适配器。

好的,所以web服务返回一个字符串数组,但 overriden onPostExecute方法正在使用一个字符串,如果我将onPostExecute参数声明为Collection,它显然不会覆盖

这是我在logcat中遇到的错误:

    Return SOAP XML: error expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <html>@1:7 in java.io.InputStreamReader@4182d238)

有人可以建议吗?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。我将响应转换为SoapObject而不是SoapPrimitive,原因是因为SoapPrimitive用于原始数据类型,SoapObject支持复合数据类型。因此,我将我的数组转换为SoapObject而不再是SoapPrimitive。

我已经删除了MyFunction()方法,因为我通过覆盖run()在onPostExecute()方法中设置适配器。最后,我添加了一个ProgressDialog,我正在处理onPreExecute()方法中显示ProgressDialog,然后我在onPostExecute()方法中调用dismiss()。

    private class GetPersonList extends AsyncTask<Void, Void, String> {

    private static final String SOAP_ACTION = "http://myNamespace/myMethod";
    private static final String METHOD_NAME = "myMethod";
    private static final String NAMESPACE = "http://myNamespace/";
    private static final String URL =
            "http://myURL/myAsmxFile.asmx";

    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog= ProgressDialog.show(MainActivity.this,
                "Wait",
                "Retrieving data",
                true
        );
    }

    @Override
    protected String doInBackground(Void... params) {
        String finalResult = null;

        //Create request object
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

        //Create envelope to which we add our request object
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);

        //Required for .net
        envelope.dotNet = true;

        //Add the request object to the envelope
        envelope.setOutputSoapObject(request);

        //Create HTTP call object
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        try {
            //Invoke web service
            androidHttpTransport.call(SOAP_ACTION, envelope);

            // Get the response
            // Cast as SoapObject and not SoapPrimitive
            SoapObject response = (SoapObject) envelope.getResponse();

            //Assign it to response to a static variable
            finalResult = response.toString();

            // Now loop through the response (loop through the properties)
            // and add them to the list
            for(int i = 0; i < response.getPropertyCount(); i++) {
                list.add(response.getProperty(i).toString());
            }

        } catch (Exception e) {
            System.out.println("######## ERROR " + e.getMessage());
        }

        return finalResult;
    }

    @Override
    protected void onPostExecute(String str) {
        progressDialog.dismiss();
        System.out.println("Returned SOAP XML: " + str);

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Set adapter
                adapter = new ArrayAdapter<String>(MainActivity.this, R.layout.list_item, R.id.product_name, list);

                listview.setAdapter(adapter);
            }
        });
    }
}

我听说有另外一种方法可以使用Gson / Json这样做,我会在发现之后发布。

Cheerz