在android中调用soap web服务

问题描述:

我需要在android设备中调用肥皂web服务。我一直在阅读大量的文章在*和其他网页上,看视频......但我已经尝试过所有的东西,我不能让它在我的android设备上工作,我不能在模拟器上测试,因为我的电脑无法处理它们中的任何一个,所以我不知道错误是在代码上还是它是我的Android设备的问题。在android中调用soap web服务

布局xml只是一个EditText,一个Button和一个TextView。

在这个环节你可以看到请求XML我需要发送到web服务(我应该使用SOAP 1.1或SOAP 1.2?) http://www.webservicex.net/globalweather.asmx?op=GetCitiesByCountry

这是我实际的代码,我试过很多其他方法,而且他们都没有为我工作。任何帮助? (URL,命名空间,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(); 
     } 
    } 
} 
+0

尝试在'NAMESPACE'结尾删除'/',并更改'SOAP_ACTION = NAMESPACE +“/”+ METHOD_NAME;' – DaveNOTDavid

你可以做doInBackGround相关操作任何用户界面,所以在onPostExecute methnod移动它们。

因为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(); 
    } 
} 
+0

它告诉我doInBackground()方法不能返回String []键入数据 –

+0

然后生成ArrayList并从doInBackGround返回ArrayList。 – Rohit

+0

你能发送代码吗?我无法写出没有错误 –

私有类AsyncCallWS扩展的AsyncTask {

private String[] data; 
    @Override 
    protected void onPreExecute() { 
     Log.i(TAG, "onPreExecute"); 
    } 

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

    @Override 
    protected void onPostExecute(String[] result) { 
     Log.i(TAG, "onPostExecute"); 
     if(result != null && result.length > 0){ 
      Log.d("dump Request: " ,androidHttpTransport.requestDump); 
      Log.d("dump response: " ,androidHttpTransport.responseDump); 
      textResult.setText(result[0]); 
     }else{ 
      Log.d("Error","There's no answer"); 
     } 
    } 

} 

我改变了它,现在是这样的...但它总是打印,有没有答案

您是否考虑过在不使用库的情况下制作soap请求?我早些时候遇到了同样的问题,这让我发现图书馆会让你的工作变得更加困难,特别是在改变请求结构时。这就是您如何在不使用库的情况下发出肥皂请求: 首先,您需要知道如何使用SOAP Ui这是一个Windows应用程序。你可以在这里导入你的wsdl文件,如果它的语法正确,那么你会得到一个屏幕显示你的web服务的请求正文。你可以输入测试值,你会得到一个响应结构。此链接将指导您如何现在就用肥皂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解析器来获得所需的值。 请随时要求进一步澄清。