webService网络服务调用总结.docx

上传人:doc321 文档编号:12826025 上传时间:2021-12-06 格式:DOCX 页数:20 大小:273.45KB
返回 下载 相关 举报
webService网络服务调用总结.docx_第1页
第1页 / 共20页
webService网络服务调用总结.docx_第2页
第2页 / 共20页
webService网络服务调用总结.docx_第3页
第3页 / 共20页
webService网络服务调用总结.docx_第4页
第4页 / 共20页
webService网络服务调用总结.docx_第5页
第5页 / 共20页
亲,该文档总共20页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《webService网络服务调用总结.docx》由会员分享,可在线阅读,更多相关《webService网络服务调用总结.docx(20页珍藏版)》请在三一文库上搜索。

1、网络服务调用总结jacking2013年 10月29日目录快递通网络服务调用总结1WebServices 简介2Webservices 调用需要注意的问题(附案例 )2准备工作2相关 jar 包导入2相关权限添加3调用 webService 服务步骤3对调用过程的分析3自定义数据类型参数问题5带有自定义类型属性的自定义类型参数6自定义类型参数集合61/20由于项目涉及到网络通信 (客户端与服务器端的数据交互 ),故此将之前学习到的关于网络通信的知识总结并分享给大家,如对文档中某些内容有异议,请及时沟通讨论。通过学习了解到android 的网络通信方式有含很多种,例如:基于TCP协议的网络通信、

2、使用 URL访问网络资源、使用 HTTP访问网络、使用 Web Services 进行网络编程等等。本文档主要针对使用 Web Services 进行网络编程方式给以详细说明。WebServices简介Web services 是一种部署在 Web 上的对象或者组件,能够通过 Internet 进行调用的应用程序。 Web services 建立在以 XML 为主的开放的 web 规范技术基础上,其业务逻辑对调用者来说是透明的。Webservices调用需要注意的问题(附案例 )接下来我们结合一个案例来理解整个调用过程, 针对当时开发时遇到的问题, 进行详细说明。附:表达能力有限, 有很多东西

3、讲的不是很清楚, 请结合附带案例看此文档,希望能帮到你准备工作相关 jar 包导入新建 android 项目,将放在 android 项目的 lib 目录下,检查 jar 包是否如下图所示:如果不同,选中jar 包右键 ->build path->add to build path即可。2/20相关权限添加既然是访问网络操作,就需要添加访问网络的权限:对 AndroidManifest.xml 文件进行修改,添加网络权限,如下图所示:否则 Log 日志会打印缺少权限,如图:注意:这里只添加了网络权限,如果你的项目中还涉及到其他权限,请添加相应权限调用 webService服务步骤第

4、一步,指定Web Services 的命名空间和调用的方法名SoapObject rpc = new SoapObject( NameSpace,methodName ); 第二步,设置需要调用的 web Services 接口需要传入的参数rpc.addProperty(proPertyName,proPertyValue);第三步,生成调用Web Services 方法的 SOAP请求信息,并制定SOAP的版本SoapSerializationEnvelopeenvelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);envel

5、ope.bodyOUt = rpc;第四步,生成调用Web Services 方法的 HttpTransportSE 实体对象HttpTransportSE transport = new HttpTransportSE( ServiceURL);第五步,调用call 方法请求服务Transport.call( soapAction,envelope);第六步,获取服务端返回的数据SoapObject object = (SoapObject)envelope.bodyIn;第七步,解析返回的soapObject 并获取需要的数据结果String result = object.getProP

6、erty(0).toString();对调用过程的分析注 意 1 : 第 一 步 、 第 四 步 、 第 五 步 中 , 涉 及 到 调 用 Web Services 之 前 需 要 弄 清楚”NameSpace”、”methodName ”、”serviceURL”、”soapAction ”。这些值需要从 wsdl 文档中寻找,如果想对 wsdl 文档深入学习,请参考 wsdl 学习文档,本文档只说明如何从 wsdl 文档中找到相应的值。将服务端提供的url 地址浏览器地址栏可以看到如下界面:3/20通过链接访问wsdl 文档,可以看到当前wsdl 文档应用的所得有命名空间,内容界面如下:

7、在此文档中,我们也可以找到我们需要的四个重要的属性值:命名空间:找到 wsdl:definitions 节点,即 wsdl 的根节点,找到属性 targetNamespace 的值,即为我们所需的命名空间 nameSpace 的值,如图:服务地址:找到 wsdl:service 节点,找到其子节点 soap:address 的属性 location 的值,即为我们所需的服务地址 serviceURL的值,如图:方法名和 SoapAction:找到 wsdl:operation 节点,其属性 name 的值即为我们所需的方法名 methodName 的值,其子节点 soap:operation

