Ksoap的使用详解Word下载.docx

上传人:b****6 文档编号:16517596 上传时间:2022-11-24 格式:DOCX 页数:15 大小:40.63KB
下载 相关 举报
Ksoap的使用详解Word下载.docx_第1页
第1页 / 共15页
Ksoap的使用详解Word下载.docx_第2页
第2页 / 共15页
Ksoap的使用详解Word下载.docx_第3页
第3页 / 共15页
Ksoap的使用详解Word下载.docx_第4页
第4页 / 共15页
Ksoap的使用详解Word下载.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

Ksoap的使用详解Word下载.docx

《Ksoap的使用详解Word下载.docx》由会员分享,可在线阅读,更多相关《Ksoap的使用详解Word下载.docx(15页珍藏版)》请在冰豆网上搜索。

Ksoap的使用详解Word下载.docx

接口

org.ksoap2.SoapEnvelope

org.ksoap2.SoapSerializationEnvelope:

序列化

org.ksoap2.SoapObject:

SOAP调用

org.ksoap2.transport.HttpTransport

SoapEnvelope对应于SOAP规范中的SOAPEnvelope,封装了head和body对象。

SoapSerializationEnvelope是kSOAP2新增加的类,是对SoapEnvelope的扩展,对SOAP序列化(Serialization)格式规范提供了支持,能够对简单对象自动进行序列化(simpleobjectserialization)。

而kSOAP1.x则是通过org.ksoap.ClassMap来做序列化的,不太好操作,也不利于扩展。

SoapObject让你自如地构造SOAP调用;

HttpTransport为你屏蔽了Internet访问/请求和获取服务器SOAP的细节。

 

下面我们通过一个最简单的webservice调用,来看看kSOAP是如何做到SOAP解析的:

2.1.kSOAP和WebService之间传递String

webservice传递String给MIDP是一件很简单的事情。

首先在服务器端,不管你是用MicrosftASP.NET创建webservice,还是由Tomcat+AXIS1.2支撑的webservice,都可以这么编写主服务类:

服务器端

