首页 > 开发 > 综合 > 正文

SOAP净化有线协议(三):用脚本语言编写服务

2024-07-21 02:21:50
字体:
来源:转载
供稿:网友
  你是一个渴望永远站在技术最前沿的java开发者吗?软件产业风云变幻,你渴望把握web的未来,更重要的是,如何把自己数年的java经验发挥到极致。要寻找这些问题的答案,你不必走得太远,答案就在于soap。

soap(简单对象访问协议)是一种利用xml编码数据的有线协议,它为java的平台无关性、可移植性带来了更高层次的协同操作能力。在这个关于soap的系列文章的第二篇中,我介绍了apache soap。作为soap规范的实现之一,apache soap简化了soap应用的构造。我们曾经用apache soap构造了两个简单的helloworld服务,以及调用这些服务的sayhelloto()方法的客户程序。我们看到,虽然创建soap服务相当简单,但客户程序必须完成许多额外的工作,例如它必须设置call对象,调用call对象的invoke()方法,然后分析作为调用结果返回的response对象。

其实,用apache soap创建soap服务的过程还可以变得更简单,唯一的前提是:你必须懂得规定的几种脚本语言之一。对我来说——以及对大多数java开发者来说,幸运的是,这些脚本语言中包含了javascript。确实不错,在apache soap中,你可以用javascript创建soap服务。本文要介绍的就是用javascript创建soap服务的具体做法。

一、重新构造apache soap
apache soap的脚本支持建立在bean scripting framework(bsf,bean脚本框架)的基础之上。bsf原先由ibm开发,现在作为一个源代码开放的工程发行,它使得java程序能够运行用其他语言编写的脚本,也使得其他脚本语言能够使用已有的java类。apache soap利用了bsf的前一种能力。从apache网站下载的标准二进制版本不支持脚本。具体地说,soap.jar不包含org.apache.soap.server.invokebsf类,而这个类是apache soap和bsf的结合点和接口。apache soap的开发者知道,并非每一个使用soap的人都需要bsf,也并非每一个人都安装了脚本引擎,所以在soap.jar中省略了脚本支持。要想用脚本编写soap服务,你必须从源代码重新构造以便引入invokebsf类。

首先要从http://xml.apache.org/dist/soap/下载源代码(soap-src-2.0.zip)。然后,把下载得到的文件解压缩到apache soap所安装的目录。在我这里,它是e:驱动器的根目录。完成后,你将在soap_2-0目录下得到一个src子目录,子目录中包含apache soap的所有源代码。重新从源代码构造apache soap之前,你还必须下载必需的bsf jar文件。在ftp://ftp.mozilla.org/pub/js/可以找到一个。请结合mozilla的javascript引擎rhino使用它,rhino可以从http://www.mozilla.org/rhino/download.html下载一个zip文件得到。我把这个文件解压缩到e:盘根目录下,最终得到一个包含了rhino的e:/rhino目录,我们感兴趣的是它的js.jar。

接下来,你需要一个实际执行重新构造操作的工具,即ant。ant也是一个apache的软件工程,它是一个基于java的工具。ant实际上和创建web服务器tomcat的工程同属一个工程,即jakarta。在ant中,所有构造信息,例如构造目标、依赖关系等,都通过xml配置文件指定,这是ant独一无二的特点。此外,ant是可扩展的。请参见本文最后“参考资源”部分收录的文章,了解如何充分发挥ant的潜能。你可以从参考资源提供的链接下载ant,然后解开压缩(我把它放入了c:盘的根目录)。

现在,从apache soap安装目录执行如下命令:


set
classpath=e:/jakarta-tomcat/lib/servlet.jar;e:/xerces-1_2_0/xerces.jar;
e:/soap-2_0/lib/bsf.jar
c:/build/bin/ant
由于上面的命令没有指定一个xml配置文件,ant批命令文件将在当前目录(在我这里,是e:/soap_2-0)中寻找一个名为build.xml的文件。apache soap提供了这个文件。打开这个文件可以看到,只有当com.ibm.bsf.bsfmanager在classpath中时,invokebsf类才会编译。这就是我把bsf.jar(它包含了bsfmanager类)放入类路径的原因。把新构造出来的soap.jar文件从build/lib子目录复制到lib子目录(我建议修改原来的soap.jar文件进行备份)。最后,把bsf.jar和js.jar加入到web服务器的类路径。

大功告成!现在你可以开始用脚本编写soap服务了。

二、用javascript编写helloworld应用
现在,我们用javascript重新编写第二篇文章的helloworld服务。服务程序的完整代码如下:


function sayhelloto(name)
{
return "hello " + name + ", how are you?";
}
还有比这更容易的事情吗?不过,不要让这简单易行欺骗了你。事实上,你可以在服务程序里进行相当复杂的处理。例如,你可以从脚本代码访问任何标准的java类。请看下面经过修改的脚本代码,它输出服务器的时间:


function sayhelloto(name)
{
var today = new java.util.date();
java.lang.system.out.println("today is " + today.tostring());
return "hello " + name + ", how are you?";
}
另外,你还可以导入和使用自己的任意java类。例如,我们可以修改脚本代码,让它使用name javabean:


importclass(packages.hello.name);
function sayhelloto(name)
{
var today = new java.util.date();
java.lang.system.out.println("today is " + today.tostring());
var beanname = new name();
beanname.setname("john");

java.lang.system.out.println(beanname.getname());
return "hello " + name + ", how are you?";
}
三、部署服务
在使用javascript版本的服务之前,首先要部署它。正如本系列文章的第二篇所介绍的,在apache soap中部署服务有两种办法:使用web界面的管理工具,或者从命令行部署服务。下面我们来看看两种办法的具体操作过程。

