Android通过ksoap2这个框架调用webservice大讲堂

Android通过ksoap2这个框架调用webservice大讲堂
摘要由CSDN通过智能技术生成
                       

昨天有人问我Android怎么连接mysql数据库,和对数据库的操作呀,我想把,给他说说json通信,可是他并不知道怎么弄,哎算了吧,直接叫他用ksoap吧,给他说了大半天,好多零碎的知识,看来还是有必要把这些东西整合起来,一方面自己有时候也看,另一方面当然是能帮助没有做个的小伙伴,其实东西不是很多,就是讲的有点详细,不怕多,就怕不仔细,
WebServices简介
Web services是一种部署在Web上的对象或者组件,能够通过Internet进行调用的应用程序。Web services 建立在以XML为主的开放的web规范技术基础上,其业务逻辑对调用者来说是透明的。

Webservices调用需要注意的问题(附案例)
接下来我们结合一个案例来理解整个调用过程,针对当时开发时遇到的问题,进行详细说明。
附:表达能力有限,有很多东西讲的不是很清楚,请结合附带案例看此文档,希望能帮到你
准备工作
相关jar包导入
新建android项目,将ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar放在android项目的lib目录下,检查jar包是否如下图所示:
这里写图片描述
相关权限添加
既然是访问网络操作,就需要添加访问网络的权限:
对AndroidManifest.xml文件进行修改,添加网络权限
这里写图片描述
调用webService服务步骤
第一步,指定WebServices的命名空间和调用的方法名
SoapObjectrpc = new SoapObject(NameSpace,methodName);
第二步,设置需要调用的webServices接口需要传入的参数
rpc.addProperty(proPertyName,proPertyValue);
第三步,生成调用WebServices方法的SOAP请求信息,并制定SOAP的版本
SoapSerializationEnvelope  envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
envelope.bodyOUt = rpc;
第四步,生成调用WebServices方法的HttpTransportSE实体对象
HttpTransportSE transport = new HttpTransportSE(ServiceURL);
第五步,调用call方法请求服务
Transport.call(soapAction,envelope);
第六步,获取服务端返回的数据
SoapObject object = (SoapObject)envelope.bodyIn;
第七步,解析返回的soapObject并获取需要的数据结果
String result = object.getProPerty(0).toString();
对调用过程的分析
注意1:第一步、第四步、第五步中,涉及到调用WebServices之前需要弄清楚”NameSpace”、”methodName”、”serviceURL”、”soapAction”。这些值需要从wsdl文档中寻找,如果想对wsdl文档深入学习,请参考wsdl学习文档,本文档只说明如何从wsdl文档中找到相应的值。
将服务端提供的url地址浏览器地址栏可以看到如下界面:
这里写图片描述
通过链接访问wsdl文档,可以看到当前wsdl文档应用的所得有命名空间,内容界面如下:这里写图片描述
在此文档中,我们也可以找到我们需要的四个重要的属性值:
命名空间:找到wsdl:definitions节点,即wsdl的根节点,找到属性targetNamespace的值,即为我们所需的命名空间nameSpace的值,如图:
这里写图片描述
这里写图片描述
方法名和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(int arg0)、getPropertyCount()、getPropertyInfo(int arg0,Hashtable arg1,PropertyInfo  arg2)、setProperty(int arg0,Object  arg1)方法。
getProperty(int arg0)  通过索引获取指定属性
getPropertyCount()   获取属性集合的大小
getPropertyInfo(int arg0,Hashtable arg1,PropertyInfo arg2)
获取指定索引的属性的名称和类型,注意:方法中第一件事是为参数设置命名空间
setProperty(int arg0,Object arg1) 为指定的属性赋值
第四步、在调用过程中,添加本地数据类型与服务端数据类型的映射,通过addMapping()方法在调用webService服务的HttpTransportSE对象调用call()方法之前。
addMapping()方法有三个参数,分别是服务端的引用url、参数名和本地对应的类型。代码如下:envelope.addMapping(soapMapping, “TransferParams”, TransferParams.class);
三个参数可通过自定义参数描述文件中xs:schema节点的targetNamespace属性值、xs:complexType节点的name属性值获取到SoapMapping和TransferParams两个值。
这样自定义类型的参数的问题也差不多能解决了。
带有自定义类型属性的自定义类型参数
但是此刻就又有问题了,你应该发现了此时自定义类型参数的所有属性都是基本数据类型,那如果此参数的某个属性也是自定义类型的,该怎么解决呢?解决方法与上述自定义类型的解决方法相似,就是新建java文件实现kvmSerializable序列化接口来描述自定义类型的属性,然后以普通属性的形式在自定义类型参数中声明。
自定义类型参数集合
到这里,自定义类型的参数问题已经解决了一半,剩下的一半是自定义类型参数集合。如果拥有自定义类型属性的自定义参数你理解了,那么这剩下的一半自定义类型参数集合就很容易了。这里你可以把集合想象成一个有且只有一个属性的参数,而此属性也为自定类型的。只是不同的是你在新建集合的java文件时,需要继承Vector,这里的E指的是集合中包含的参数类型。当然参数类型的映射仍需要添加。

