2017-03-29 212 views
2

我需要在android設備中調用肥皂web服務。我一直在閱讀大量的文章在stackoverflow和其他網頁上,看視頻......但我已經嘗試過所有的東西,我不能讓它在我的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

回答

0

你可以做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

你能發送代碼嗎?我無法寫出沒有錯誤 –

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

} 

我改變了它,現在是這樣的...但它總是打印,有沒有答案

0

您是否考慮過在不使用庫的情況下製作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解析器來獲得所需的值。 請隨時要求進一步澄清。