加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Ksoap2 与 JAX-WS 相互传送自定义类

发布时间:2020-12-17 01:01:15 所属栏目:安全 来源:网络整理
导读:本文主要描述了android客户端与PC服务器端,利用webservice和ksoap2插件进行网络通信的传递实体类的方法。网上有好多文章都描述了将android客户端的自定义实体类作为参数传递给webservice中方法的步骤,能够正常的运行。但是当android客户端接收自定义类型时

本文主要描述了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) 取每条记录。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读