8、的属性 SoapAction 的值即为当前我们所需方法所对应的 soapAction 的值,如图:至此,调用webService 服务所需的最基本的四个属性值获取完成。但调用的过程中一定要保证 methodName 与 soapAction 的一一对应关系。注意 2:第二步中,涉及到设置参数。通过wsdl 文件中 wsdl:types 节点的子节点xsd:import通过第一个URL获取到当前服务的所有方法、每个方法的所有参数及参数类型通过第二个URL获取到当前服务所有能直接传递的数据类型,即基本数据类型通过第三个URL获取到当前服务所有自定义类型的参数、参数的所有属性及属性类型4/20通过第

9、一个URL访问到如下界面:针对参数类型,如何判断参数是不是自定义参数类型呢?可以通过第二个URL 跳转查看服务描述的所有基本数据类型,如下图:若没有,通过第三个URL 跳转查看服务描述的所有自定义类型,一一对应的关系,如果没有在当前链接里找到你所要了解的数据类型, 那么这种数据类型即为复杂类型, 或称自定义类型。需要对自定义类型的属性加以进一步了解,如下图:若没有,可以询问服务端负责人员自定义数据类型参数问题针对这种自定义类型的参数,通过第二步中设置参数是达不到我们想要的效果的,服务端返回的信息为 ”服务器内部错误”等。那么这种情况我们该怎么解决呢?下面拿上述TransferParams 讲解

10、一下:第一步、在本地新建TransferParams.java 文件,实现KvmSerializable 序列化接口。第二步、将上图中TransferParams 参数包含的所有属性按顺序声明,注意:一定要按顺序第三步、实现getProperty(intarg0)、 getPropertyCount() 、 getPropertyInfo(intarg0,Hashtablearg1,PropertyInfoarg2)、 setProperty(int arg0,Objectarg1)方法。getProperty(int arg0)通过索引获取指定属性getPropertyCount()获取属性

11、集合的大小getPropertyInfo(int arg0,Hashtable arg1,PropertyInfo arg2)获取指定索引的属性的名称和类型,注意:方法中第一件事是为参数设置命名空间setProperty(int arg0,Object arg1)为指定的属性赋值5/20第四步、在调用过程中,添加本地数据类型与服务端数据类型的映射,通过addMapping()方法在调用webService 服务的 HttpTransportSE 对象调用 call()方法之前。addMapping() 方法有三个参数,分别是服务端的引用url、参数名和本地对应的类型。代码如下: envelop

12、e.addMapping(soapMapping, "TransferParams", TransferParams.class);三个参数可通过自定义参数描述文件中xs:schema 节点的targetNamespace属性值、xs:complexType 节点的 name 属性值获取到SoapMapping 和 TransferParams两个值。这样自定义类型的参数的问题也差不多能解决了。带有自定义类型属性的自定义类型参数但是此刻就又有问题了,你应该发现了此时自定义类型参数的所有属性都是基本数据类型,那如果此参数的某个属性也是自定义类型的, 该怎么解决呢?解决方法与上

13、述自定义类型的解决方法相似, 就是新建 java 文件实现 kvmSerializable 序列化接口来描述自定义类型的属性,然后以普通属性的形式在自定义类型参数中声明。自定义类型参数集合到这里, 自定义类型的参数问题已经解决了一半,剩下的一半是自定义类型参数集合。如果拥有自定义类型属性的自定义参数你理解了,那么这剩下的一半自定义类型参数集合就很容易了。这里你可以把集合想象成一个有且只有一个属性的参数,而此属性也为自定类型的。只是不同的是你在新建集合的java 文件时,需要继承Vector<E>,这里的E 指的是集合中包含的参数类型。当然参数类型的映射仍需要添加。最后,针对上面的资

14、源用一个完整的案例帮助大家分析一下,所以请容我再啰嗦一遍准备工作服务地址Ksoap2-android.Jar 包下载地址 1、 新建 android 项目,导入jar 包,添加权限2、 修改 activity_main.xml 文件,添加三个按钮分别用于测试无参(基本数据类型)webServices服务调用、自定义参数 webServices 服务调用、 自定义参数集合 webServices 服务调用和一个用于显示结果的显示框,代码如下:<?xml version="1.0" encoding="utf-8"?>android:layout

15、_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><TextViewandroid:id="+id/textView"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="hello world"6/20/&

16、gt;<Buttonandroid:id="+id/simple"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="1"/><Buttonandroid:id="+id/simplecom"android:layout_width="match_parent"android:layout_height="wrap_content&

17、quot;android:text="2"/><Buttonandroid:id="+id/comlist"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="3"/></LinearLayout>布局不是很复杂,在此就不再赘述了。3、 新建负责调用服务的工具类WebServiceOp.java 文件,代码如下:public class WebSer