3.1 使用web界面的管理工具
要使用web界面的管理工具,用浏览器打开http://localhost:8080/apache-soap/admin。点击窗口左边的deploy按钮。记住,id输入框用来设置对象id,soap基础设施利用对象id把rpc(远程过程调用)请求关联到soap服务。每一个apache soap服务都必须有一个对象id,而且这个对象id必须在该服务器上部署的所有服务之间唯一。把id设置成urn:hello,这个id也就是我们在第二篇文章中为服务设置的对象id。

把scope输入框设置成application。回顾一下,scope输入框用来指定响应调用请求的服务实例的生存时间(请参考第二篇文章中的更多说明)。

在methods输入框中输入当前部署的服务允许调用的方法名字,多个方法名字之间以空白字符分隔。我们的服务只支持一个方法,即sayhelloto()。

由于服务用javascript实现,而不是象第二篇文章那样用java实现,所以provider type输入框应该填script。相应地,java provider输入框(包括provider class和static输入框)不必填写。但现在必须填写script provider输入框,选择javascript(rhino)作为脚本语言。由于我们将在script文本输入框中提供脚本正文,所以现在不用填写script filename输入框。把下面的脚本代码复制到script输入框:


importclass(packages.hello.name);
function sayhelloto(name)
{
var today = new java.util.date();
java.lang.system.out.println("today is " + today.tostring());
var beanname = new name();
beanname.setname("john");
java.lang.system.out.println(beanname.getname());
return "hello " + name + ", how are you?";
}
现在滚动到屏幕的最下面,点击表单下面的deploy按钮(不是窗口左边的deploy按钮)。要验证服务已经成功部署,点击窗口左边的list按钮。这时,urn:hello服务应该在服务清单中出现。点击这个服务,确认所有信息都与刚才输入的吻合。

3.2 从命令行部署服务
要从命令行部署服务,所有部署信息必须放入一个xml部署描述器文件。下面是我用来部署该服务的xml部署描述器文件:


<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:hello">
<isd:provider type="script" scope="application" methods="sayhelloto">
<isd:script language="javascript">
importclass(packages.hello.name);
function sayhelloto(name)
{
var today = new java.util.date();
java.lang.system.out.println("today is " + today.tostring());
var beanname = new name();
beanname.setname("john");

java.lang.system.out.println(beanname.getname());
return "hello " + name + ", how are you?";
}
</isd:script>
</isd:provider>
</isd:service>
和第二篇文章用到的部署描述器文件相比,这里主要的不同在于把提供者类型设置成了script而不是java。由于这个原因,部署描述器文件不再指定一个java类,而是提供了服务的脚本代码。

部署服务之前应当确保web服务器已经启动。下面的代码显示了如何部署服务:


java org.apache.soap.server.servicemanagerclient
http://localhost:8080/apache-soap/servlet/rpcrouter deploy
deploymentdescriptor.xml
deploymentdescriptor.xml是前面介绍的包含部署描述信息的xml文件。要验证服务已经成功部署,执行下面的命令:


java org.apache.soap.server.servicemanagerclient
http://localhost:8080/apache-soap/servlet/rpcrouter query urn:hello
这时,我们应该看到和deploymentdescriptor.xml文件一样的内容。

四、测试
我们用第二篇文章提供的客户程序client.java来测试helloworld服务。为什么可以用同一个客户程序访问javascript编写的服务呢?因为客户程序完全不会在乎服务用什么语言编写。只要服务能够理解soap请求,能够返回soap应答,客户程序不会关注服务用什么方式实现。回顾一下,下面就是我用来运行hello.client的批命令文件:


set
classpath=e:/soap-2_0/samples/;e:/soap-2_0/lib/soap.jar;
e:/xerces-1_2_0/xerces.jar
java hello.client tarak

观察web服务器的控制台窗口,每次运行客户程序的时候,我们都可以看到当前的日期和输出“john”。

■ 结束语
在这篇文章中,我介绍了apache soap实现所提供的脚本语言支持。为什么说它很重要呢?只要分析一下为何如此流行。在我看来,一个关键的原因在于已经成熟,几乎任何人都能够用html和javascript之类的简单脚本语言构造出复杂的web页面。类似地,在的服务器端,人们可以使用jsp这类易学但强大的脚本语言。我认为这种推理同样适用于soap开发。如果soap想要挺进主流,获得绝大部分人的支持,那么它应该尽量地简化。apache soap加入对脚本的支持正是为了这个目标;它显著地扩展了创建soap服务的开发者的范围。

不过,不要忘了还有另一个因素需要考虑:客户端开发者,即调用soap服务的开发者。如前所述,apache soap的客户端开发者比较“吃亏”,反而增加了一些原本不必做的工作。因此,在本系列文章的下一篇也即最后一篇中,我将介绍一个框架,它以java 2平台1.3版本新引入的动态代理类为基础,使得创建客户程序就象创建soap服务一样简单直观。
■ 参考资源
  • w3c的soap 1.1规范
  • http://www.w3.org/tr/soap/
  • 下载apache soap:
  • http://xml.apache.org/dist/soap/
  • 关于ibm soap工程的更多信息:
  • http://www.alphaworks.ibm.com/tech/soap4j
  • 关于mozilla rhino的更多信息:
  • http://www.mozilla.org/rhino/
  • 关于ant的更多信息:
  • http://jakarta.apache.org/ant/index.html
  • 利用java和ant自动化构造过程(javaword,2001年10月):
  • http://www.javaworld.com/jw-10-2000/jw-1020-ant.html
  • 下载ant:
  • http://jakarta.apache.org/builds/jakarta-ant/release/v1.2/bin/
  • 发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表