android调用webservice传递自定义类以及类的集合

来源:互联网 发布:淘宝分销下单什么意思 编辑:程序博客网 时间:2024/05/22 03:41

    由于公司项目需要使用webservice传递自定义的类的集合,所以最近研究了一下这方面的内容,其中遇到的各种困难和挫折就不提了,闲话少说进入正题。

   1.首先引入支持ksoap协议的第三方jar包,至于怎么加入android项目工程中网上有很多文章,需要提到的一点是当你运行android项目报引用jar包中的类找不到的错误时一般就是你加入jar包的方式不对。

   2.在你的android项目中实现你要传递的类,注意该类是需要实现KvmSerializable接口。

   3.编写调用webservice的方法。在这里webservice是通过axis2+Eclipse构建的。

   4.运行android项目,测试实现效果。

   以上只是简短的叙述了一下项目的整个流程,这些网上都有,文章好不好关键看代码。下面呈上代码了。

  一:android客户端代码:

   1.要传输的类:

package com.cbq.webServiceTest;
import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Person implements KvmSerializable {
private String name;
private Integer age;
public Person(){

}
public Person(String name,Integer age){
this.name=name;
this.age=age;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}


public void setAge(Integer age) {
this.age = age;
}

@Override
public Object getProperty(int arg0) {
switch(arg0){
case 0:
return name;
case 1:
return age;
}
return null;
}

@Override
public int getPropertyCount() {
return 2;
}

@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
        switch(index){
        case 0:
        info.type=PropertyInfo.STRING_CLASS;//设置info type的类型
        info.name="name";
        break;
        case 1:
        info.type=PropertyInfo.INTEGER_CLASS;
        info.name="age";
        break;
        default:
        break;
        }
}

@Override
public void setProperty(int index, Object value) {
         switch(index){
         case 0:
        name=value.toString();
        break;
         case 1:
        age=Integer.parseInt(value.toString());
        break;
        default:
        break;
         }
}
}

以上定义了Person类该类拥有name和age属性,并实现了 KvmSerializable接口。

2.调用webservice的方法。

      public static String SERVICE_NS="http://test.cbq.com";
public static String  WEATHER_SERVICES_URL ="http://192.168.99.18:8080/axis2/services/MyFristService";

     public static Person getPerson(Person person){
String PersonNameSpace="http://test.cbq.com/xsd";//这个很重要,注意和targetNamespace区分
String methodName="getPerson";
HttpTransportSE ht=new HttpTransportSE(WEATHER_SERVICES_URL);
    ht.debug=true;//开启ht的调试模式,以打印调试信息。
    SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
    SoapObject request=new SoapObject(SERVICE_NS,methodName);
    //把要传输的对象封装SoapObject中,这也是一种方法,但过于麻烦,不建议采用
    /*SoapObject so=new SoapObject("http://test.cbq.com/xsd", "Person");
    so.addProperty("age", person.getAge());
    so.addProperty("name", person.getName());*/
    request.addProperty("person", person);
    envelope.setOutputSoapObject(request);
    //addMapping中namespace不是整个wsdl中的namespace而是你自定义数据类型的namespace,注意,这是太重要了。
    envelope.addMapping(PersonNameSpace, "Person", Person.class);
    envelope.dotNet=false;
    try {
ht.call(SERVICE_NS+methodName, envelope);
if(envelope.getResponse()!=null){
    SoapObject response=(SoapObject) envelope.bodyIn;
    Person p=(Person)response.getProperty("return");
    System.out.println(p.getName());
    }
} catch (Exception e) {
System.out.println("出错了");
e.printStackTrace();

return null;
}

上面是个人写的原生态传递单个自定类的方法。其中关键要注意的地方都已标注上。下面给出传递类的自定义类的集合方法:

public static List<Person> getPersons(Person[] ps){
String methodName="getPs";
String PersonNameSpace="http://test.cbq.com/xsd";
HttpTransportSE ht=new HttpTransportSE(WEATHER_SERVICES_URL);
    ht.debug=true;//开启ht的调试模式,以打印调试信息。
    SoapSerializationEnvelope envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
    SoapObject request=new SoapObject(SERVICE_NS,methodName);
    //多次添加传入的参数。
    request.addProperty("ps",ps[0]);
    request.addProperty("ps",ps[1]);
    envelope.bodyOut=request;
    envelope.addMapping(PersonNameSpace, "Person", Person.class);
    envelope.dotNet=false;
    try {
ht.call(SERVICE_NS+methodName, envelope);
if(envelope.getResponse()!=null){
    SoapObject response=(SoapObject) envelope.bodyIn;
    List<Person>persons=new ArrayList<Person>();
    for(int i=0;i<response.getPropertyCount();i++){
    Person p=(Person)response.getProperty(i);
    persons.add(p);
    System.out.println(p.getName()+"--->"+p.getAge());
    }
    return persons;
    }
} catch (Exception e) {
System.out.println("出错了");
e.printStackTrace();

return null;
}

  这里有几点需要注意:1.改方法传入的参数是自定义类的数组,而在编写服务端代码的时候注意也是需要使用自定义                                        数组来接收传入的参数。使用其他的集合类型都会报类无法序列化的异常。

                                       2.在传入参数时需要逐个加入。

二:服务端代码:

       如何构建webservice,网上有好多资料,这里不再叙述。

       1.定义一个和android client一样的Person类,用于接收从client传过来的Person。注意要和客户端的Person类完全一样,但不必实现Kvmserilable接口。

       2.服务端对外开放的接口实现:

public Person getPerson(Person person){
    return person;
    }

 public Person[] getPs(Person[] ps){
    List<Person> persons=new ArrayList<Person>();
    for(int i=0;i<ps.length;i++){
    persons.add(ps[i]);
    }
    //return persons;
    return ps;
    }

服务端并没有做其他的逻辑处理,只是简单的返回了从android客户端接收的数据。这里需要注意的方法参数传入的类型,尤其是在传入自定义类型的集合时使用数字的形式封装集合。

3.打包发布到网络,生成wsdl,这些网上都有介绍。