网络服务调用总结jacking2013年10月29日目录快递通网络服务调用总结...............................................................................................................1WebServices简介.............................................................................................................................2Webservices调用需要注意的问题(附案例)...................................................................................2准备工作...................................................................................................................................2相关jar包导入................................................................................................................2相关权限添加...................................................................................................................3调用webService服务步骤......................................................................................................3对调用过程的分析...........................................................................................................3自定义数据类型参数问题...............................................................................................5带有自定义类型属性的自定义类型参数.......................................................................6自定义类型参数集合.......................................................................................................6由于项目涉及到网络通信(客户端与服务器端的数据交互),故此将之前学习到的关于网络通信的知识总结并分享给大家,如对文档中某些内容有异议,请及时沟通讨论。通过学习了解到android的网络通信方式有含很多种,例如:基于TCP协议的网络通信、使用URL访问网络资源、使用HTTP访问网络、使用WebServices进行网络编程等等。本文档主要针对使用WebServices进行网络编程方式给以详细说明。WebServices简介Webservices是一种部署在Web上的对象或者组件,能够通过Internet进行调用的应用程序。Webservices建立在以XML为主的开放的web规范技术基础上,其业务逻辑对调用者来说是透明的。Webservices调用需要注意的问题(附案例)接下来我们结合一个案例来理解整个调用过程,针对当时开发时遇到的问题,进行详细说明。附:表达能力有限,有很多东西讲的不是很清楚,请结合附带案例看此文档,希望能帮到你准备工作相关jar包导入新建android项目,将ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar放在android项目的lib目录下,检查jar包是否如下图所示:如果不同,选中jar包右键-buildpath-addtobuildpath即可。相关权限添加既然是访问网络操作,就需要添加访问网络的权限:对AndroidManifest.xml文件进行修改,添加网络权限uses-permissionandroid:name=android.permission.INTERNET/,如下图所示:否则Log日志会打印缺少权限,如图:注意:这里只添加了网络权限,如果你的项目中还涉及到其他权限,请添加相应权限调用webService服务步骤第一步,指定WebServices的命名空间和调用的方法名SoapObjectrpc=newSoapObject(NameSpace,methodName);第二步,设置需要调用的webServices接口需要传入的参数rpc.addProperty(proPertyName,proPertyValue);第三步,生成调用WebServices方法的SOAP请求信息,并制定SOAP的版本SoapSerializationEnvelopeenvelope=newSoapSerializationEnvelope(SoapEnvelope.VER10);envelope.bodyOUt=rpc;第四步,生成调用WebServices方法的HttpTransportSE实体对象HttpTransportSEtransport=newHttpTransportSE(ServiceURL);第五步,调用call方法请求服务Transport.call(soapAction,envelope);第六步,获取服务端返回的数据SoapObjectobject=(SoapObject)envelope.bodyIn;第七步,解析返回的soapObject并获取需要的数据结果Stringresult=object.getProPerty(0).toString();对调用过程的分析注意1:第一步、第四步、第五步中,涉及到调用WebServices之前需要弄清楚”NameSpace”、”methodName”、”serviceURL”、”soapAction”。这些值需要从wsdl文档中寻找,如果想对wsdl文档深入学习,请参考wsdl学习文档,本文档只说明如何从wsdl文档中找到相应的值。将服务端提供的url地址浏览器地址栏可以看到如下界面:通过链接访问wsdl文档,可以看到当前wsdl文档应用的所得有命名空间,内容界面如下:在此文档中,我们也可以找到我们需要的四个重要的属性值:命名空间:找到wsdl:definitions节点,即wsdl的根节点,找到属性targetNamespace的值,即为我们所需的命名空间nameSpace的值,如图:服务地址:找到wsdl:service节点,找到其子节点soap:address的属性location的值,即为我们所需的服务地址serviceURL的值,如图:方法名和SoapAction:找到wsdl:operation节点,其属性name的值即为我们所需的方法名methodName的值,其子节点soap:operation的属性SoapAction的值即为当前我们所需方法所对应的soapAction的值,如图:至此,调用webService服务所需的最基本的四个属性值获取完成。但调用的过程中一定要保证methodName与soapAction的一一对应关系。注意2:第二步中,涉及到设置参数。通过wsdl文件中wsdl:types节点的子节点xsd:import通过第一个URL获取到当前服务的所有方法、每个方法的所有参数及参数类型通过第二个URL获取到当前服务所有能直接传递的数据类型,即基本数据类型通过第三个URL获取到当前服务所有自定义类型的参数、参数的所有属性及属性类型通过第一个URL访问到如下界面:针对参数类型,如何判断参数是不是自定义参数类型呢?可以通过第二个URL跳转查看服务描述的所有基本数据类型,如下图:若没有,通过第三个URL跳转查看服务描述的所有自定义类型,一一对应的关系,如果没有在当前链接里找到你所要了解的数据类型,那么这种数据类型即为复杂类型,或称自定义类型。需要对自定义类型的属性加以进一步了解,如下图:若没有,可以询问服务端负责人员自定义数据类型参数问题针对这种自定义类型的参数,通过第二步中设置参数是达不到我们想要的效果的,服务端返回的信息为”服务器内部错误”等。那么这种情况我们该怎么解决呢?下面拿上述TransferParams讲解一下:第一步、在本地新建TransferParams.java文件,实现KvmSerializable序列化接口。第二步、将上图中TransferParams参数包含的所有属性按顺序声明,注意:一定要按顺序第三步、实现getProperty(intarg0)、getPropertyCount()、getPropertyInfo(intarg0,Hashtablearg1,PropertyInfoarg2)、setProperty(intarg0,Objectarg1)方法。getProperty(intarg0)通过索引获取指定属性getPropertyCount()获取属性集合的大小getPropertyInfo(intarg0,Hashtablearg1,PropertyInfoarg2)获取指定索引的属性的名称和类型,注意:方法中第一件事是为参数设置命名空间setProperty(intarg0,Objectarg1)为指定的属性赋值第四步、在调用过程中,添加本地数据类型与服务端数据类型的映射,通过addMapping()方法在调用webService服务的HttpTransportSE对象调用call()方法之前。addMapping()方法有三个参数,分别是服务端的引用url、参数名和本地对应的类型。代码如下:envelope.addMapping(soapMapping,TransferParams,TransferParams.class);三个参数可通过自定义参数描述文件中xs:schema节点的targetNamespace属性值、xs:complexType节点的name属性值获取到SoapMapping和TransferParams两个值。这样自定义类型的参数的问题也差不多能解决了。带有自定义类型属性的自定义类型参数但是此刻就又有问题了,你应该发现了此时自定义类型参数的所有属性都是基本数据类型,那如果此参数的某个属性也是自定义类型的,该怎么解决呢?解决方法与上述自定义类型的解决方法相似,就是新建java文件实现kvmSerializable序列化接口来描述自定义类型的属性,然后以普通属性的形式在自定义类型参数中声明。自定义类型参数集合到这里,自定义类型的参数问题已经解决了一半,剩下的一半是自定义类型参数集合。如果拥有自定义类型属性的自定义参数你理解了,那么这剩下的一半自定义类型参数集合就很容易了。这里你可以把集合想象成一个有且只有一个属性的参数,而此属性也为自定类型的。只是不同的是你在新建集合的java文件时,需要继承VectorE,这里的E指的是集合中包含的参数类型。当然参数类型的映射仍需要添加。最后,针对上面的资源用一个完整的案例帮助大家分析一下,所以请容我再啰嗦一遍准备工作服务地址包下载地址: