在Android 中使用KSOAP2呼叫WebService
WebService 是一種基於SOAP協議的遠端呼叫標準。通過WebService可以將不同作業系統平臺,不同語言、不同技術整合到一起。在Android SDK中並沒有提供呼叫WebService的庫,因此,需要使用第三方類庫(KSOAP2)來呼叫WebService。在本文將介紹在Android 中呼叫WebService的具體細節,並在最後給出一個完整的例子來演示如何使用KSOAP2來呼叫WebService。
安裝第三方類庫:KSOAP2 PC版本的WebService客戶端類庫非常豐富,例如,Axis2、CXF等,但這些類庫對於Android系統過於龐大,也未必很容易移植到 Android系統上。因此,這些開發包並不在我們考慮的範圍內。適合手機的WebService客戶端類庫也有一些。本例使用了比較常用的 KSOAP2。讀者可以從如下的地址下載Android版的KSOAP2。將下載後的jar檔案複製到Eclipse工程的lib目錄中(如果沒有該目錄,可以新建一個,當然,也可以放在其他的目錄中)。並在Eclipse工程中引用這個jar包,引用後的Eclipse工程目錄結構如圖1所示。 圖1 引用KSOAP2開發包
SoapObject request = new SoapObject("http://service", "getName");
SoapObject類的第1個引數表示WebService的名稱空間,可以從WSDL文件中找到WebService的名稱空間。第2個引數表示要呼叫的WebService方法名。
2. 設定呼叫方法的引數值,這一步是可選的,如果方法沒有引數,可以省略這一步。設定方法的引數值的程式碼如下:
要注意的是,addProperty方法的第1個引數雖然表示呼叫方法的引數名,但該引數值並不一定與服務端的WebService類中的方法引數名一致,只要設定引數的順序一致即可。 3. 生成呼叫WebService方法的SOAP請求資訊。該資訊由SoapSerializationEnvelope物件描述,程式碼如下:request.addProperty("param1", "value1"); request.addProperty("param2", "value2");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
建立SoapSerializationEnvelope物件時需要通過SoapSerializationEnvelope類的構造方法設定SOAP協 議的版本號。該版本號需要根據服務端WebService的版本號設定。在建立SoapSerializationEnvelope物件後,不要忘了設定 SoapSerializationEnvelope類的bodyOut屬性,該屬性的值就是在第1步建立的SoapObject物件。
4. 建立HttpTransportSE物件。通過HttpTransportSE類的構造方法可以指定WebService的WSDL文件的URL,程式碼如下:
5. 使用call方法呼叫WebService方法,程式碼如下:HttpTransportSE ht = new HttpTransportSE("http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl");
ht.call(null, envelope);
call方法的第1個引數一般為null,第2個引數就是在第3步建立的SoapSerializationEnvelope物件。
6. 使用getResponse方法獲得WebService方法的返回結果,程式碼如下:
SoapObject soapObject = (SoapObject) envelope.getResponse();
示例:通過WebService查詢產品資訊
本例涉及到一個WebService服務端程式和一個OPhone客戶端程式。讀者可直接將服務端程式(axis2目錄)複製到<Tomcat安裝目錄>\webapps目錄中,然後啟動Tomcat,並在瀏覽器位址列中輸入如下的URL:
http://localhost:8080/axis2
如果在瀏覽器中顯示如圖2所示的頁面,說明服務端程式已經安裝成功。
圖2 WebService主頁面
這個服務端WebService程式是SearchProductService,實際上SearchProductService是一個Java類,只 是利用Axis2將其對映成WebService。在該類中有一個getProduct方法。這個方法有一個String型別的引數,表示產品名稱。該方 法返回一個Product物件,該物件有3個屬性:name、price和productNumber。讀者可以使用如下的URL來檢視 SearchProductService的WSDL文件。
http://localhost:8080/axis2/services/SearchProductService?wsdl
顯示WSDL文件的頁面如圖3所示。
圖3 WSDL文件
在圖3中的黑框中就是WebService的名稱空間,也是SoapObject類的構造方法的第1個引數值。這個WebService程式可以直接使用如下的URL進行測試。
http://localhost:8080/axis2/services/SearchProductService/getProduct?param0=iphone
測試的結果如圖4所示。
圖4 測試getProduct方法
從圖4所示的測試結果可以看出,Axis2將getProduct方法返回的Product物件直接轉換成了XML文件(實際上是SOAP格式)返回。
下面我們來根據前面介紹的使用KSOAP2的步驟來編寫呼叫WebService的OPhone客戶端程式,程式碼如下:
package net.blogjava.mobile.wsclient;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity implements OnClickListener
{
@Override
public void onClick(View view)
{
EditText etProductName = (EditText)findViewById(R.id.etProductName);
TextView tvResult = (TextView)findViewById(R.id.tvResult);
// WSDL文件的URL,192.168.17.156為PC的ID地址
String serviceUrl = "http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl";
// 定義呼叫的WebService方法名
String methodName = "getProduct";
// 第1步:建立SoapObject物件,並指定WebService的名稱空間和呼叫的方法名
SoapObject request = new SoapObject("http://service", methodName);
// 第2步:設定WebService方法的引數
request.addProperty("productName", etProductName.getText().toString());
// 第3步:建立SoapSerializationEnvelope物件,並指定WebService的版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
// 設定bodyOut屬性
envelope.bodyOut = request;
// 第4步:建立HttpTransportSE物件,並指定WSDL文件的URL
HttpTransportSE ht = new HttpTransportSE(serviceUrl);
try
{
// 第5步:呼叫WebService
ht.call(null, envelope);
if (envelope.getResponse() != null)
{
// 第6步:使用getResponse方法獲得WebService方法的返回結果
SoapObject soapObject = (SoapObject) envelope.getResponse();
// 通過getProperty方法獲得Product物件的屬性值
String result = "產品名稱:" + soapObject.getProperty("name") + "\n";
result += "產品數量:" + soapObject.getProperty("productNumber") + "\n";
result += "產品價格:" + soapObject.getProperty("price");
tvResult.setText(result);
}
else {
tvResult.setText("無此產品.");
}
}
catch (Exception e)
{
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnSearch = (Button) findViewById(R.id.btnSearch);
btnSearch.setOnClickListener(this);
}
}
在編寫上面程式碼時應注意如下兩點:
- 在 第2步中addProperty方法的第1個引數值是productName,該值雖然是getProduct方法的引數名,但addProperty方 法的第1個引數值並不限於productName,讀者可以將這個引數設為其他的任何字串(但該值必須在XML中是合法的,例如,不是設為 “<”、“>”等XML預留的字串)。
- 通過SoapObject類的getProperty方法可以獲得Product物件的屬性值,這些屬性名就是圖4所示的測試結果中的屬性名。
package net.blogjava.mobile.wsclient;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity implements OnClickListener
{
private EditText etProductName;
private TextView tvResult;
class WSAsyncTask extends AsyncTask
{
String result = "";
@Override
protected Object doInBackground(Object... params)
{
try
{
String serviceUrl = "http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl";
String methodName = "getProduct";
SoapObject request = new SoapObject("http://service",
methodName);
request.addProperty("productName", etProductName.getText().toString());
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.bodyOut = request;
HttpTransportSE ht = new HttpTransportSE(serviceUrl);
ht.call(null, envelope);
if (envelope.getResponse() != null)
{
SoapObject soapObject = (SoapObject) envelope.getResponse();
result = "產品名稱:" + soapObject.getProperty("name") + "\n";
result += "產品數量:" + soapObject.getProperty("productNumber")
+ "\n";
result += "產品價格:" + soapObject.getProperty("price");
}
else
{
result = "無此產品.";
}
}
catch (Exception e)
{
result = "呼叫WebService錯誤.";
}
// 必須使用post方法更新UI元件
tvResult.post(new Runnable()
{
@Override
public void run()
{
tvResult.setText(result);
}
});
return null;
}
}
@Override
public void onClick(View view)
{
// 非同步執行呼叫WebService的任務
new WSAsyncTask().execute();
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnSearch = (Button) findViewById(R.id.btnSearch);
btnSearch.setOnClickListener(this);
etProductName = (EditText) findViewById(R.id.etProductName);
tvResult = (TextView) findViewById(R.id.tvResult);
}
}
呼叫WebService的核心程式碼與示例中的程式碼完全一樣,在這裡就不再做具體的介紹了。但在編寫上面的程式碼時還需要注意如下幾點。
1. 一般需要編寫一個AsyncTask的子類來完成後臺執行任務的工作。
2. AsyncTask的核心方法是doInBackground,當呼叫AsyncTask類的execute方法時,doInBackground方法會非同步執行。因此,可以將執行任務的程式碼寫在doInBackground方法中。
3. 由 於本例中的TextView元件是在主執行緒(UI執行緒)中建立的,因此,在其他的執行緒(doInBackground方法所在的執行緒)中不能直接更新 TextVew元件。為了更新TextView元件,需要使用TextView類的post方法。該方法的引數是一個Runnable物件,需要將更新 TextView元件的程式碼寫在Runnable介面的run方法中。
4. 雖然不能在其他執行緒中更新UI元件,但可以從其他執行緒直接讀取UI元件的值。例如,在doInBackground方法中直接讀取了EditText元件的值。
5. 呼叫AsyncTask類的execute方法後會立即返回。execute方法的引數就是doInBackground方法的引數。doInBackground方法的返回值可以通過AsyncTask.execute(...).get()方法獲得。
讀者可以將本例中的IP改成其他的值,看看單擊按鈕後,是否還可在文字框中輸入其他的內容。如果這個IP是正確的,並且WebService可訪問,那麼會在TextView元件中輸出相應的返回值。
總結
本文主要介紹瞭如何使用KSOAP2來呼叫WebService。KSOAP2是第三方開發的專門用於在移動裝置呼叫WebService的類庫。使用 KSOAP2呼叫WebService可分為6步來完成,其中主要使用了SoapObject物件來指定了要呼叫的方法,然後通過 HttpTransportSE物件的call方法來呼叫WebService的方法,最後通過getResponse方法返回結果。讀者可以通過本文提 供的完整示例來體會使用KSOAP2呼叫WebService的完整過程。在最後還介紹瞭如何通過非同步呼叫WebService的方式來防止因服務端故障
或其他原因導致的UI元件阻塞。
相關推薦
在Android 中使用KSOAP2呼叫WebService
WebService 是一種基於SOAP協議的遠端呼叫標準。通過WebService可以將不同作業系統平臺,不同語言、不同技術整合到一起。在Android SDK中並沒有提供呼叫WebService的庫,因此,需要使用第三方類庫(KSOAP2)來呼叫WebServic
android ksoap2 呼叫WebService和WCF服務的區別
如何區分服務是webservice服務和wcf服務 webservice服務網址是以.asmx結尾的,例子:http://ip地址/Interface/MapService.asmx?wsdl wcf服務是以.svc結尾的,例子:http://ip地址/ydyzt/ReadXml
Android 呼叫KSOAP2 呼叫 webservice 報錯:意外的元素,
我用java jax-ws做的webservice,然後用java 通過wsimport生成的client程式碼呼叫webservice正常,但是用android呼叫webservice時,能夠正常返回值,只是傳遞的引數(一個String),伺服器返回的值,顯示接受的st
ksoap2呼叫webservice
使用ksoap2呼叫遠端webservice,程式碼如下: import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; impo
Android中Java呼叫c++裡面的方法,如何檢視錯誤
向我們如果在Java中呼叫C++裡面的方法,有的時候發現並不執行,也不知道問題卡住哪裡,這個時候在Androidstudio下面會有這樣的一片紅: ,這個時候就可以通過doc命令列檢視在C++哪一行報錯,: 前面的exe是自己本地NDK目錄下的路徑, -C
Android中JNI呼叫過程簡述
1.安裝和下載cygwin,下載Android NDK; 2.在ndk專案中JNI介面的設計; 3.使用C/C++實現本地方法; 4.JNI生成動態連結庫.so檔案; 5.將動態連結庫複製到java工程,在Java工程中呼叫,執行Java工程即可。
Android 中aidl呼叫執行執行緒和同步非同步問題
1,bind服務回撥執行所線上程 客戶端呼叫bindService(intent, mConn, Context.BIND_AUTO_CREATE); ServiceConnection回撥中獲取伺服器端的介面(實現了Binder的類)onService
Android中Java呼叫C/C++
① Javah配置,Tool settings填寫的三項在不同平臺是相同的,無需改動。 ② 安裝NDK ,下載安裝包並安裝。 ③ 在AS中配置NDK路徑 ④ Make project
android中webview呼叫撥號盤
webview.setWebViewClient(new WebViewClient(){ public boolean shouldOverrideUrlLoading(WebView view,String url){
delphi 中如何呼叫webservice返回dataset 資料集
We're nearly there. Drop a TClientDataset, a TXMLTransformProvider and a TDatasource on the form. Here's what the form looks like now:Link
Android使用Ksoap2呼叫Web service傳遞自定義物件,List,大檔案
JavaBean,List 呼叫 1、匯入Gson.jar包 2、呼叫 new Gson().toJson(obj); new Gson().toJson(list); 將JavaBean或list轉
android使用ksoap2解析webservice的值為anyType{}格式的解決辦法
遇到的問題,soapObject打印出來的值:GetGongdanResponse{GetGongdanResult=anyType{results=anyType{details=anyType{id=c252cd5d-8e1f-466f-9b1c-95d8ec
關於 ksoap2呼叫 webservice 遇到的一些問題
拿到了 webservice 介面呼叫 不算完整的文件 當用 ksoap2 寫好程式碼 ,去呼叫 webservice 遇到 伺服器返回 500 的錯誤碼 解決方案: 可能是 ksoap2的 jar包有問題, 換一個試試(雖然原來用的這個j
在Android 中使用KSOAP2調用WebService(轉)
arch 輸出 移植 發包 runnable round csdn service服務 語言 WebService 是一種基於SOAP協議的遠程調用標準。通過WebService可以將不同操作系統平臺,不同語言、不同技術整合到一起。在Android SDK中並沒有提供調
Android通過ksoap2這個框架呼叫webservice大講堂
昨天有人問我An
關於android中webservice使用ksoap2傳遞複雜物件的研究
android開發中需要與伺服器互動,其中就要用到webservice,google提供了ksoap的外掛,網上很多關於使用字串引數沒有問題,但是如果使用像date,decimal,以及自定義的類物件就不行了,這還要分為兩種情況: 1.date等引數需要new Ma
呼叫webservice 中出現的問題
寫完webservice當然要呼叫,但是以前呼叫的都是我們的架構封裝好的方法,我自己也沒有看過,換了一家公司以後,自己又寫了一個介面,這時候隊友跪了,該如何呼叫呢?網上找了許多東西,但真正能用的東西不多,好多沒用的東西還可能會誤導大家,現在寫一下我們自己的構成,可能和你的有很多的不一樣,然後即使不同
android jni開發中c++ 呼叫java 方法
最近幾天搞fbreader 電子書的二次開發,其中需要 c++ 呼叫 java方法解密電子書,所以l老虎吃天,硬著頭皮看c++程式碼。 具體的思路如下,其實也就這幾步: 1. jni 中用到 java反射的方法
Android中呼叫攝像頭拍照儲存,並在相簿中選擇圖片顯示
我的配置是: android手機版本是7.0 android studio是3.1 android平臺是9.0 我的測試都是在真機上進行的。 首先來看程式碼: package com.example.sunshunli.cameraalbumtest; import a
(轉)Android訪問webservice 糾正網上亂傳的android呼叫Webservice方法。
糾正網上亂傳的android呼叫Webservice方法。 1.寫作背景: 筆者想實現android呼叫webservice,可是網上全是不管對與錯亂轉載的文章,結果不但不能解決問題,只會讓人心煩,所以筆者決定將自己整理好的能用的android呼叫webserv