由于公司项目需要使用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,这些网上都有介绍。