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的基本一致。

 

posted @ 2013-05-16 15:42  蠢驴  阅读(526)  评论(0)    收藏  举报