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.youkuaiyun.com/lilysea2012/article/details/8648027
AndroidManifest.xml文件添加这一行
<uses-permission android:name="android.permission.INTERNET"/>
效果如下