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

趁热打铁,通过两天的不懈努力,终于小有成就。总算通过自建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 Double				dBusLongitude; 
	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());
	}
	*/
	@Override
	public Object getProperty(int arg0) {
		// TODO Auto-generated method stub
		switch(arg0){
			case 2:
				return iDataNum;
			case 1:
				return dBusLongitude;
			case 0:
				return dBusLatitude;
		}
		
		return null;
	}

	@Override
	public int getPropertyCount() {
		// TODO Auto-generated method stub
		return 3;
	}

	@Override
	public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo info) {
		// TODO Auto-generated method stub
		switch(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;
        }
	}

	@Override
	public void setProperty(int index, Object value) {
		// TODO Auto-generated method stub
		switch(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";
		// EndPoint
		String endPoint = "http://192.168.0.7:8088/BusLocationService/services/BusLocationService";
		// SOAP Action
		String 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开发的WebService
		envelope.dotNet = false;
		envelope.encodingStyle="UTF-8";
		// 等价于envelope.bodyOut = rpc;
		envelope.setOutputSoapObject(rpc);
		
		envelope.addMapping("http://entity.jianboBusLocation.com", "CBusLocation", CBusLocation.CBUSLOCATION_CLASS);

		//Marshal class
		MarshalDouble marshaldDouble = new MarshalDouble();
		marshaldDouble.register(envelope);
		
		HttpTransportSE transport = new HttpTransportSE(endPoint);
		transport.debug = true;
		try {
			// 调用WebService
			transport.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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值