Android使用KSOAP调用webservice返回自定义类

来源:互联网 发布:javascript在web哪里找 编辑:程序博客网 时间:2024/05/04 20:11

趁热打铁,通过两天的不懈努力,终于小有成就。总算通过自建webservice服务端与Android客户端实现了自定义类即复杂对象的传递。

一、服务器端:

使用XFire引擎创建Webservice,方法很简单,网上也有许多例子,不再赘述。代码目录结构如下:


IBusLocationService为接口类,BusLocationServiceImpl为实现类。CBusLocation为自定义类,即要传递的类型。IBusLocationService.aegis.xml为XFire的映射配置文件。CFinalData为自己写的辅助类,不用关心。

二、客户端:

不要忘记引入Jar包(ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar)。代码目录结构如下:

MainActivity_BusLocation为Activity类。MainActivity为另一个Activity,调用网络webservice查询天气应用,不用关心。MarshalDouble是为了实现Double类序列化的类。CBusLocation为客户端的自定义类型,与服务器端的自定义类型相对。

1.CBusLocation类源码:

package com.jianboBusLocation.entity.sub;import java.util.Hashtable;import org.ksoap2.serialization.KvmSerializable;import org.ksoap2.serialization.PropertyInfo;import org.ksoap2.serialization.SoapObject;import java.lang.Double;public class CBusLocation implements KvmSerializable{/** *  */public static Class CBUSLOCATION_CLASS = CBusLocation.class;private int iDataNum;private Double  dBusLatitude;private DoubledBusLongitude; public static final String NAMESPACE = "http://entity.jianboBusLocation.com";public CBusLocation(){}public CBusLocation(int iDataNum, Double dLatitude, Double dLongitude){this.iDataNum = iDataNum;this.dBusLatitude = dLatitude;this.dBusLongitude = dLongitude;}/*public CBusLocation(SoapObject obj){this.iDataNum = Integer.parseInt(obj.getProperty("iDataNum").toString());this.dBusLatitude = Double.parseDouble(obj.getProperty("dBusLatitude").toString());this.dBusLongitude = Double.parseDouble(obj.getProperty("dBusLongitude").toString());}*/@Overridepublic Object getProperty(int arg0) {// TODO Auto-generated method stubswitch(arg0){case 2:return iDataNum;case 1:return dBusLongitude;case 0:return dBusLatitude;}return null;}@Overridepublic int getPropertyCount() {// TODO Auto-generated method stubreturn 3;}@Overridepublic void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo info) {// TODO Auto-generated method stubswitch(arg0){        case 2:        info.type=PropertyInfo.INTEGER_CLASS;//设置info type的类型        info.name="iDataNum";        info.namespace = NAMESPACE;        break;        case 1:        info.type=Double.class;        info.name="dBusLongitude";        info.namespace = NAMESPACE;        break;        case 0:        info.type=Double.class;        info.name="dBusLatitude";        info.namespace = NAMESPACE;        break;        default:        break;        }}@Overridepublic void setProperty(int index, Object value) {// TODO Auto-generated method stubswitch(index){    case 2:    iDataNum=Integer.valueOf(value.toString());    break;        case 1:        dBusLongitude=Double.valueOf(value.toString());        break;        case 0:        dBusLatitude=Double.valueOf(value.toString());        break;        default:        break;        }}public int getIDataNum() {return iDataNum;}public void setIDataNum(int iDataNum) {this.iDataNum = iDataNum;}public double getDBusLatitude() {return dBusLatitude;}public void setDBusLatitude(Double dBusLatitude) {this.dBusLatitude = dBusLatitude;}public double getDBusLongitude() {return dBusLongitude;}public void setDBusLongitude(Double dBusLongitude) {this.dBusLongitude = dBusLongitude;}}

一定要实现接口KvmSerializable,并注意NameSpace属性。

2.MainActivity_BusLocation中调用webservice的方法源码:

public void getRemoteInfo_My(String phoneSec) throws SoapFault {// 命名空间String nameSpace = "http://jianboBusLocation.com";// 调用的方法名称String methodName = "getBusLocation";// EndPointString endPoint = "http://192.168.0.7:8088/BusLocationService/services/BusLocationService";// SOAP ActionString soapAction = "http://jianboBusLocation.com/getBusLocation";// 指定WebService的命名空间和调用的方法名SoapObject rpc = new SoapObject(nameSpace, methodName);// 设置需调用WebService接口需要传入的两个参数mobileCode、userId//rpc.addProperty("in0", "my test");rpc.addProperty("iTime", 1);CBusLocation cTemp = new CBusLocation();cTemp.setIDataNum(2);cTemp.setDBusLatitude(2.0);cTemp.setDBusLongitude(2.0);PropertyInfo objekt = new PropertyInfo();          objekt.setName("inBusLoc");          objekt.setValue(cTemp);          objekt.setType(cTemp.getClass());          objekt.setNamespace(CBusLocation.NAMESPACE);        rpc.addProperty(objekt); // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);envelope.bodyOut = rpc;// 设置是否调用的是dotNet开发的WebServiceenvelope.dotNet = false;envelope.encodingStyle="UTF-8";// 等价于envelope.bodyOut = rpc;envelope.setOutputSoapObject(rpc);envelope.addMapping("http://entity.jianboBusLocation.com", "CBusLocation", CBusLocation.CBUSLOCATION_CLASS);//Marshal classMarshalDouble marshaldDouble = new MarshalDouble();marshaldDouble.register(envelope);HttpTransportSE transport = new HttpTransportSE(endPoint);transport.debug = true;try {// 调用WebServicetransport.call(soapAction, envelope);} catch (Exception e) {e.printStackTrace();}// 获取返回的数据SoapObject object = (SoapObject) envelope.getResponse();//CBusLocation cLoc = new CBusLocation(object);// 获取返回的结果//2个数,1经度,0纬度resultString = "latitude : " + object.getProperty(0).toString() + "\nlongitude : " + object.getProperty(1).toString() + "\ndata number : " + object.getProperty(2).toString();}
注意参数设置,及addMapping方法的调用。addMapping方法的第一个参数为服务器端的自定义类的命名空间,第二个参数为类名,第三个参数为客户端自定义类。

以上,这样就完成了。看似简单,可是费了我两三天的时间,追根究底还是自己懂得太少,写出来希望对大家有用。


由于项目需要使用webservice与android所以学习了一下。期间遇到了许多问题,最大的收获就是,信心与坚持。有信心,相信自己能够解决问题;坚持住,遇到困难不退缩。电子信息技术如浩瀚大海,咱们做开发的,不可能什么技术都会,只有不断学习才能跟上技术发展。向所有程序猿致敬,信心与坚持,与君共勉!

借鉴文章:怎样通过ksoap2发送复杂参数给web service方法(How to send complex type using ksoap2)

源码链接:http://download.csdn.net/detail/rjliulei/6523113