[Android] 使用 Ksoap2 呼叫 Web Service

開發環境:Android Studio 0.8.6

搭配API:Ksoap2 3.3.0

首先將抓取到的 Ksoap2 放到 lib 資料夾中,接著開啟 Project Structure 將其加入到 Library dependency

設定完之後,打開 build.gradle 就可以看到 Android Studio 已經將其加入到 dependencies 中。

接下來我們簡單設計一下頁面:

activity_my.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    android:paddingBottom="@dimen/activity_vertical_margin"

    tools:context="william.home.javawsactivity2.MyActivity">

    <TextView

        android:id="@+id/text_View_01"

        android:text="@string/hello_world"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

</RelativeLayout>

接著寫code,建立我們所要使用的 WebService 類別:

package william.home.javawsactivity2;

import android.nfc.Tag;

import android.util.Log;

import org.ksoap2.SoapEnvelope;

import org.ksoap2.SoapFault;

import org.ksoap2.serialization.PropertyInfo;

import org.ksoap2.serialization.SoapObject;

import org.ksoap2.serialization.SoapPrimitive;

import org.ksoap2.serialization.SoapSerializationEnvelope;

import org.ksoap2.transport.HttpTransportSE;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

import java.net.HttpRetryException;

public class WebService {

        //Namespace of the Webservice - can be found in WSDL

        private static String NAMESPACE = "http://footballpool.dataaccess.eu";

        //Webservice URL - WSDL File location        

        private static String URL = "http://footballpool.dataaccess.eu/data/info.wso?WSDL";

        //SOAP Action URI again Namespace + Web method name

//        private static String SOAP_ACTION = "http://footballpool.dataaccess.eu/TopGoalScorers";

    private static String SOAP_ACTION_URL = "http://footballpool.dataaccess.eu/";

        

        public static String invokeHelloWorldWS(String paraName, String paraValue, String webMethName) {

                String resTxt = null;

                // Create request

                SoapObject request = new SoapObject(NAMESPACE, webMethName);

                // Property which holds input parameters

                PropertyInfo sayHelloPI = new PropertyInfo();

                // Set Name

                sayHelloPI.setName(paraName);

                // Set Value

                sayHelloPI.setValue(paraValue);

                // Set dataType

                sayHelloPI.setType(String.class);

                // Add the property to request object

                request.addProperty(sayHelloPI);

//        request.addProperty(paraName, paraValue);

                // Create envelope

                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(

                                SoapEnvelope.VER11);

//        envelope.dotNet = true;

                // Set output SOAP object

                envelope.setOutputSoapObject(request);

                // Create HTTP call object

                HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

        androidHttpTransport.debug = true;

                try {

            // Invoke web service

            androidHttpTransport.call(SOAP_ACTION_URL + webMethName, envelope);

        } catch (HttpRetryException e) {

            //Assign error message to resTxt

            resTxt = "Error occured";

            e.printStackTrace();

        } catch (IOException e) {

            //Assign error message to resTxt

            resTxt = "Error occured";

            e.printStackTrace();

        } catch (XmlPullParserException e) {

            //Assign error message to resTxt

            resTxt = "Error occured";

            e.printStackTrace();

        } catch (Exception e) {

            //Print error

            e.printStackTrace();

            //Assign error message to resTxt

            resTxt = "Error occured";

        }

//        SoapPrimitive response = null;

        SoapObject response = null;

        try {

            // Get the response

//            response = (SoapPrimitive) envelope.getResponse();

            response = (SoapObject) envelope.getResponse();

        } catch (SoapFault soapFault) {

            //Assign error message to resTxt

            resTxt = "Error occured";

            soapFault.printStackTrace();

        } catch (Exception e) {

            //Print error

            e.printStackTrace();

            //Assign error message to resTxt

            resTxt = "Error occured";

        }

        // Assign it to resTxt variable static variable

//                resTxt = response.toString();

        resTxt = response.getProperty(0).toString();

//        resTxt = response.getPropertyCount() + "";

        //下面開始是解析回傳的資料

        for (int i = 0; i < response.getPropertyCount() ; i++) {

            PropertyInfo pi = new PropertyInfo();

            response.getPropertyInfo(i,pi);

            Log.d("TAG-1-"+i , "namespace=" + pi.namespace + " name=" + pi.name + " flags=" +

                    pi.flags + " elementType=" + pi.elementType + " type=" + pi.type + " value=" +

                    pi.getValue());

            SoapObject result = (SoapObject)pi.getValue();

            for (int j = 0; j < result.getPropertyCount(); j++) {

                PropertyInfo pi2 = new PropertyInfo();

                result.getPropertyInfo(j,pi2);

                Log.d("TAG-2-"+j , "namespace=" + pi2.namespace + " name=" + pi2.name + " flags=" +

                        pi2.flags + " elementType=" + pi2.elementType + " type=" + pi2.type + " value=" +

                        pi2.getValue());

            }

        }

        /* result xml

                <tTopGoalScorer>

                <sName>Thomas Mueller</sName>

                <iGoals>5</iGoals>

                <sCountry>Y</sCountry>

                <sFlag>

                        http://footballpool.dataaccess.eu/images/flags/de.gif

                </sFlag>

                <sFlagLarge>

                        http://footballpool.dataaccess.eu/images/flags/de.png

                </sFlagLarge>

                </tTopGoalScorer>

                */

                //Return resTxt to calling object

                return resTxt;

        }

}

