Android调用WCF(三)
Android调用WCF(三)
2013-05-16 15:26:45
在前面的学习中已经解决了Android与WCF的初步交互,已经可以获得服务端传来的集合类中的数据了。在本篇中,要继续了解怎么样将复杂类型的数据传递给WCF。这个实现后,对Ksoap2包就算是有一个基本的了解了,可以用其进行项目开发。下面记录一下利用Ksoap2包传递复杂类型的步骤。
1、先建立一个实体类,用来封装需要传递的数据
1 /** 2 * 建立一个User实体类,封装数据 3 * 4 */ 5 public class User { 6 /** 7 * 必须使用int类型, 因为当不设置此属性时, KSOAP2会得到默认值0. 如果是Integer类型, 未设置属性的情况下, 8 * KSOAP2只会得到null, 此时会报错 SoapFault - faultcode: 'soap:Server' faultstring: 9 * 'Illegal argument. For input string: ""' faultactor: 'null' detail: null 10 */ 11 private String UId; 12 private String UName; 13 14 public String getAge() { 15 return UId; 16 } 17 18 public void setAge(String Age) { 19 this.UId = Age; 20 } 21 22 public String getName() { 23 return UName; 24 } 25 26 public void setName(String Name) { 27 this.UName = Name; 28 } 29 }
在项目中,一般将需要交互的数据抽出来,单独做一个实体类。
2、建立KSOAP2模型序列化实现类
1 /** 2 * KSOAP2模型序列化实现类 3 * User_必须要实现KvmSerializable接口,KvmSerializable接口是Ksoap2中一个用来实现传递复杂类型数据的 4 * 所以User_类需要实现getProperty()、getPropertyInfo()、setProperty()、setProperty()的覆写 5 */ 6 7 public class User_ extends User implements KvmSerializable { 8 9 /** 10 * 自定义类型(对象)所处的命名空间. 从wsdl(xsd:schema节点targetNamespace属性)中可以找到 例如: 11 * <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 12 */ 13 public static final String NAMESPACE = "http://schemas.datacontract.org/2004/07/WcfRecieve";//???不知道为什么要用这个NAMESPACE 14 15 16 /** 17 * 覆写方法一:获得需要传递的属性。有几个加几个 18 */ 19 @Override 20 public Object getProperty(int index) { 21 Object value = null; 22 switch (index) { 23 case 0: 24 value = getName(); 25 break; 26 case 1: 27 value = getAge(); 28 break; 29 } 30 return value; 31 } 32 33 34 /** 35 * 覆写方法二:返回需要传递的属性个数 36 */ 37 @Override 38 public int getPropertyCount() { 39 return 2; 40 } 41 42 43 /** 44 * 覆写方法三:得到要传递给服务端的具体信息。其中UName、UId....是服务端接收属性的名字 45 */ 46 @Override 47 public void getPropertyInfo(int index, Hashtable properties, 48 PropertyInfo info) { 49 switch (index) { 50 case 0: 51 info.name = "UName"; 52 info.type = PropertyInfo.STRING_CLASS; 53 // 必须设置对象属性所处的命名空间. 54 // XXX 只要设置一个属性的namespace, 其他属性就可以不设置了 55 info.namespace = NAMESPACE; 56 break; 57 case 1: 58 info.name = "UId"; 59 info.type = PropertyInfo.STRING_CLASS; 60 info.namespace = NAMESPACE; 61 break; 62 default: 63 break; 64 } 65 66 } 67 68 69 /** 70 * 覆写方法四: 可以不实现 71 */ 72 @Override 73 public void setProperty(int index, Object value) { 74 // switch (index) { 75 // case 0: 76 // setId(Integer.valueOf(value.toString())); 77 // break; 78 // case 1: 79 // setName(value.toString()); 80 // break; 81 // default: 82 // break; 83 // } }} 84 } 85 86 }
这个类是进行传递复杂类型数据的关键,其中的四个覆写方法就是描述需要传递的数据的。具体解释看代码中间的注释。
3、调用Ksoap2包来连接WCF服务端,并传递数据
1 /** 2 * 调用Ksoap2包来连接WCF服务端,并传递数据 3 * @author Administrator 4 * 5 */ 6 public class Main { 7 /** 8 * web service服务的命名空间, 可以在wsdl(wsdl:definitions节点targetNamespace属性)中找到 例如: 9 * <wsdl:definitions targetNamespace="http://communication.service.server"> 10 */ 11 private String URL = "http://172.16.201.190:8015/Service.svc"; 12 private String NAMESPACE = "http://tempuri.org/"; 13 private String Action="http://tempuri.org/IServer/GetStu"; 14 private String METHOD_NAME = "GetStu"; 15 16 17 public static void main(String[] args) { 18 19 new Main().testKsoap2InvokeWs(); 20 } 21 22 private void testKsoap2InvokeWs() { 23 // TODO Auto-generated method stub 24 SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 25 // 建立一个KSOAP2模型序列化实现类的对象user 26 User_ user = new User_(); 27 // 设置要传递的信息 28 user.setName("远程调用含自定义类型参数的WebService方法"); 29 user.setAge("610"); 30 PropertyInfo argument = new PropertyInfo(); 31 // web service实现方法中参数的名称 32 argument.setName("user"); 33 argument.setValue(user); 34 // 如果要调用的web,service方法有自定义类型参数 35 // 建议设置参数的命名空间(如果在参数序列化实现类User_的属性中已经指定了命名空间, 省略似乎没什么影响, 但推荐指定) 36 argument.setNamespace(NAMESPACE); 37 argument.setType(User_.class); 38 39 request.addProperty(argument); 40 41 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 42 envelope.dotNet = true; 43 envelope.setOutputSoapObject(request); 44 // 映射调用WebService要传递的序列化类对象,namespace和name就是wsdl中定义的complexType,clazz指定要序列化的类对象 45 envelope.addMapping(User_.NAMESPACE, "User", User_.class); 46 47 HttpTransportSE httpTransport = new HttpTransportSE(URL); 48 // debug为true时调用httpTransport.requestDump/responseDump才有值, 否则为null, 49 // 可以将生成的SOAP协议全部打印出来以供排错 50 httpTransport.debug = true; 51 52 try { 53 httpTransport.call(Action, envelope); 54 // System.out.println(httpTransport.requestDump); 55 // System.out.println(httpTransport.responseDump); 56 SoapObject response = (SoapObject) envelope.getResponse(); 57 // 获取WCF服务端返回的属性值 58 System.out.println(response.getProperty("UName")); 59 System.out.println(response.getProperty("UId")); 60 61 } catch (Exception e) { 62 e.printStackTrace(); 63 } 64 65 } 66 67 }
到这里,我目前了解到的Ksoap2包的内容基本上已经说完了,可以调用Ksoap2进行交互了。注意,Android与Webservice的交互用到的知识与Android调用WCF的基本一致。

浙公网安备 33010602011771号