Chinaunix首页 | 论坛 | 博客
  • 博客访问: 626370
  • 博文数量: 98
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 1528
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-28 16:20
文章分类

全部博文(98)

文章存档

2011年(1)

2010年(11)

2009年(44)

2008年(42)

我的朋友

分类: Java

2009-03-16 11:59:23

1.概述

对于J2ME访问远端的Web Service,除了官方标准JSR 172,我们还有两种选择:

l         kSOAP

l         Wingfoot

Wingfoot是由Wingfoot Software()出品的一款J2ME(CLDC/CDC) SOAP1.1的轻量级实现方案。

kSOAPEnhydra.org的一个开源作品,是EnhydraME项目的一部分。基于Enhydra.org出品的开源通用XML解析器kXMLkSOAP完成J2ME/MIDP平台上的SOAP解析和调用工作

Stefan Haustein领导的kSOAP开发小组于2001517日推出了Alhpa版本。之后又经过了一年的开发,200266日推出的kSOAP 1.2支持了SOAP1.2规范。2003825日推出的kSOAP2,对SOAP序列化规范支持得更好了。

大多数人选择kSOAP的原因是,kSOAP虽然在20038月之后就不再维护了,但它是Open Source的,很容易加入增强特性,比如说默认情况下kSOAP2仅仅支持cmnet接入点,可以修改kSOAP2HttpTransport.java代码增加对cmwap接入点的支持。

下载提示

kSOAP当前有两个版本:1.22.0

官方网站:

kSOAP2.0还有一个优点是,改进了对Microsoft dotNET的兼容。以前有很多人抱怨kSOAP调用dotNET编写的Web Service时遇到了不少的困扰。

本章节我们将使用kSOAP 2.0的例子来讲解。

为了使用kSOAP 2.0,必须还要下载工具包kXML2

下载提示

kXML当前有两个版本:1.212.0

官方网站:

kXML2kXML更小更快。

2kSOAP2接口

让我们先熟悉一下即将用到的kSOAP2的常用接口。

接口

org.ksoap2. SoapEnvelope

org.ksoap2. SoapSerializationEnvelope

org.ksoap2. SoapObject

org.ksoap2.transport. HttpTransport

SoapEnvelope对应于SOAP规范中的SOAP Envelope,封装了headbody对象。

SoapSerializationEnvelopekSOAP2新增加的类,是对SoapEnvelope的扩展,对SOAP序列化(Serialization)格式规范提供了支持,能够对简单对象自动进行序列化(simple object serialization)。而kSOAP1.x则是通过org.ksoap.ClassMap来做序列化的,不太好操作,也不利于扩展。

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

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

 

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

21kSOAPWeb Service之间传递String

webservice传递StringMIDP是一件很简单的事情。首先在服务器端,不管你是用Microsft ASP.NET创建webservice,还是由Tomcat+AXIS1.2支撑的webservice,都可以这么编写主服务类:

服务器端

public class SimpleKSoapWS {

   

    public SimpleKSoapWS () {

    }

   

    public String  foo(String username, String password) {

        return “fooResult”;

}

}

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

首先要使用SoapObject,这是一个高度抽象化的类,完成SOAP调用。可以调用它的addProperty方法填写要调用的webservice方法的参数。如下面代码所示:

SoapObject request  = new SoapObject(serviceNamespace, methodName);

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

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

这样的,也可以是

urn:PI/DevCentral/SoapService这样的;

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

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

request.addProperty( "username", "user" );

request.addProperty( "password", "pass" );

来填充webservice参数。

注意

建议webservice的方法传递的参数尽量用string类型。即使是int类型,kSOAP2Java编写的webservice也有可能交互发生异常。

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

要点

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

SOAP type           Java type

xsd:int             java.lang.Integer

xsd:long            java.lang.Long

xsd:string         java.lang.String

xsd:boolean         java.lang.Boolean

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

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

SoapSerializationEnvelope envelope =

new SoapSerializationEnvelope(SoapEnvelope.VER11);

envelope.bodyOut = request;

要点

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

常量SoapEnvelope.VER10:对应于SOAP 1.0规范

常量SoapEnvelope.VER11:对应于SOAP 1.1规范

常量SoapEnvelope.VER12:对应于SOAP 1.2规范

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

接下来就要声明

HttpTransport tx = new HttpTransport(serviceURL);

ht.debug = true;

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

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

HttpTransport是一个强大的辅助类,来完成Http-call transport process,它封装了网络请求的一切,你完全不用考虑序列化消息。我们通过设置它的debug属性为true来打开调试信息。

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

ht.call(null, envelope);

HttpTransportcall方法的两个参数含义为:

soapAction – SOAP 规范定义了一个名为 SOAPAction 的新 HTTP 标头,所有 SOAP HTTP 请求(即使是空的)都必须包含该标头。 SOAPAction 标头旨在表明该消息的意图。通常可以置此参数为null,这样HttpTransport就会设置HTTP标头SOAPAction为空字符串。

Envelope – 就是前面我们构造好的SoapSerializationEnvelopeSoapEnvelope对象。

注意

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

对于kSOAP 1.2HttpTransport的构造函数是HttpTransport (String url, String soapAction),第二个参数soapAction可以是要调用的webservice方法名。

kSOAP 2,构造函数是 HttpTransport(String url)kSOAP2相当于把webservice方法名分离出去,完全交给SoapObject去封装,而HttpTransport仅仅负责把SoapEnvelope发送出去并接收响应,这样更合理一些。

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

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

Object Response = envelope.getResult();

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

System.out.println("Response dump>>" + tx.responseDump);

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

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

String sResponse = (String)Response;

注意

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

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

MIDlet codes

import org.ksoap2.SoapEnvelope;

import org.ksoap2.serialization.SoapObject;

import org.ksoap2.serialization.SoapSerializationEnvelope;

import org.ksoap2.transport.HttpTransport;

 

public void commandAction(Command c, Displayable s) {

        if (c == exitCommand)

        {

            destroyApp(false);

            notifyDestroyed();

        }

        if (c == connectCommand)

        {

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

            Thread webserviceThread = new Thread()

            {

                            public void run(){                   

                            try

                            {

                     String serviceNamespace =

 "";

                     String methodName = "foo";

                     String serviceURL =

 "";

 

SoapObject request  =

new SoapObject(serviceNamespace, methodName);

request.addProperty( "username", "user" );

request.addProperty( "password", "pass" );

 

                     SoapSerializationEnvelope envelope =

                  new SoapSerializationEnvelope(SoapEnvelope.VER11);

               envelope.bodyOut = request;

 

              HttpTransport tx = new HttpTransport(serviceURL);

              ht.debug = true;

              ht.call(null, envelope);

              Object Response = envelope.getResult();

/*

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

            */

System.out.println("dump>>" + tx.responseDump);

               String sResponse = (String)Response;                              

                            }

                   catch (Exception e) {

                                  e.printStackTrace ();

                   }

                     }

            };

            webserviceThread.start();

        }

 

阅读(740) | 评论(0) | 转发(0) |
0

上一篇:DWR写个3级联动

下一篇:kSOAP的运用2

给主人留下些什么吧!~~