f(msg.what=12){
lblResult.append(msg.getData().getString("result")+"\r\n");
}
}
};
到目前为止,我们已经调用了wcf服务第一个服务,就说明传递基类型是没有问题。但是很遗憾的是,对于传递复杂类型和数组集合参数进行调用,在服务那边总是提示无法对传递进来的数据进行反序列化的错误(希望高手指点)。还好我们可以把所以的服务类型都转为json数据,通过json数据进行传递调用,就可以解决复杂类型传递的问题。
对于有强迫症的我来说,不甘心,因为在网上看了许多的教程,利用Ksoap2是可以直接传递复杂类型的来调用.NET平台的服务的。不过网上大部分教程调用的都是传统的webservice服务(asmx文件),于是我就在wcf服务项目中新建一个传统的asmx文件,提供的服务与wcf服务一样的。结果发现,果然能够利用ksoap2传递一个复杂类型来调用服务。下一节总结利用ksoap2传递复杂对象来调用传统的webservice服务。
3 传统的WebService服务
为了和wcf服务进行对比,webservice提供的服务和wcf一致,代码如下:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。
// [System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{
[WebMethod]
public int Add(int op1, int op2)
{
return op1 + op2;
}
[WebMethod]
public string PostPeopleInfo(People people)
{
return "姓名:" + people.Name + "/" + "年龄:" + people.Age;
}
}
其中WebService特性中的Namespace属性和wcf的Namespace的作用一样的。
同样的也在iis中进行发布。发布成功之后,能够访问到asmx文件。
4 Android调用WebService服务
不管是调用WCF的服务还是WebService的服务,传递基类型去调用,代码都是一样的,且能够正确的调用。下面利用复杂的People类型来调用WebService的服务。
我们需要传递复杂类型,首先我们要在android中建立一个复杂类型,并且复杂类型包含字段名称和个数一定要与服务上的复杂类型保持一致,对于服务的复杂类型具有哪些字段,我们可以通过查看服务调用的示例得知。如下图所示。
根据上面复杂类型的字段说明,我们在android中建立复杂类型(类型名可以随意),包含两个字段且字段名称必须是Age和Name,数据类型也要一致,上面的这个people代表该复杂类型形参名为people(服务调用的时候必须要保持一样)。需要注意的是,这个复杂类型必须要继承KvmSerializable,这样ksoap2进行服务调用的时候,能够把people对象序列化为服务端能够接受的格式。代码如下:
public class People implements KvmSerializable {
public int Age;
public String Name;
@Override
public Object getProperty(int arg0) {
switch (arg0){
case 0:
return Age;
case 1:
return Name;
default:
return null;
}
}
@Override
public int getPropertyCount() {
return 2;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
switch (arg0){
case 0:{
arg2.type = PropertyInfo.INTEGER_CLASS;
arg2.name = "Age";
break;
}
case 1:{
arg2.type = PropertyInfo.STRING_CLASS;
arg2.name = "Name";
break;
}
}
}
@Override
public void setProperty(int arg0, Object arg1) {
switch (arg0){
case 0:{
Age = Integer.parseInt(arg1.toString()) ;
break;
}
case 1:{
Name = arg1.toString();
break;
}
}
}
}
下面是传递复杂对象调用web服务,其中服务地址、操作地址、方法名以及命名空间和前面一样,只需要在服务说明wsdl文档中找operation name节点和operation soapAction节点的值即可,其他地方也类似,只是在封装soapobject的时候有一些区别,代码如下:
//地址声明
private String nameSpace="http://tempuri.org/";
private String url="http://172.21.212.54:8888/WebService.asmx";
private String soapAction="http://tempuri.org/PostPeopleInfo";
private String methodName="PostPeopleInfo";
//服务调用
protected SoapObject getSoapResult() {
SoapObject outObject = new SoapObject(nameSpace, methodName);
People people = new People();
// 设置字段值
people.setProperty(0, 23);
people.setProperty(1, "Juame");
// 设置SoapObject对象
outObject.addProperty("people", people);
//也可以这样设置SoapObject
/*PropertyInfo peoInfo = new PropertyInfo();
peoInfo.setName("people");
peoInfo.setValue(people);
|