2017-03-29 12 views
2

나는 Android 장치에서 soap webservice를 호출해야합니다. stackoverflow 및 다른 페이지에서 비디오를 보는 많은 기사를 읽었습니다 ...하지만 난 everythin 시도하고 내 안드로이드 장치에서 작동하도록 만들 수 없습니다 및 에뮬레이터에서 테스트 할 수 없습니다. 내 컴퓨터가 그 중 어떤 것도 처리 할 수 ​​없기 때문에 오류가 코드에 있는지 또는 내 안드로이드 장치의 문제인지는 알 수 없습니다.android에서 soap webservice를 호출하십시오.

레이아웃 XML은 EditText, Button 및 TextView입니다. 당신은 내가 웹 서비스에 보낼 필요가 요청 XML을 볼 수있는 링크에서

(I는 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에서 작업을 관련된 UI를 수행 그래서 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

라이브러리를 사용하지 않고 비누 요청을 고려한 적이 있습니까? 저는 이전에 같은 문제가 있었으며, 특히 요청 구조를 변경하는 경우 라이브러리가 작업을 더욱 어렵게한다는 것을 발견하게되었습니다. 이것은 라이브러리를 사용하지 않고 비누 요청을하는 방법입니다. 먼저 Windows 애플리케이션 인 SOAP Ui를 사용하는 방법을 알아야합니다. 여기서 wsdl 파일을 가져올 수 있습니다. 구문이 정확하다면 웹 서비스에 대한 요청 본문이 표시된 화면이 나타납니다. 테스트 값을 입력하면 응답 구조가 생깁니다. 이 링크는 안드로이드 코드에 이제 비누 UI https://www.soapui.org/soap-and-wsdl/working-with-wsdls.html

을 사용하는 방법에 당신을 안내 할 것입니다 :

우리는 비동기 작업을 확장 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 파서. 추가 설명을 요청하십시오.