这两天给老师做地铁app的demo,与后台的交互要用WebService,还挺麻烦的。所以想写点,希望有用。
Web Services(Web服务)是一个用于支持网络间不同机器互操作的软件系统,它是一种自包含、自描述和模块化的应用程序,它可以在网络中被描述、发布和调用,可以将它看作是基于网络的、分布式的模块化组件。它建立在HTTP,SOAP,WSDL这些通信协议之上,可以轻松的跨平台。
我们用的WebService就是服务器公布的一个接口,连上之后可以交互。WSDL是一份XML文档,它描述了Web服务的功能、接口、参数、返回值等,便于用户绑定和调用服务。它以一种和具体语言无关的方式定义了给定Web服务调用和应答的相关操作和消息。
比如我们内部的wsdl地址:http://172.16.1.59:8081/authpay/DataProcessBean?wsdl(这是内网的地址外面登不进去啦)。
开头是这样,
1 <wsdl:definitions xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://dataprocess.sw.hhjt.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DataProcessBeanService" targetNamespace="http://dataprocess.sw.hhjt.com/"> 2 <wsdl:types> 3 <xs:schema xmlns:tns="http://dataprocess.sw.hhjt.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" targetNamespace="http://dataprocess.sw.hhjt.com/" version="1.0"> 4 <xs:element name="Vey_Bnd_Req" type="tns:Vey_Bnd_Req"/> 5 <xs:element name="Vey_Bnd_ReqResponse" type="tns:Vey_Bnd_ReqResponse"/> 6 <xs:element name="Vey_Data_Col" type="tns:Vey_Data_Col"/> 7 <xs:element name="Vey_Data_ColResponse" type="tns:Vey_Data_ColResponse"/> 8 <xs:element name="Vey_Data_Send" type="tns:Vey_Data_Send"/> 9 <xs:element name="Vey_Data_SendResponse" type="tns:Vey_Data_SendResponse"/> 10 <xs:element name="Vey_Sell_Ticket" type="tns:Vey_Sell_Ticket"/> 11 <xs:element name="Vey_Sell_TicketResponse" type="tns:Vey_Sell_TicketResponse"/> 12 <xs:element name="Vey_Token_Download" type="tns:Vey_Token_Download"/> 13 <xs:element name="Vey_Token_DownloadResponse" type="tns:Vey_Token_DownloadResponse"/>
第一行有targetNamespace也即命名空间,在下面有调用的方法名称,比如我用了Vey_Token_Download,EndPoint一般是将WSDL地址末尾的"?wsdl"去除后剩余的部分;而SOAP Action通常为命名空间 + 调用的方法名称。
1 // 命名空间 2 String nameSpace = "http://dataprocess.sw.hhjt.com/"; 3 // 调用的方法名称 4 String methodName = "Vey_Token_Download"; 5 // EndPoint 6 String endPoint = "http://172.16.1.59:8081/authpay/DataProcessBean"; 7 // SOAP Action 8 String soapAction = "http://dataprocess.sw.hhjt.com/Vey_Token_Download"; 9 //调用Service 成功之后 new Ticket 存入数据库 失败则告诉他失败了 10 SoapObject rpc = new SoapObject(nameSpace,methodName); 11 12 BindTicket bt = new BindTicket(); 13 bt.setProperty(4,simnum); 14 bt.setProperty(6, useraccount); 15 bt.setProperty(7, userpassword); 16 17 PropertyInfo proInfo = new PropertyInfo(); 18 proInfo.setName("arg0"); 19 proInfo.setValue(bt); 20 proInfo.setType(bt.getClass()); 21 // 设置需调用WebService接口需要传入的参数 22 rpc.addProperty(proInfo); 23 24 // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本 25 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10); 26 27 envelope.bodyOut = rpc; 28 // 设置是否调用的是dotNet开发的WebService 29 envelope.dotNet = false; 30 // 等价于envelope.bodyOut = rpc; 31 envelope.setOutputSoapObject(rpc); 32 33 34 HttpTransportSE transport = new HttpTransportSE(endPoint); 35 try { 36 // 调用WebService 37 transport.call(soapAction, envelope); 38 } catch (Exception e) { 39 e.printStackTrace(); 40 } 41 42 // 获取返回的数据 43 SoapObject object = (SoapObject) envelope.bodyIn; 44 // 获取返回的结果 45 // String result = object.getProperty("ret").toString(); 46 String result = object.getProperty(0).toString(); 47 Log.v("result", result); 48 String flag = result.split(";")[1].split("=")[1]; 49 Log.v("flag",flag); 50 exMessage = result.split(";")[0].split("=")[1]; 51 Log.v("exmessage",exMessage);
值类型的传递通过ksoap可以直接进行传递,这里就不多说了!利用ksoap,值类型的变量即可作参数,也可以当作返回值。
但是这里要传的是对象,要编写实体类,且按照参数序列化设置好,demo里的实体类就照搬了一下。
import org.ksoap2.serialization.KvmSerializable; import org.ksoap2.serialization.PropertyInfo; import java.util.Hashtable; public class BindTicket implements KvmSerializable { protected String bndReqDate; protected String bndTcomAccount; protected String bndTcomPass; protected long bndTcomType; protected String bndTelNo; protected long bndUID; protected String bndUserName; protected String bndUserPass; protected String isSelled; protected String password; @Override public Object getProperty(int i) { switch (i){ case 0: return bndReqDate; case 1: return bndTcomAccount; case 2: return bndTcomPass; case 3: return bndTcomType; case 4: return bndTelNo; case 5: return bndUID; case 6: return bndUserName; case 7: return bndUserPass; case 8: return isSelled; case 9: return password; } return null; } @Override public int getPropertyCount() { return 10; } @Override public void setProperty(int i, Object o) { switch (i){ case 0: bndReqDate = o.toString(); break; case 1: bndTcomAccount = o.toString(); break; case 2: bndTcomPass = o.toString(); break; case 3: bndTcomType = Long.parseLong(o.toString());; break; case 4: bndTelNo = o.toString(); break; case 5: bndUID = Long.parseLong(o.toString());; break; case 6: bndUserName = o.toString(); break; case 7: bndUserPass =o.toString(); break; case 8: isSelled = o.toString(); break; case 9: password = o.toString(); break; default: break; } } @Override public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) { switch (i){ case 0: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndReqDate"; break; case 1: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndTcomAccount"; break; case 2: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndTcomPass"; break; case 3: propertyInfo.type = PropertyInfo.LONG_CLASS; propertyInfo.name = "bndTcomType"; break; case 4: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndTelNo"; break; case 5: propertyInfo.type = PropertyInfo.LONG_CLASS; propertyInfo.name = "bndUID"; break; case 6: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndUserName"; break; case 7: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "bndUserPass"; break; case 8: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "isSelled"; break; case 9: propertyInfo.type = PropertyInfo.STRING_CLASS; propertyInfo.name = "password"; break; default: break; } } }
最后记得在AndroidManifest.xml中配置添加访问网络的权限
<uses-permission android:name="android.permission.INTERNET" />
时间: 2024-10-25 14:06:27