WebService是一種基於SOAP協議的遠程調用標準。通過WebService可以將不同作業系統平台,不同語言、不同技術整合到一起。在Android SDK中並沒有提供調用WebService的庫,因此,需要使用第三方類庫(KSOAP2)來調用WebService。在本文將介紹在Android中調用WebService的具體細節,並在最後給出一個完整的例子來示範如何使用KSOAP2來調用WebService。 安裝第三方類庫:KSOAP2 PC版本的WebService用戶端類庫非常豐富,例如,Axis2、CXF等,但這些類庫對於Android系統過於龐大,也未必很容易移植到Android系統上。因此,這些開發包並不在我們考慮的範圍內。適合手機的WebService用戶端類庫也有一些。本例使用了比較常用的KSOAP2。讀者可以從如下的地址下載Android版的KSOAP2。 http://code.google.com/p/ksoap2-android/downloads/list?can=1&q=&colspec=Filename+Summary+Uploaded+Size+DownloadCount
將下載後的jar檔案複製到Eclipse工程的lib目錄中(如果沒有該目錄,可以建立一個,當然,也可以放在其他的目錄中)。並在Eclipse工程中引用這個jar包,引用後的Eclipse工程目錄結構如圖1所示。 圖1 引用KSOAP2開發包 使用KSOAP2調用WebService 讀者可按如下6步來調用WebService的方法。 1. 指定WebService的命名空間和調用的方法名,代碼如下:
|
SoapObject request =new SoapObject("http://service","getName"); |
SoapObject類的第1個參數表示WebService的命名空間,可以從WSDL文檔中找到WebService的命名空間。第2個參數表示要調用的WebService方法名。 2. 設定調用方法的參數值,這一步是可選的,如果方法沒有參數,可以省略這一步。設定方法的參數值的代碼如下:
|
request.addProperty("param1","value1"); |
|
request.addProperty("param2","value2"); |
要注意的是,addProperty方法的第1個參數雖然表示調用方法的參數名,但該參數值並不一定與服務端的WebService類中的方法參數名一致,只要設定參數的順序一致即可。 3. 產生調用WebService方法的SOAP請求資訊。該資訊由SoapSerializationEnvelope對象描述,代碼如下:
|
SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(SoapEnvelope.VER11); |
|
envelope.bodyOut = request; |
建立SoapSerializationEnvelope對象時需要通過SoapSerializationEnvelope類的構造方法設定SOAP協議的版本號碼。該版本號碼需要根據服務端WebService的版本號碼設定。在建立SoapSerializationEnvelope對象後,不要忘了設定SoapSerializationEnvelope類的bodyOut屬性,該屬性的值就是在第1步建立的SoapObject對象。 4. 建立HttpTransportSE對象。通過HttpTransportSE類的構造方法可以指定WebService的WSDL文檔的URL,代碼如下:
|
newHttpTransportSE("http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl"); |
5. 使用call方法調用WebService方法,代碼如下:
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用戶端程式,代碼如下:
01 |
packagenet.blogjava.mobile.wsclient; |
03 |
importorg.ksoap2.SoapEnvelope; |
04 |
importorg.ksoap2.serialization.SoapObject; |
05 |
importorg.ksoap2.serialization.SoapSerializationEnvelope; |
06 |
importorg.ksoap2.transport.HttpTransportSE; |
07 |
importandroid.app.Activity; |
08 |
importandroid.os.Bundle; |
09 |
importandroid.view.View; |
10 |
importandroid.view.View.OnClickListener; |
11 |
importandroid.widget.Button; |
12 |
importandroid.widget.EditText; |
13 |
importandroid.widget.TextView; |
15 |
publicclass Main extendsActivity implements OnClickListener |
18 |
publicvoid onClick(View view) |
20 |
EditText etProductName = (EditText)findViewById(R.id.etProductName); |
21 |
TextView tvResult = (TextView)findViewById(R.id.tvResult); |
22 |
// WSDL文檔的URL,192.168.17.156為PC的ID地址 |
23 |
String serviceUrl ="http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl"; |
25 |
String methodName ="getProduct"; |
26 |
// 第1步:建立SoapObject對象,並指定WebService的命名空間和調用的方法名 |
27 |
SoapObject request =new SoapObject("http://service", methodName); |
28 |
// 第2步:設定WebService方法的參數 |
29 |
request.addProperty("productName", etProductName.getText().toString()); |
30 |
// 第3步:建立SoapSerializationEnvelope對象,並指定WebService的版本 |
31 |
SoapSerializationEnvelope envelope =new SoapSerializationEnvelope(SoapEnvelope.VER11); |
33 |
envelope.bodyOut = request; |
34 |
// 第4步:建立HttpTransportSE對象,並指定WSDL文檔的URL |
35 |
HttpTransportSE ht =new HttpTransportSE(serviceUrl); |