上面主要是設計好怎麼接資料,怎麼送資料的動作,而接資料回來之後要怎麼解析,要解析成什麼樣的格式,端看程式本身的需求。

接著來寫主要的 Activity:

主要有使用到Android 當中的 AsyncTask 來完成資料送出及資料接回的動作,當中有 doInBackground 及 onPostExecute 是比較重要的部份,見文知義,就知道是負責一些自動執行的動作,我們在 doInBackground 將我們要做的事情寫好,在 onPostExecute 在做 UI Thread 所要執行的動作。

package william.home.javawsactivity2;

import android.os.AsyncTask;

import android.support.v7.app.ActionBarActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.widget.TextView;

import org.json.JSONObject;

import org.ksoap2.serialization.SoapObject;

public class MyActivity extends ActionBarActivity {

    private TextView tv;

    private String response;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_my);

        tv = (TextView) findViewById(R.id.text_View_01);

        //建立非同步作業類別

        myAsyncTask mRequest = new myAsyncTask();

        //執行

        mRequest.execute();

    }

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

        @Override

        protected Void doInBackground(Void... voids) {

            //資料接回

            response = WebService.invokeHelloWorldWS("iTopN", "5", "TopGoalScorers");

            return null;

        }

        @Override

        protected void onPreExecute() {

            super.onPreExecute();

        }

        @Override

        protected void onPostExecute(Void aVoid) {

            super.onPostExecute(aVoid);

            //設定值

            tv.setText(response);

        }

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.

        getMenuInflater().inflate(R.menu.my, menu);

        return true;

    }

    @Override

    public boolean onOptionsItemSelected(MenuItem item) {

        // Handle action bar item clicks here. The action bar will

        // automatically handle clicks on the Home/Up button, so long

        // as you specify a parent activity in AndroidManifest.xml.

        int id = item.getItemId();

        if (id == R.id.action_settings) {

            return true;

        }

        return super.onOptionsItemSelected(item);

    }

}

其他的配置檔省略不談,若有需要可下載範例程式來參照。

本例子是連結到 http://footballpool.dataaccess.eu/data/info.wso 這個已經建立好的 Web Service 去取得資料,再將資料顯示到 TextView 中。

demo程式(右鍵另開視窗下載)

demo2程式(右鍵另開視窗下載)

本篇文件位置:

http://kuoshenghsu.blogspot.tw/2014/08/android-ksoap2-web-service.html

相關資源:

http://sweeteason.pixnet.net/blog/post/37349418-android---%E7%94%A8-ksoap2-%E5%91%BC%E5%8F%AB-web-service

http://seesharpgears.blogspot.tw/2010/11/basic-ksoap-android-tutorial.html

http://andygeeks.blogspot.tw/2014/04/parse-json-format-data-from-soap-web.html

http://andygeeks.blogspot.in/2014/02/how-to-get-data-from-soap-webservice.html

http://karanbalkar.com/2014/03/tutorial-78-using-ksoap2-in-android/