Ksoap2 与 JAX-WS 相互传送自定义类
来源:互联网 发布:2017网络行业利润率 编辑:程序博客网 时间:2024/06/17 12:46
本文主要描述了android客户端与PC服务器端,利用webservice和ksoap2插件进行网络通信的传递实体类的方法。网上有好多文章都描述了将android客户端的自定义实体类作为参数传递给webservice中方法的步骤,能够正常的运行。但是当android客户端接收自定义类型时,却不能强制类型转换为自定义类型(附注:好像用dotNet实现的webservice可以,但是用JAX-WS的不行)。本文自定义了一个parseToObject方法,来处理该问题,并以此为基础,处理了自定义类型List的返回值。
首先在服务端创建自定义类Person,详细代码如下:
public class Person {
private String name;
private Integer 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;
}
}
然后创建服务的接口和实现方法,详细代码如下:
public interface HelloWorldService {
public List<Person> sayHelloOne(Person person);
public Person sayHelloTwo(Person person);
public Boolean sayHelloThree(Boolean isRight);
public Date sayHelloFour(Date date);
}
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
@Stateless
@Remote(HelloWorldService.class)
@WebService(name = "HelloWorldService", serviceName = "HelloWorldServiceImpl",
targetNamespace = "http://cn.edu.nju.software", portName = "HelloWorldPort")
public class HelloWorldServiceImpl implements HelloWorldService {
@WebMethod(exclude = true)
public String getHelloWorld(String content){
return "Hello World: "+content;
}
@Override
public List<Person> sayHelloOne(Person person) {
// TODO Auto-generated method stub
Person personA = new Person();
personA.setName(person.getName()+"Hello");
personA.setAge(person.getAge()+4);
List<Person> list = new ArrayList<Person>();
list.add(person);
list.add(personA);
return list;
}
@Override
public Person sayHelloTwo(Person person) {
// TODO Auto-generated method stub
Person personA = new Person();
personA.setName(person.getName()+"Hello");
personA.setAge(person.getAge()+4);
return personA;
}
@Override
public Boolean sayHelloThree(Boolean isRight) {
// TODO Auto-generated method stub
if(isRight){
return false;
}
return true;
}
@Override
public Date sayHelloFour(Date date) {
// TODO Auto-generated method stub
System.out.println(date.toString());
return new Date(0);
}
}
标记好注释之后,利用myeclipse自带的工具生成webservice以及wsdl文件。
-------------------------------------------------------------------------------------------------------------------------------
在客户端创建自定义实体类Person,属性(名称,类型)都要和服务端的相同,该实体类还需要实现KvmSerializable接口,以便顺利地将其传输给JAX-WS服务端的webservice,详细代码如下:
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) {
// TODO Auto-generated method stub
switch(arg0){
case 0:
return name;
case 1:
return age;
}
return null;
}
@Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 2;
}
@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
// TODO Auto-generated method stub
switch(index)
{
case 0:
info.type = PropertyInfo.STRING_CLASS;
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) {
// TODO Auto-generated method stub
switch(index)
{
case 0:
name = value.toString();
break;
case 1:
age = Integer.parseInt(value.toString());
break;
default:
break;
}
}
}
接下来是android端利用ksoap2与webservice进行通信的详细介绍(最主要的部分),先贴上详细代码:
//首先创建自定义对象并包装到PropertyInfo 中;也可以直接被request.addProperty,注意第一个设置参数名的参数内容必须和服务端方法的wsdl中参数名相同,这里是arg0
Person person = new Person();
person.setName("Android;Android:Android");
person.setAge(7);
PropertyInfo pi = new PropertyInfo ();
pi.setType(Person.class);
pi.setValue(person);
pi.setName("arg0"); //必须和服务端方法的wsdl中参数名相同
String wsdl = "http://IPAddress:8080/HelloWorldService/HelloWorldServiceImplPort?wsdl";
String namespace = "http://software.nju.edu.cn/";
String webmethod = "sayHelloOne";
String soapAction = namespace+webmethod;
SoapObject request = new SoapObject(namespace, webmethod);
request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = false; //由于不是用dotNet做服务端,需设置为false。
envelope.setOutputSoapObject(request);
envelope.addMapping(namespace, "Person", Person.class);
//ksoap2传递自定义类型对象的属性中如果有除了Boolean、Integer和String以外类型的属性时,需要在envelope中注册相应的Marshal
//Marshal dateMarshal = new MarshalDate();
//dateMarshal.register(envelope);
HttpTransportSE ht = new HttpTransportSE(wsdl);
String response = "";
//设置为true,方便之后读取信息,如 ht.requestDump和ht.responseDump
ht.debug = true;
try {
ht.call(soapAction, envelope);
if(envelope.getResponse()!=null){
List<Person> list = new ArrayList<Person>();
SoapObject rpsObject = (SoapObject) envelope.bodyIn;
int numOfList = rpsObject.getPropertyCount();
for(int i=0;i<numOfList;i++){
SoapObject tmpSoapObject = (SoapObject)rpsObject.getProperty(i);
list.add((Person)CastObject.parseToObject(tmpSoapObject, Person.class));
}
for(Person obj:list){
response += "name: "+obj.getName()+" age: "+obj.getAge()+"\n";
}
}catch (IOException e){
// TODO Auto-generated catch block
response += e.getMessage();
} catch (XmlPullParserException e){
// TODO Auto-generated catch block
response += e.getMessage();
}catch (Exception e){
// TODO Auto-generated catch block
response += e.getMessage();
}
response += "\nRequest: ";
response += ht.requestDump;
response += "\nResponse: ";
response += ht.responseDump;
自定义方法parseToObject,详细代码如下:
public class CastObject {public static KvmSerializable parseToObject(SoapObject soapObject, Class objectClass) throws IllegalAccessException, InstantiationException{
KvmSerializable result = (KvmSerializable) objectClass.newInstance();
int numOfAttr = result.getPropertyCount();
for(int i=0; i<numOfAttr; i++){
PropertyInfo info = new PropertyInfo();
result.getPropertyInfo(i, null, info);
//处理property不存在的情况
try{
result.setProperty(i, soapObject.getProperty(info.name));
}catch(Exception e){
continue;
}
}
return result;
}
}
在经过多次试验之后还发现了envelope.getResponse()和envelope.bodyIn的区别,请读者注意:
envelope.getResponse()是取单条记录;当遇到多条记录时,用envelope.bodyIn,然后用(SoapObject)object.getProperty(i) 取每条记录。
- Ksoap2 与 JAX-WS 相互传送自定义类
- KSoap2 调用JAX-WS
- JAX-WS与JAX-RPC
- JAX-WS与JAX-RPC
- JAX-RPC 与 JAX-WS
- JAX-WS与JAX-RS
- JAX-RPC 与 JAX-WS 的比较
- JAX-RPC 与 JAX-WS 的比较
- JAX-WS与JAX-RS区别是什么
- JAX-WS与JAX-RS区别是什么?
- Axis2 与 JAX-WS规范
- JAX-WS 与XFire比较
- JAX-WS 与XFire比较
- AX-WS与JAX-RPC
- JAX-WS
- JAX-WS
- JAX-WS
- JAX-WS
- .NET发送邮件
- android api 中文 (75)—— AdapterView.OnItemClickListener
- 解决WINDOWS7下打开VC6错误
- android TabHost小结
- 超强JSP防SQL注入攻击
- Ksoap2 与 JAX-WS 相互传送自定义类
- 如何将TabBar放置底部?
- 自定义Toast、程序退出时Toast也退出、Toast的用法
- Python模块包中__init__.py文件的作用
- 哈希聚簇读取(Hash Cluster Access)[摘]
- Fortran 90学习之旅(一)Compaq Visual Fortran 6.5 的安装与第一个例子
- Android Handler总结
- IBM websphere MQ v6.0配置过程
- build uboot