【问题标题】:Call a soap webservice in android [duplicate]在android中调用soap webservice [重复]
【发布时间】:2017-08-22 15:24:48
【问题描述】:

我需要在安卓设备中调用一个肥皂网络服务。我一直在阅读stackoverflow和其他页面上的很多文章,观看视频......但我已经尝试了一切,但我无法让它在我的android设备上工作,我无法在模拟器上进行测试,因为我的电脑无法处理其中任何一个,所以我不知道错误是在代码上还是我的android设备的问题。

布局xml只有一个EditText、一个Button和一个TextView。

在此链接中,您可以看到我需要发送到 Web 服务的请求 xml(我应该使用 SOAP 1.1 还是 SOAP 1.2?) http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry

这是我的实际代码,我尝试了许多其他方法,但没有一个对我有用。有什么帮助吗? (url、namespace、soap_action 和 method_name 的值都不错,不是吗?)

package com.example.doazdoas.webservice_prueba;


    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;

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

    import android.os.AsyncTask;
    import android.widget.Toast;

    import static android.content.ContentValues.TAG;

   public class MainActivity extends Activity{
    private TextView textResult;
    private Button buttonSend;

    String NAMESPACE = "http://www.webserviceX.NET/";
    String METHOD_NAME = "GetCitiesByCountry";
    String SOAP_ACTION = NAMESPACE + METHOD_NAME;
    String URL = "http://www.webservicex.net/globalweather.asmx?WSDL";

    private Object resultsRequestSOAP = null;

    HttpTransportSE androidHttpTransport;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textResult = (TextView)findViewById(R.id.textResultado);
        buttonSend = (Button)findViewById(R.id.buttonEnviar);
        //setContentView(tv);
    }

    public void onClickEnviar(View view){
        AsyncCallWS task = new AsyncCallWS();
        task.execute();
    }

    private class AsyncCallWS extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            Log.i(TAG, "onPreExecute");
        }

        @Override
        protected Void doInBackground(Void... params) {
            Log.i(TAG, "doInBackground");
            sendRequest();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            Log.i(TAG, "onPostExecute");
            Log.d("dump Request: " ,androidHttpTransport.requestDump);
            Log.d("dump response: " ,androidHttpTransport.responseDump);
        }

    }


    public void sendRequest(){
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);


        //SoapObject
        request.addProperty("@CountryName", "SPAIN");
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.setOutputSoapObject(request);


        androidHttpTransport = new HttpTransportSE(URL);
        try
        {
            androidHttpTransport.call(SOAP_ACTION, envelope);
            resultsRequestSOAP =  envelope.getResponse();
            String[] results = (String[])  resultsRequestSOAP;
            textResult.setText( results[0]);
        }
        catch (Exception aE)
        {
            aE.printStackTrace ();
        }
    }
}

【问题讨论】:

  • 尝试去掉NAMESPACE末尾的'/',并更改SOAP_ACTION = NAMESPACE + "/" + METHOD_NAME;

标签: java android xml web-services android-ksoap2


【解决方案1】:

你可以在doInBackGround做任何UI相关的操作,所以把它们移到onPostExecute方法中。

因为doInBackGround 不是 UI 线程。请仔细阅读 AsyncTask 文档。无论您从doInBackGround 返回的数据是什么,它都将被用作onPostExecute 的输入。

所以改变你的代码如下,

    private class AsyncCallWS extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        Log.i(TAG, "onPreExecute");
    }

    @Override
    protected String[] doInBackground(Void... params) {
        Log.i(TAG, "doInBackground");
        String[] data = sendRequest();
        return data;
    }

    @Override
    protected void onPostExecute(String[] result) {
        Log.i(TAG, "onPostExecute");
        if(result != null && result.length > 0){
             textResult.setText( results[0]);
        }
    }

}


private String[] sendRequest(){
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);


    //SoapObject
    request.addProperty("@CountryName", "SPAIN");
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.setOutputSoapObject(request);


    androidHttpTransport = new HttpTransportSE(URL);
    try
    {
        androidHttpTransport.call(SOAP_ACTION, envelope);
        resultsRequestSOAP =  envelope.getResponse();
        String[] results = (String[])  resultsRequestSOAP;
    }
    catch (Exception aE)
    {
        aE.printStackTrace ();
    }
}

【讨论】:

  • 告诉我doInBackground()方法不能返回String[]类型数据
  • 然后生成ArrayList并从doInBackGround返回ArrayList。
【解决方案2】:

您是否考虑过在不使用库的情况下发出肥皂请求?我之前也遇到过同样的问题,这让我发现库会让你的工作更加努力,尤其是在更改请求结构时。这是您在不使用库的情况下发出肥皂请求的方式: 首先,您需要知道如何使用 SOAP Ui,它是一个 Windows 应用程序。您可以在此处导入您的 wsdl 文件,如果我们的语法正确,那么您将看到一个屏幕,显示您的 Web 服务的请求正文。您可以输入测试值,您将获得一个响应结构。此链接将指导您如何使用soap ui https://www.soapui.org/soap-and-wsdl/working-with-wsdls.html

现在进入 android 代码:

我们将创建一个名为 runTask 的类,它扩展异步任务并使用 http 发送请求正文并获取请求响应:

 private class runTask extends AsyncTask<String, String, String> {

        private String response;
        String string = "your string parameter"
        String SOAP_ACTION = "your soap action here";

        String stringUrl = "http://your_url_here";
        //if you experience a problem with url remove the '?wsdl' ending



        @Override
        protected String doInBackground(String... params) {

            try {

                        //paste your request structure here as the String body(copy it exactly as it is in soap ui)
                        //assuming that this is your request body


                String body = "<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">" +
                                "<soap:Body>"+
                                "<GetCitiesByCountryResponse xmlns="http://www.webserviceX.NET">"+
                                "<GetCitiesByCountryResult>"+string+"</GetCitiesByCountryResult>"+
                                "</GetCitiesByCountryResponse>"+
                                "</soap:Body>"+
                                "</soap:Envelope>";


                try {
                    URL url = new URL(stringUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("POST");
                    conn.setDoOutput(true);
                    conn.setDefaultUseCaches(false);
                    conn.setRequestProperty("Accept", "text/xml");
                    conn.setRequestProperty("SOAPAction", SOAP_ACTION);

                    //push the request to the server address

                    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
                    wr.write(body);
                    wr.flush();

                    //get the server response

                    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    StringBuilder builder = new StringBuilder();
                    String line = null;

                    while ((line = reader.readLine()) != null) {


                        builder.append(line);
                        response = builder.toString();//this is the response, parse it in onPostExecute

                    }


                } catch (Exception e) {

                    e.printStackTrace();
                } finally {

                    try {

                        reader.close();
                    } catch (Exception e) {

                        e.printStackTrace();
                    }
                }


            } catch (Exception e) {

                e.printStackTrace();
            }

            return response;
        }

        /**
         * @see AsyncTask#onPostExecute(Object)
         */
        @Override
        protected void onPostExecute(String result) {



           try {

              Toast.makeText(this,"Response "+ result,Toast.LENGTH_LONG).show();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

现在只需执行该类并观看魔术发生:

runTask runner = new runTask();
runner.execute();

您可以使用 DOM 或 SAX 解析器解析响应以获取所需的值。 随时要求进一步澄清。

【讨论】:

    猜你喜欢
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    相关资源
    最近更新 更多