publicclassSimpleKSoapWS{

publicSimpleKSoapWS(){

}

publicStringfoo(Stringusername,Stringpassword){

return“fooResult”;

}

kSOAP是如何调用这个webservice的呢?

首先要使用SoapObject,这是一个高度抽象化的类,完成SOAP调用。

可以调用它的addProperty()方法填写要调用的webservice方法的参数。

如下面代码所示:

SoapObjectrequest=newSoapObject(serviceNamespace,methodName);

SoapObject构造函数的两个参数含义为:

serviceNamespace–你的webservice的命名空间,既可以是

//localhost:

8088/flickrBuddy/services/Buddycast这样的,也可以是

urn:

PI/DevCentral/SoapService这样的;

methodName–你要调用方法的名字。

然后,按照webservice方法参数的顺序,依次调用

request.addProperty("

username"

"

user"

);

password"

pass"

来填充webservice参数。

注意:

建议webservice的方法传递的参数尽量用string类型。

即使是int类型,kSOAP2与Java编写的webservice也有可能交互发生异常。

对于webservice方法返回String类型的情况,还用不着开发者做序列化(Serialization)定制工作。

要点:

kSOAP1.X/2.0可以自动把四种SOAP类型映射为Java类型

SOAPtypeJavatype

xsd:

intjava.lang.Integer

longjava.lang.Long

stringjava.lang.String

booleanjava.lang.Boolean

除此之外,都需要开发者自己做类型映射。

然后要告诉SoapSerializationEnvelope把构造好的SoapObject封装进去:

SoapSerializationEnvelopeenvelope=

newSoapSerializationEnvelope(SoapEnvelope.VER11);

envelope.bodyOut=request;

你可以通过SoapSerializationEnvelope或者SoapEnvelope的构造函数来指明你要用SOAP的哪一个规范,可以是以下几种之一:

常量SoapEnvelope.VER10:

对应于SOAP1.0规范

常量SoapEnvelope.VER11:

对应于SOAP1.1规范

常量SoapEnvelope.VER12:

对应于SOAP1.2规范

这样,无论要调用的webservice采用了哪一个SOAP规范,你都可以轻松应对。

接下来就要声明

HttpTransporttx=newHttpTransport(serviceURL);

ht.debug=true;

HttpTransport构造函数的参数含义为:

serviceURL–要投递SOAP数据的目标地址,譬如说

HttpTransport是一个强大的辅助类,来完成Http-calltransportprocess,它封装了网络请求的一切,你完全不用考虑序列化消息。

我们通过设置它的debug属性为true来打开调试信息。

方法HttpTransport.call()自己就能够发送请求给服务器、接收服务器响应并序列化SOAP消息,如下所示:

ht.call(null,envelope);

HttpTransport的call方法的两个参数含义为:

soapAction–SOAP规范定义了一个名为SOAPAction的新HTTP标头,所有SOAPHTTP请求(即使是空的)都必须包含该标头。

SOAPAction标头旨在表明该消息的意图。

通常可以置此参数为null,这样HttpTransport就会设置HTTP标头SOAPAction为空字符串。

Envelope–就是前面我们构造好的SoapSerializationEnvelope或SoapEnvelope对象。

对于HttpTransport的处理上,kSOAP2和kSOAP1.2的写法不一样。

对于kSOAP1.2,HttpTransport的构造函数是HttpTransport(Stringurl,StringsoapAction),第二个参数soapAction可以是要调用的webservice方法名。

而kSOAP2,构造函数是HttpTransport(Stringurl)。

kSOAP2相当于把webservice方法名分离出去,完全交给SoapObject去封装,而HttpTransport仅仅负责把SoapEnvelope发送出去并接收响应,这样更合理一些。

调用call方法是一个同步过程,需要等待它返回。

返回之后,就可以调用SoapSerializationEnvelope的getResult方法来获取结果了:

ObjectResponse=envelope.getResult();

如果HttpTransport的debug属性为true,那么此时就可以通过

System.out.println("

Responsedump>

>

"

+tx.responseDump);

打印出HttpTransport的调试信息。

尤其当前面call方法和getResult方法发生异常时,这个调试信息是非常有用的。

前面我们的webservice方法由于是返回string,所以得到这个string值就非常简单了:

StringsResponse=Response.ToString();

由于HttpTransport类实际上是调用了HttpConnection作网络连接,所以必须另起一个线程来专门做kSOAP工作,否则会堵塞操作。

综上所述,J2ME客户端的MIDlet按键事件函数这么写即可:

MIDletcodes

importorg.ksoap2.SoapEnvelope;

importorg.ksoap2.serialization.SoapObject;

importorg.ksoap2.serialization.SoapSerializationEnvelope;

importorg.ksoap2.transport.HttpTransport;

publicvoidcommandAction(Commandc,Displayables){

if(c==exitCommand)

{

destroyApp(false);

notifyDestroyed();

}

if(c==connectCommand)

//匿名内部Thread,调用kSOAP2访问远程服务。

ThreadwebserviceThread=newThread(){

publicvoidrun(){

try{

StringserviceNamespace="

8080/SimpleWS/services/SimpleKSoapWS"

;

StringmethodName="

foo"

StringserviceURL="

SoapSerializationEnvelopeenvelope=newSoapSerializationEnvelope(SoapEnvelope.VER11);

envelope.bodyOut=request;

HttpTransportht=newHttpTransport(serviceURL);

/*

*必要时打印出tx.responseDump来观察soap是否正确工作*/

dump>

StringsResponse=Response.ToString();

}

catch(Exceptione){e.printStackTrace();

};

webserviceThread.start();

2.2.webservice返回复杂描述的情况

kSOAP2处理webservice简单的string类型返回值是很容易的。

那么如何处理像亚马逊网上书店这种webservice返回的复杂描述呢?

kSOAP2自带了一个例子来说明,下面我们就讲解一下。

关于亚马逊的查询书目的webservice,你可以通过

来获知定义。

我们要关注的是它的关键词查询请求的方法,它的定义是:

<

operationname="

KeywordSearchRequest"

<

soap:

operationsoapAction="

/>

input>

bodyuse="

encoded"

encodingStyle=http:

//schemas.xmlsoap.org/soap/encoding/namespace="

<

/<

font>

output>

operation>

我们提交对包含指定关键词的书目查询,如果查询成功,将会返回一系列书名节点,每一本书都提供了作者、出版社、出版日期、价格等等信息。

这些书名节点都在一个“Details”节点下。

查询结果的总数放在TotalResults节点。

每页10个结果,可以通过查看TotalPages节点来确定需要多少页。

那么,kSOAP2可以很简单地通过SoapObject的getProperty方法来得到书详细信息的节点,存储入一个Vector对象中,如下所示:

HttpTransportht=newHttpTransport("

SoapObjectresult=(SoapObject)envelope.getResult();

VectorresultVector=(Vector)result.getProperty("

Details"

);

Vector对象中实际上还是存储了一组SoapObject对象,这里的每一个SoapObject对象对应于一本书的DOM对象。

那么如何得到每一本书的书名、价格呢?

for(inti=0;

i<

resultVector.size();

i++){

SoapObjectdetail=(SoapObject)resultVector.elementAt(i);

System.out.println("

书名>

+(String)detail.getProperty("

ProductName"

));

日期>

ReleaseDate"

价格>

ListPrice"

这样就可以了。

需要注意的是,要测试这个工程,必须到亚马逊的注册获取AccessKeyID,也就是webservice方法中的“devtag”参数所需要的Developer-Tag。

2.3.webservice传递自定义复杂对象

下面我们讲述如何在MIDP设备和webservice之间传递自定义类,比如这个类中不但有String类型成员变量,还有Vector之类的复杂类型。

大致思路就是,在服务器端将类实例按照一定规格(一个一个的成员变量写)序列化为byte[],将这个byte[]数组返回给kSOAP2。

kSOAP2收到之后,再反序列化,将byte[]一段一段地读入类实例。

2.3.1.webservice服务器端的做法

我们先来定义要传递的wsTeam类:

类定义

publicclasswsTeam{

privateStringwsReturnCode;

privateStringwsPersonCount;

publicStringVectorwsvPersonName;

publicbyte[]serialize();

publicstaticwsTeamdeserialize(byte[]data);

其中,StringVector类是另外一个自定义类,就是简单地把String[]封装了一下,便于操作。

StringVector类定义在示范代码中可以找到。

服务器端主要是序列化,所以我们来讲讲wsTeam的serialize()函数。

wsTeam的序列化函数

publicbyte[]serialize(){

ByteArrayOutputStreambaos=newByteArrayOutputStream();

DataOutputStreamdos=newDataOutputStream(baos);

try

{

dos.writeUTF(wsReturnCode);

dos.writeUTF(wsPersonCount);

wsvPersonName.writeObject(dos);

baos.close();

dos.close();

}

catch(Exceptionexc)

exc.printStackTrace();

returnbaos.toByteArray();

这样,类实例就可以把自己序列化为byte[]数组。

那么,webservice可以这么提供:

publicbyte[]foo2(Stringusername,Stringpassword){

wsTeamobj=newwsTeam();

returnobj.serialize();

到了MIDP设备上,要能够从byte[]恢复出wsTeam类实例才行。

StringVector的序列化方法writeObject也很简单,先写入字符串数组的大小,然后再将每一个元素写入,如下所示:

StringVector的序列化

publicclassStringVector

{…

publicsynchronizedvoidwriteObject(java.io.DataOutputStreams)

throwsjava.io.IOException

//Writeoutarraylength

s.writeInt(count);

//Writeoutallelementsintheproperorder.

for(inti=0;

i

s.writeUTF(data[i]);

2.3.2.MIDP设备的做法

和前面的MIDlet代码差不多,只不过要kSOAP2的MarshalBase64出场了。

在kSOAP中,我们用Base64把二进制流编码为ASCII字符串,这样就可以通过XML/SOAP传输二进制数据了。

org.ksoap2.serialization.MarshalBase64的目的就是,把SOAPXML中的xsd:

based64Binary元素序列化为Java字节数组(byetearray)类型。

类似的,kSOAP2还提供了MarshalDate、MarshalHashtable类来把相应的元素序列化为Java的Date、Hashtable类型。

使用MarshalBase64

importorg.ksoap2.serialization.MarshalBase64;

SoapObjectrequest=newSoapObject(serviceNamespace,methodName);

newSoapSerializationEnvelope(SoapEnvelope.VER11);

newMarshalBase64().register(envelope);

HttpTransporttx=newHttpTransport(serviceNamespace);

tx.debug=true;

tx.call(null,envelope);

将接收到的SoapObject强制转换为byte[]。

转换

byte[]by=(byte[])Response;

succconvert!

然后,再调用

反序列化

wsTeamwc=wsTeam.deserialize(by);

这样,在无线设备

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1