Webservice 是一種基於Soap協議的遠程調用標準,通過webservice可以將不同操作系統平臺,不同語言,不同技術整合到一起.
在PC機java客戶端,需要用一些庫來訪問webservice,可以用Ksoap第三方
的類庫來獲取服務器端webService的調用.
首先
下載Ksoap包:ksoap2-android-assembly-3.0.0-RC.4-jar-with-dependencies.jar
下載鏈接:
http://ksoap2-android.googlecode.com/svn/m2-repo/com/google/code/ksoap2-android/ksoap2-android-assembly/3.0.0/ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar
新建android項目,把該包複製到該工程的src->lib目錄下.並更改工程的編譯路徑:右鍵選中工程->Properties->Java Build Path->Libraries->Add External JARs.把該包加入編譯路徑中.
七步調用WebService方法:
1 指定webService的命名空間,請求WDSL文檔的URL,調用方法名
//命名空間
private static final String targetNameSpace="http://WebXml.com.cn/";
//請求WSDL文檔的URL
private static final String WSDL=
"http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";
//方法名
private static final String getSupportCity="getSupportCity";
private static final String getWeatherbyCityName="getWeatherbyCityName";
2 實例化SoapObject對象,如果方法有參數,傳入參數值
//實例化
SoapObject soapObject=new SoapObject(targetNameSpace, getWeatherbyCityName);
//傳入參數soapObject.addProperty(參數名, 參數值);
soapObject.addProperty("theCityName", city);
/************建議webservice的方法傳遞的參數儘量用string類型。即使是int類型,kSOAP2與Java編寫的webservice也有可能交互發生異常.**************/
3 設置SOAP請求信息,把構造好的soapObject封裝進去,設置好屬性後,再發出請求(參數部分爲SOAP協議版本號,與webservice版本號一致)
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=soapObject;
envelope.dotNet=true;
envelope.setOutputSoapObject(soapObject);
/*
* 注意:這個屬性是對dotnetwebservice協議的支持,
* 如果dotnet的webservice 不指定rpc方式則用true否則要用false
*/
/*****************
常量SoapEnvelope.VER10:對應於SOAP1.0規範
常量SoapEnvelope.VER11:對應於SOAP1.1規範
常量SoapEnvelope.VER12:對應於SOAP1.2規範
***********************/
/**********************
在kSOAP中,我們用Base64把二進制流編碼爲ASCII字符串,這樣就可以通過XML/SOAP傳輸二進制數據了。
org.ksoap2.serialization.MarshalBase64的目的就是,把SOAP XML中的xsd:based64Binary元素序列化爲Java字節數組(byete array)類型。類似的,kSOAP2還提供了MarshalDate、MarshalHashtable類來把相應的元素序列化爲Java的Date、Hashtable類型。
(該步可省 據需要決定) (new MarshalBase64()).register(envelope); //註冊envelope
*********************/
4 構建傳輸對象,開啓調試信息
HttpTransportSE httpTranstation=new HttpTransportSE(WSDL);
httpTranstation.debug=true;
/*********如果HttpTransport的debug屬性爲true,那麼此時就可以通過System.out.println("Response dump>>+ tx.responseDump);打印出HttpTransport的調試信息。尤其當前面call方法和getResult方法發生異常時,這個調試信息是非常有用的。************/
/***************
對於HttpTransport的處理上,kSOAP2和kSOAP1.2的寫法不一樣。
kSOAP 1.2,HttpTransport的構造函數是HttpTransport (String url, String soapAction),第二個參數soapAction可以是要調用的webservice方法名。
kSOAP 2,構造函數是 HttpTransport(String url)。kSOAP2相當於把webservice方法名分離出去,完全交給SoapObject去封裝,而HttpTransport僅僅負責把SoapEnvelope發送出去並接收響應,這樣更合理一些。
***************/
5 調用WebService(其中參數爲1:命名空間+方法名稱,2:Envelope對象):
httpTranstation.call(targetNameSpace+getWeatherbyCityName, envelope);
/*************方法HttpTransport.call()自己就能夠發送請求給服務器、接收服務器響應並序列化SOAP消息,如下所示:
ht.call(soapAction, envelope);
soapAction – SOAP 規範定義了一個名爲 SOAPAction 的新 HTTP 標頭,所有 SOAP HTTP 請求(即使是空的)都必須包含該標頭。
soapAction標頭旨在表明該消息的意圖。通常可以置此參數爲null,這樣HttpTransport就會設置HTTP標頭SOAPAction爲空字符串。
Envelope – 就是前面我們構造好的SoapSerializationEnvelope或SoapEnvelope對象。
*************/
SoapObject result=(SoapObject)envelope.getResponse();
//打印出調試錯誤信息System.out.println("Responsedump>>"+ tx.responseDump);
/********
由於HttpTransport類實際上是調用了HttpConnection作網絡連接,所以必須另起一個線程來專門做kSOAP工作,否則會堵塞操作。
********/
7 對result進行提取和處理便於顯示.
示例>天氣預報獲取城市天氣情況和圖標
public class WebServiceUtil {
//命名空間
private static final String targetNameSpace="http://WebXml.com.cn/";
//請求WSDL文檔的URL
private static final String WSDL=
"http://webservice.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl";
//方法名
private static final String getSupportCity="getSupportCity";
private static final String getWeatherbyCityName="getWeatherbyCityName";
/***************************
* 根據城市信息獲取天氣預報信息
* @param city
* @return
***************************/
public WeatherBean getWeatherByCity(String city){
WeatherBean bean=new WeatherBean();
//實例化SoapObject對象,如果方法有參數,傳入參數值
SoapObject soapObject=new SoapObject(
targetNameSpace, getWeatherbyCityName);
soapObject.addProperty("theCityName", city);
SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut=soapObject;
/*
* 注意:這個屬性是對dotnetwebservice協議的支持,
* 如果dotnet的webservice 不指定rpc方式則用true否則要用false
envelope.dotNet=true;
envelope.setOutputSoapObject(soapObject);
*/
HttpTransportSE httpTranstation=new HttpTransportSE(WSDL);
httpTranstation.debug=true;
try{
httpTranstation.call(
targetNameSpace+getWeatherbyCityName, envelope);
SoapObject result=(SoapObject)envelope.getResponse();
//對getWeatherbyCityName返回的XML文件進行解析,提取三天天氣情況給bean
bean=parserWeather(result);
}catch (IOException e){
e.printStackTrace();
}catch (XmlPullParserException e){
e.printStackTrace();
}
return bean;
}
/**
* 解析返回的結果(從soapObject對今天\明天\後天三天的天氣情況的獲取)
* @param soapObject
*/
protected WeatherBean parserWeather(SoapObject soapObject){
WeatherBean bean=new WeatherBean();
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
Map<String,Object>map=new HashMap<String,Object>();
// 城市名---xml文件第二個參數
bean.setCityName(soapObject.getProperty(1).toString());
//城市情況 ---位於最後一個參數
bean.setCityDescription(soapObject.getProperty(soapObject.getPropertyCount()-1).toString());
//天氣實況+建議
bean.setLiveWeather(soapObject.getProperty(10).toString()+"\n"+soapObject.getProperty(11).toString());
//其他數據
//把三天天氣情況載入數組,打包進入bean.setList();
String date=soapObject.getProperty(6).toString();
String weatherToday="今天:"+date.split(" ")[0];
weatherToday+="\n天氣:"+date.split(" ")[1];
weatherToday+="\n氣溫:"+soapObject.getProperty(5).toString();
weatherToday+="\n風力:"+soapObject.getProperty(7).toString();
weatherToday+="\n";
// List<Integer> icons=new ArrayList<Integer>();
//天氣趨勢開始圖片名稱(以下稱:圖標一),天氣趨勢結束圖片名稱(以下稱:圖標二)
//icons.add(parseIcon(soapObject.getProperty(8).toString()));//Adds the specified object at the end of this List
// icons.add(parseIcon(soapObject.getProperty(9).toString()));
int icon1_ID=parseIcon(soapObject.getProperty(8).toString());
int icon2_ID=parseIcon(soapObject.getProperty(9).toString());
// Log.v("icon1",soapObject.getProperty(8).toString());
// Log.v("icon2",soapObject.getProperty(9).toString());
map.put("weatherDay",weatherToday);
//map.put("icons", icons);
map.put("icon1", icon1_ID);
map.put("icon2", icon2_ID);
list.add(map);
//-------------------------------------
map=new HashMap<String,Object>();
date=soapObject.getProperty(13).toString();
String weatherTomorrow="明天:" + date.split(" ")[0];
weatherTomorrow+="\n天氣:"+ date.split(" ")[1];
weatherTomorrow+="\n氣溫:"+soapObject.getProperty(12).toString();
weatherTomorrow+="\n風力:"+soapObject.getProperty(14).toString();
weatherTomorrow+="\n";
//icons=new ArrayList<Integer>();
// icons.add(parseIcon(soapObject.getProperty(15).toString()));
//icons.add(parseIcon(soapObject.getProperty(16).toString()));
icon1_ID=parseIcon(soapObject.getProperty(15).toString());
icon2_ID=parseIcon(soapObject.getProperty(16).toString());
Log.v("icon1",soapObject.getProperty(15).toString());
Log.v("icon2",soapObject.getProperty(16).toString());
map.put("weatherDay", weatherTomorrow);
map.put("icon1", icon1_ID);
map.put("icon2", icon2_ID);
//map.put("icons",icons);
list.add(map);
//------------------------
map=new HashMap<String,Object>();
date=soapObject.getProperty(18).toString();
String weatherAfterTomorrow="後天:" + date.split(" ")[0];
weatherAfterTomorrow+="\n天氣:"+ date.split(" ")[1];
weatherAfterTomorrow+="\n氣溫:"+soapObject.getProperty(17).toString();
weatherAfterTomorrow+="\n風力:"+soapObject.getProperty(19).toString();
weatherAfterTomorrow+="\n";
// icons=new ArrayList<Integer>();
// icons.add(parseIcon(soapObject.getProperty(20).toString()));
//icons.add(parseIcon(soapObject.getProperty(21).toString()));
icon1_ID=parseIcon(soapObject.getProperty(20).toString());
icon2_ID=parseIcon(soapObject.getProperty(21).toString());
Log.v("icon1",soapObject.getProperty(20).toString());
Log.v("icon2",soapObject.getProperty(21).toString());
map.put("weatherDay", weatherAfterTomorrow);
map.put("icon1", icon1_ID);
map.put("icon2", icon2_ID);
//map.put("icons",icons);
list.add(map);
//------------------------------------
bean.setList(list);
return bean;
}
//解析圖標名稱.gif字符串強制轉化爲--R.drawable.c_1整型 便於查表
private int parseIcon(String strIcon){
if (strIcon == null)
return -1;
if ("0.gif".equals(strIcon))
return R.drawable.a_0;
if ("1.gif".equals(strIcon))
return R.drawable.a_1;
if ("2.gif".equals(strIcon))
return R.drawable.a_2;
if ("3.gif".equals(strIcon))
return R.drawable.a_3;
if ("4.gif".equals(strIcon))
return R.drawable.a_4;
if ("5.gif".equals(strIcon))
return R.drawable.a_5;
if ("6.gif".equals(strIcon))
return R.drawable.a_6;
if ("7.gif".equals(strIcon))
return R.drawable.a_7;
if ("8.gif".equals(strIcon))
return R.drawable.a_8;
if ("9.gif".equals(strIcon))
return R.drawable.a_9;
if ("10.gif".equals(strIcon))
return R.drawable.a_10;
if ("11.gif".equals(strIcon))
return R.drawable.a_11;
if ("12.gif".equals(strIcon))
return R.drawable.a_12;
if ("13.gif".equals(strIcon))
return R.drawable.a_13;
if ("14.gif".equals(strIcon))
return R.drawable.a_14;
if ("15.gif".equals(strIcon))
return R.drawable.a_15;
if ("16.gif".equals(strIcon))
return R.drawable.a_16;
if ("17.gif".equals(strIcon))
return R.drawable.a_17;
if ("18.gif".equals(strIcon))
return R.drawable.a_18;
if ("19.gif".equals(strIcon))
return R.drawable.a_19;
if ("20.gif".equals(strIcon))
return R.drawable.a_20;
if ("21.gif".equals(strIcon))
return R.drawable.a_21;
if ("22.gif".equals(strIcon))
return R.drawable.a_22;
if ("23.gif".equals(strIcon))
return R.drawable.a_23;
if ("24.gif".equals(strIcon))
return R.drawable.a_24;
if ("25.gif".equals(strIcon))
return R.drawable.a_25;
if ("26.gif".equals(strIcon))
return R.drawable.a_26;
if ("27.gif".equals(strIcon))
return R.drawable.a_27;
if ("28.gif".equals(strIcon))
return R.drawable.a_28;
if ("29.gif".equals(strIcon))
return R.drawable.a_29;
if ("30.gif".equals(strIcon))
return R.drawable.a_30;
if ("31.gif".equals(strIcon))
return R.drawable.a_31;
return 0;
}
}
界面設計如ListVIew應用一所示http://blog.csdn.net/lilysea2012/article/details/8648027
AndroidManifest.xml文件添加這一行
<uses-permission android:name="android.permission.INTERNET"/>
效果如下