18、viceOp / 命名空间private static final String NAME_SPACE = "http:/tempuri.org/"/ 服务地址/ 操作方法的名称private static String methodName = ""7/20private static LinkedHashMap<String,Object> paramMap;private static TransferParams tran;private static int flag = 1;/*公用方法* param methodname方法名称

19、* param paramMap参数集合* return* throws IOException*/public static SoapObject LoadResult(String methodname,Map<String,Object> paramMap) throws IOException/ 创建 soap 对象, 传入所需调用的webService 的命名空间和webService 方法名SoapObject soapObject = new SoapObject(NAME_SPACE, methodname);/ 创建 SoapSerializationEnvelo

20、pe 对象,传入所需版本SoapSerializationEnvelope envelope= new SoapSerializationEnvelope(SoapEnvelope.VER11);/ 创建 HttpTransportSE 对象,该对象用于调用 webService 操作 HttpTransportSE trans = new HttpTransportSE(URL,20000);/ 判断参数集合是否为空if(paramMap != null)/ 将 map 中的参数放入迭代器中Iterator<Entry<String, Object>> iter =

21、paramMap.entrySet().iterator();/ 遍历迭代器,为 soap 对象设置参数while(iter.hasNext()Map.Entry<String, Object> me = iter.next();soapObject.addProperty(me.getKey(),"".equals(me.getValue()?null:me.getValue();/ 服务器端自定义类型的映射switch(flag)case 0:break;case 1:envelope.addMapping(soapMapping,"Transfe

22、rParams",TransferParams.class);break;case 2:envelope.addMapping(soapMapping,"TransferParams",TransferParams.class);8/20envelope.addMapping(soapMapping, "ParamEnt", ParamEnt.class);envelope.addMapping(soapMapping,"ArrayOfParamEnt",ArrayOfPEnt.class);break;case 3:env

23、elope.addMapping(soapMapping,"TransferParams",TransferParams.class);envelope.addMapping(soapMapping, "ScanData", ScanData.class);envelope.addMapping(soapMapping,"ArrayOfScanData",ArrayOfScanData.class);break;default:break;/ 创建的 SoapObject 对象设为 SoapSerializationEnvelope

24、的传出 SOAP消息体 envelope.bodyOut = soapObject;envelope.setOutputSoapObject(soapObject);/ 设置兼容 .net 服务器端envelope.dotNet = true;/ 使用调试功能trans.debug = true;try / 调用操作对象call 方法,将 SoapSerializationEnvelope 作为参数调用远程webService/ 调用完成, 访问 SoapSerializationEnvelope 对象的 bodyIn 属性,该属性返回一个 SoapObject 对象,该对象代表 webSer

25、vice 的返回信息SoapObject result = (SoapObject) envelope.bodyIn;/ 打印 Log 日志信息return result; catch (XmlPullParserException e) e.printStackTrace();return null;/ 无参调用public static SoapObject serverTime() throws IOExceptionmethodName = "ServerTime"9/20flag = 0;return LoadResult(methodName, null);/

26、自定义类型参数调用public static SoapObject register() throws IOException/ 设置需要调用的服务器接口方法的名称methodName = "Register"tran = new TransferParams();tran.setCompress(true);tran.setDBType(0);tran.setDefaultLogic(true);tran.setEnterpriseID("Thinta");tran.setFileType(0);tran.setPDAID("1000000&

27、quot;);tran.setStationID("900001");/ 将自定义类型以参数形式放入map 集合中paramMap = new LinkedHashMap<String, Object>();paramMap.put("param", tran);flag = 1;return LoadResult(methodName, paramMap);/ 含有自定义类型参数集合的调用public static SoapObject downLoad() throws IOExceptionmethodName = "Down

28、load"tran = new TransferParams();tran.setCompress(true);tran.setDBType(0);tran.setDefaultLogic(true);tran.setEnterpriseID("Thinta");tran.setFileType(0);tran.setPDAID("1000000");tran.setStationID("900001");ParamEnt p1= new ParamEnt();p1.setTableName("SiteInfo&q

29、uot;);ParamEnt p2 = new ParamEnt();p2.setTableName("Employee");ArrayOfPEnt aope = new ArrayOfPEnt();aope.add(p1);aope.add(p2);10/20paramMap = new LinkedHashMap<String, Object>();paramMap.put("param", tran);paramMap.put("list", aope);flag = 2;return LoadResult(meth

30、odName, paramMap);对于这个类,需要啰嗦几句。主要方法是 LoadResult(String methodName, Map<String,Object>) 方法,它主要负责调用服务。从上述标记红色的代码可以看出, 其他方法在结尾时都调用了该方法, 这样写主要是为了提高 代 码 的 复 用 性 。 我 们 发 现 每 次 调 用 时 我 们 传 递 的 第 二 个 参数 都 是 Map 的 子 类LinkedHashMap 类型,因为这样能保证参数存入Map 集合中的顺序和参数从Map 中取出来的顺序是一致的 (因为参数的顺序会影响到 xml 信息的拼装,就可能导致

31、服务端解析不了的错误 ),所以此处选择了具体的 LinkedHashMap 类型由于承载参数在类内部的传递。然后我们讲解一下几个对应不同类型参数的方法:无参的方法 (serverTime) 在此处代表了基本数据类型参数的调用服务和无参调用服务两种情况,由于基本数据类型在 ksoap2 中已经做了默认的映射,所以映射工作我们不必再做,只需要直接设置参数就行(只是需要参数名称与参数值要保证一一对应)。自定义参数的方法 (Register)在此处代表含有自定义参数的调用服务操作,这里的参数为 TransferParams 类型,针对这种自定义类型,我们需要映射,既然要映射,就需要服务器端和客户端的各

32、自的类型,而此时只有服务器端对这个类型进行了定义,客户端并没有对这个类型进行定义,所以接下来的第一件事就是定义TransferParams 类型。具体作法如下:4、 新建 TransferParams.java 文件,实现KvmSerializable 接口,代码如下:public class TransferParams implements KvmSerializableprivate boolean Compress;private int DBType;private boolean DefaultLogic;private String EnterpriseID;private in

33、t FileType;private String MD5;private String PDAID;private String StationID;private String Version;Override11/20public Object getProperty(int arg0) switch (arg0) case 0:return Compress;case 1:return DBType;case 2:return DefaultLogic;case 3:return EnterpriseID;case 4:return FileType;case 5:return MD5

34、;case 6:return PDAID;case 7:return StationID;case 8:return Version;default:return null;Overridepublic int getPropertyCount() return 9;/ 参数的个数Overridepublic void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) / 这个很重要case 0:arg2.type=PropertyInfo.BOOLEAN_CLASS;arg2.name="Compress&qu

35、ot;break;case 1:arg2.type=PropertyInfo.INTEGER_CLASS;arg2.name="DBType"break;case 2:12/20arg2.type=PropertyInfo.BOOLEAN_CLASS;arg2.name="DefaultLogic"break;case 3:arg2.type=PropertyInfo.STRING_CLASS;arg2.name="EnterpriseID"break;case 4:arg2.type=PropertyInfo.INTEGER_CLA

36、SS;arg2.name="FileType"break;case 5:arg2.type=PropertyInfo.STRING_CLASS;arg2.name="MD5"break;case 6:arg2.type=PropertyInfo.STRING_CLASS;arg2.name="PDAID"break;case 7:arg2.type=PropertyInfo.STRING_CLASS;arg2.name="StationID"break;case 8:arg2.type=PropertyInfo.S

37、TRING_CLASS;arg2.name="Version"break;default:break;Overridepublic void setProperty(int arg0, Object arg1) switch (arg0) case 0:Compress = Boolean.getBoolean(arg1.toString();break;case 1:DBType = Integer.valueOf(arg1.toString();break;case 2:DefaultLogic = Boolean.getBoolean(arg1.toString();

38、break;13/20case 3:EnterpriseID = arg1.toString();break;case 4:FileType = Integer.valueOf(arg1.toString();break;case 5:MD5 = arg1.toString();break;case 6:PDAID = arg1.toString();break;case 7:StationID = arg1.toString();break;case 8:Version = arg1.toString();break;default:break;public boolean isCompre

39、ss() return Compress;public void setCompress(boolean compress) Compress = compress;public int getDBType() return DBType;public void setDBType(int dBType) DBType = dBType;public boolean isDefaultLogic() return DefaultLogic;public void setDefaultLogic(boolean defaultLogic) 14/20DefaultLogic = defaultL

40、ogic;public String getEnterpriseID() return EnterpriseID;public void setEnterpriseID(String enterpriseID) EnterpriseID = enterpriseID;public int getFileType() return FileType;public void setFileType(int fileType) FileType = fileType;public String getMD5() return MD5;public void setMD5(String mD5) MD

41、5 = mD5;public String getPDAID() return PDAID;public void setPDAID(String pDAID) PDAID = pDAID;public String getStationID() return StationID;public void setStationID(String stationID) StationID = stationID;public String getVersion() 15/20return Version;public void setVersion(String version) Version = version;此文件中除了属性的名称需要同wsdl 文件中的一致,getProperty() 、 getPropertyInfo() 、setProperty() 方法中属性的顺序需要注意意外,特别需要注意就是上边红色代码部分,一个是 getCount() 方法的返回值,一个是getPropertyInfo() 方法第三个参数的命名空间的设置。返回值是随着属性的改变而改变的,这点一定要注意,如果当前返回值小于属性的总

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1