最后,针对上面的资源用一个完整的案例帮助大家分析一下,所以请容我再啰嗦一遍
准备工作
服务地址    http://10.0.1.223:9100/KdtService/
Ksoap2-android.Jar包 下载地址:http://pan.baidu.com/s/1CE754
1、  新建android项目,导入jar包,添加权限
2、  修改activity_main.xml文件,添加三个按钮分别用于测试无参(基本数据类型)webServices服务调用、自定义参数webServices服务调用、自定义参数集合webServices服务调用和一个用于显示结果的显示框,代码如下:

package com.example.webservicetest;import java.io.IOException;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Map;import java.util.Map.Entry;import org.ksoap2.SoapEnvelope;import org.ksoap2.serialization.SoapObject;import org.ksoap2.serialization.SoapSerializationEnvelope;import org.ksoap2.transport.HttpTransportSE;import org.xmlpull.v1.XmlPullParserException;public class WebServiceOp {
        //命名空间    private static final String NAME_SPACE = "http://tempuri.org/";    //服务地址    private static final String URL = "http://10.0.1.223:9100/KdtService/basic";    //操作方法的名称    private static String methodName = "";    private static String soapMapping = "http://schemas.datacontract.org/2004/07/WebServiceManager";    private static LinkedHashMap<String,Object>paramMap;    private static TransferParamstran;    private static int flag = 1/**     * 公用方法     * @parammethodname方法名称     * @paramparamMap   参数集合     * @return     * @throws IOException     */    public static SoapObjectLoadResult(String methodname,Map<String,Object>paramMap) throws IOException{
   //创建soap对象,传入所需调用的webService的命名空间和webService方法名    SoapObjectsoapObject = new SoapObject(NAME_SPACE, methodname);    //创建SoapSerializationEnvelope对象,传入所需版本    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);     //创建HttpTransportSE对象,该对象用于调用webService操作    HttpTransportSE trans = new HttpTransportSE(URL,20000);    //判断参数集合是否为空    if(paramMap != null)    {        //将map中的参数放入迭代器中        Iterator<Entry<String, Object>>iter = 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, "TransferParams", TransferParams.class);                    break;                case 2:                    envelope.addMapping(soapMapping, "TransferParams", TransferParams.class);                envelope.addMapping(soapMapping, "ParamEnt", ParamEnt.class);                envelope.addMapping(soapMapping, "ArrayOfParamEnt", ArrayOfPEnt.class);                    break;                case 3:                    envelope.addMapping(soapMapping, "TransferParams", TransferParams.class);                envelope.addMapping(soapMapping, "ScanData", ScanData.class);                envelope.addMapping(soapMapping, "ArrayOfScanData", ArrayOfScanData.class);                    break;                default:                    break;            }    }    //创建的SoapObject对象设为SoapSerializationEnvelope的传出SOAP消息体envelope.bodyOut = soapObject;envelope.setOutputSoapObject(soapObject);        //设置兼容.net服务器端envelope.dotNet = true;        //使用调试功能trans.debug = true;         try {    //调用操作对象call方法,将SoapSerializationEnvelope作为参数调用远程webServicetrans.call(NAME_SPACE + "IKdtService/" + methodname, envelope);System.out.println(trans.requestDump);            //调用完成,访问SoapSerializationEnvelope对象的bodyIn属性,该属性返回一个SoapObject对象,该对象代表webService的返回信息SoapObject result = (SoapObject) envelope.bodyIn;            //打印Log日志信息            return result;        } catch (XmlPullParserException e) {e.printStackTrace();            return null;        }    }    //无参调用    public static SoapObjectserverTime() throws IOException    {    methodName = "ServerTime";    flag = 0;    return LoadResult(methodName, null);    }    //自定义类型参数调用    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");    tran.setStationID("900001");    //将自定义类型以参数形式放入map集合中    paramMap = new LinkedHashMap<String, Object>();    paramMap
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值