SOAP::Lite简介

ZDNet软件频道 时间:2002-03-24 作者:ZDNET CHINA 特稿 |  我要评论()
本文关键词:SOAP
选择合适的SOAP工具包通常是个费力的任务。Web服务还是项相当年轻的技术,各种工具包为各类Web服务标准提供了不同层次的支持。所以选择自己满意的利器就必须看得清、辨得明。

选择合适的SOAP工具包通常是个费力的任务。Web服务还是项相当年轻的技术,各种工具包为各类Web服务标准提供了不同层次的支持。所以选择自己满意的利器就必须看得清、辨得明。

对Perl开发人员来说却不妨考虑一下SOAP::Lite。这是一款免费的Perl模块,由Pavel (Paul) Kulchenko编写,在业内已经得到了普遍欢迎而且日益成为市场上最具竞争性的工具包之一。虽然这种工具包用起来确实非常方便,但是,毕竟这是一个刚崭露头角的程序模块。其文档也还很不完善,代码里潜伏的一些bug时不时地就会跳出来捣乱。

本文对采用SOAP::Lite 工具包创建SOAP 客户程序进行了经验性的说明。我会阐述一些在使用这一工具包所遇到的一些问题,以及从使用中学到的一些经验、教训乃至喜好等。

服务细节

这里用到的例子采用了我在XMethods上发现的horoscope服务。我选用这一服务的目的是为了简化其接口,这样,在粘贴一个消息作为测试之后就可以证明这不是一个一般性的说明而是确实可以起作用的服务。该服务是一项RPC风格的Web服务,只支持一种方法:getHoroscope。我不打算把事情弄得太复杂而让大家陷入细节的泥沼;我们的出发点是学习SOAP::Lite的基本要点,这才是最重要的。

程序清单A 对接口的简化进行了说明。这是对Horoscope Web服务的请求/响应。

客户程序细节
现在就让我们仔细分析一下SOAP::Lite。正如你看到的那样,SOAP::Lite API相当简单。事实上,你只需要在客户程序中编写几行代码就可以组织、粘贴和接收对SOAP消息的响应了。在 程序清单B就举了一个简单的例子。

在程序清单B的第2行,uri() 子程序标识了SOAP体的名称空间。在第3行上,proxy()子程序指定了粘贴消息的目标URL。在第4行,用户用远程Web服务所使用的名字调用一个方法。该行实际上促使SOAP::Lite把你建立的SOAP消息传递给了Web服务。最后,第5行的result()子程序返回响应对象。

SOAPAction HTTP 头

许多Web服务都需要,或者说至少必须实现SOAPAction头。SOAPAction头的作用就是表达消息中正被调用的方法以便作为接收者的服务一方可以确定指定的句柄而不必解析SOAP XML。

horoscope客户程序没有采用SOAPAction头,但是我打算说明一下如何重载SOAP::Lite SOAPAction头默认行为的方法。采用on_action() 子程序,你就可以重载SOAP::Lite给SOAPAction头建立的默认行为。只需要创建一个匿名(或命名)的子程序,同时把它作为参数传递给on_action()即可。该子程序返回的值就可以用作SOAPAction HTTP头了。程序清单C对这一用法进行了说明。

嵌套的SOAP Body元素

SOAP::Lite创建复杂的SOAP体是相当简单的,只不过你无法从文档中了解到具体的详情。我设法完成了这一工作,方法是给SOAP::Lite邮件列表发了个求助消息,总有人会帮忙的。

为了让你知道最终实现可用的解决方案所需要的信息,我采取了好几个措施让你经历这一过程。我对这些步骤进行了大致的说明,包括如何构造一个嵌套三层元素的方法调用。

以下是我创建的方法调用:
<getHoroscope>
<astrology>
<sign>Aries</sign>
</astrology>
</getHoroscope>


初看起来,我好象并没有说明自己是如何构造的。好,让我们假设这个方法调用是下面的样子:
<getHoroscope>
<sign>Aries</sign>
</getHoroscope>


构造这个SOAP::Lite方法调用则很简单了(从SOAP::Lite手册上可以直接得到这个例子)。程序清单D显示了方法调用的示例。

当然,接口会要求“astrology”元素。我认为,从接口的角度看这是不明智的,我的第1个想法是嵌入SOAP::Data 元素,如程序清单E所示。

以上代码产成的SOAP Body在程序清单F中显示。

注意到没有,“astrology”元素不知何故被“吞没”了。为了解决这个问题我编写了程序清单G中的代码(注意方括号表示数组)。

以上的代码真正的实现了封闭但却令SOAP::Lite把嵌套的元素作为数组进行了串行化,结果让另一端的Web服务不知所云。这一细节实际上演示了SOAP::Lite一个相当精彩的方面:它有能力把Perl变量串行化为SOAP::Data数据类型。产生的代码见程序清单H

我用花括号作了同样的逻辑尝试,正如我期望的那样,SOAP::Lite把SOAP Body串行化为哈系数组。当然,这也不是我希望得到的结果,叫我万分恼火。为了弄清真相,我搜遍了网络和各种SOAP::Lite perl文档也没有找到什么能帮得上忙的东西。

仔细一想也许我需要创建自己的SOAP::Serializer或者类似的东西,从在线文档的说明来看。这应该是一个很困难的任务。在走投无路的情况下我给邮件列表发信求助。我得到的第1个回应(只有不到几分钟的时间)建议我生成程序清单I中的代码。

可是,这样做并没有帮助我实现目标。但它也确实给我展示了另一个出色的特性。SOAP::Lite可以把哈系数组串行化为SOAP Struct,而且演示结果表明,创建这种元素类型真是简单。清单I中的代码产生的输出见清单J

正如你看到的那样,现在离我目标又前进了一步—嵌套元素至少没有串行化为数组或者哈系数组。但是,现在又弄出个奇怪的“c-gensym3”元素。很幸运,邮件列表里的下一个回应解决了以上的问题。

最后一招

必须指出,我的第1次尝试是正确的,只是有一点小问题:嵌套SOAP::Data之前的斜线符号,这个可以从清单K中显示的结果看出来。这只不过让你看到SOAP::Lite 比你想象的更富意味,假如你比较熟悉Perl而且有耐心深入研究源代码就会认识到这一点了。

更复杂的数据结果

好,终于明白该如何令SOAP::Lite输出希望的结果了。那么更复杂的结构又是怎样一说呢?既然你明白这个道理了,就让我们快速地看看另一个例子了解得更清楚一些。 程序清单L创建了假设的SOAP Body。

清单M 中的代码是实现清单L显示的输出结果所必需的。

小结

SOAP::Lite是一种相当强大的工具包。它是实现和支持 SOAP 1.2版的为数不多的工具包之一,照我的经验看,你采用它可以很快地在服务器和客户机环境下建立和运行Web服务。即便如此,SOAP::Lite也还存在一些问题。在撰写本文的时候,最新版本的SOAP::Lite是0.52,这个版本修改了一些bug。可惜的是,发布版等老半天都冒不出来一个。有关的文档倒是写得很棒,而且这还是一个人编写的!希望能有更多的软件文档和示例促使SOAP::Lite变得更加好用。

责任编辑:炒饭

百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134