本文介绍了如何扩展Axis2框架,以支持Jython、JRuby等基于Java虚拟机(JVM)的脚本语言。文章对这一主题进行了高层次概述,包括Apache Axis2的一些关键概念,以及如何利用Axis2为基于JVM的脚本语言提供扩展。读完此文,开发人员可以扩展Axis2框架,来支持基于JVM的脚本语言。Axis2框架扩展之后,可以轻松做到如下两点:
Apache Axis2是开源的Web服务引擎。它对应用广泛的Apache Axis SOAP堆栈进行了彻底的重新设计和编写。Axis2不仅能为Web应用添加Web服务接口,还能作为独立的服务器应用运转。Apache Axis2支持SOAP协议,也支持备受欢迎的REST风格Web服务。使用Axis2,你可以将业务逻辑实现暴露为WS-*风格的接口,与此同时,也可以将该实现暴露为REST/POX风格的接口。
设计JVM的初衷仅仅是为了支持Java编程语言。但随着时间的流逝,越来越多的语言移植到了Java平台,其中包括很多脚本语言。JVM现在支持诸多脚本语言,比如Jython、JRuby、ColdFusion等。简单起见,本文选择了Jython,不过描述的技术同样适用于其他语言。
Jython是Python编程语言的Java实现。它取Java、Python两者之所长,是这两种语言的混合编程。由于Jython是完全用Java编写的,所以用Jython编写的脚本能运行在任何兼容的JVM上,并能使用现有的Java库(这些Java库得是Python模块)。
Web服务是构建面向服务的体系架构(SOA)的一组技术。尽管SOA和Web服务之间的关系通常很容易混淆,但Web服务是一种实现技术,它采用标准协议来执行SOA,理解这一点很重要。开发Web服务的技术中,使用较为广泛的两种是代码优先和契约优先:
使用代码优先的方法,主要关注点是给出代码;你要先编写Java代码,再根据Java代码生成Web服务契约(WSDL)。相比之下,契约优先强调的则是服务契约;你先编写WSDL契约,然后使用Java或代码生成工具实现该契约。契约优先的方法有一些好处,它能促进:
代码优先的方法则有如下优势:
这就是说,在设计服务契约时,你可以在代码优先和契约优先两种技术中择其一。最终的决定则取决于你是更想确保互操作性,还是更想提高生产力。本文将展示如何扩展Apache Axis2,使其对两种方式都进行支持。
Axis2包含一个基于XML的客户端API,功能甚为强大。这个API可用来开发Java服务客户端。现在的需求是用脚本语言编写服务客户端,我们选择Jython进行演示。
要让Jython与Axis2客户端库协作,我们需要开发Axis2客户端API的包装库。开发该包装库的目的是在现有功能主体之上创建一个抽象层。此时,我们要重新定义Axis2客户端API的接口,使其能接受Jython脚本。
上图显示了API的架构。当执行Jython客户端脚本时,会创建并执行一个相映射的Java服务客户端。接着会进行Web服务调用,将结果返回给客户端脚本。要获得更多有关Axis2服务客户端API的信息,请参看这里。
通过客户端API发送SOAP消息时,会激活输出管道(Out Pipe)。输出管道将调用各个处理器,最终由传输发送者(Transport Sender)把SOAP消息发送给目标端点。SOAP消息由传输接收者(Transport Receiver)接收,传输接收者会读取SOAP消息、启动输入管道(In Pipe)。输入管道由一些处理器组成,终端是Jython消息接收者(Message Receiver),Jython消息接收者会消费SOAP消息,并把它交给应用。
下面的代码片段展示了调用Web服务的Jython客户端。
from org.wso2.wsf.jython.client import WSClient from org.wso2.wsf.jython.client import WSFault from org.wso2.wsf.jython.client import WSMessage req_payload_string = "<webSearch><appid>ApacheRestDemo</appid><query>Sri Lanka</query><form/></webSearch>" LOG_FILE_NAME = "/home/heshan/IdeaProjects/MRclient/src/jython_yahoo.log" END_POINT = "http://search.yahooapis.com/WebSearchService/V1/webSearch" try client = WSClient({ "to" : END_POINT, "http_method" : "GET", "use_soap" : "false"}, LOG_FILE_NAME) req_message = WSMessage(req_payload_string, {}) print " Sending OM : " , req_payload_string res_message = client.request(req_message) print " Response Message: " , res_message except WSFault, e: e.printStackTrace();
提到代码生成,Axis2含有一个代码生成模块——Axis2代码生成器(Axis2 Code Generator)。代码生成器能合并多个数据绑定框架,而且易于扩展。因此代码生成工具可以进行扩展,以支持脚本语言。在深入扩展工具的细节之前,让我们先看看Axis2的代码生成器。
考量SOAP处理引擎时,一个关键的附加价值就是基于WSDL的代码生成。代码生成要能:
现在来看看Axis2代码生成器的架构。
工具的架构非常简单。核心部分会处理WSDL文件、生成对象模型。然后根据模板解析生成的对象模型、生成源代码。
代码生成引擎逐个调用扩展,最终会调用组件Emitter。Emitter是代码生成流程中处理重要工作的真正组件。Emitter通常与语言相关,因此语言和Emitter是一一关联的。所以我们要有一个支持Jython代码生成的Emitter。上图说明了这一简单但功能强大的架构。
Emitter处理WSDL、生成对象模型。对象模型只不过是个XML文件,里面包含针对WSDL、关于Axis2信息模型(即Axis服务、Axis操作、Axis消息等)的对象模型。模板是XSLT文件,含有如何生成代码的信息。最后,生成的对象模型会根据模板进行解析、生成Jython源代码。
要支持契约优先的方法,需要为服务生成一个框架、一个消息接收者。已经写好的通用消息接收者运转不了,它只能在有限的Schema结构上运行。我们可以利用Axis2现有的基础设施来做到这一点。Axis2创建了一个表示WSDL的中间XML结构,我们必须根据该XML结构运行两个XSLT文件,来生成框架类和消息接收者。有了这些XSLT文件和代码生成工具,我们就能用Jython支持契约优先的Web服务了。最后,就可以使用消息接收者和框架来编写Jython实现的服务客户端了。
本节将讨论如何将业务逻辑暴露为Web服务。
要在Axis2中暴露Jython实现的Web服务,可以从Axis2可插拔部署器的概念中找找解决方案。为了暴露用Jython编写的服务,我们要编写一个自定义的部署器、一个Jython消息接收者。
消息接收者消费SOAP消息,并把SOAP消息传给应用。消息接收者是输入管道中最后一个处理器。要了解更多关于消息接收者和Axis2架构的信息,请参阅文档。
部署器需要将Jython的数据类型映射到XML Schema数据类型。这个过程称为数据绑定。然后借助数据绑定和方法注解,就能为Jython服务生成XML Schema了。接下来,生成的XML Schema和有关AxisService的元数据都会交给Axis2引擎。Axis2引擎将创建出对应的WSDL,Jython服务也会被暴露为Web服务。如果你想对部署器有更多的了解,我建议你看看文章Axis2部署——自定义部署器。
上图展示了该解决方案的架构。传输监听器(Transport Listener)接收传入的SOAP消息,并将消息传给处理器链。接着,SOAP消息交由Jython消息接收者处理,消息接收者会遍历Axis对象模型(AXIOM)的结构、检索相关的信息。检索到的信息再传递给Jython服务。然后Jython服务开始执行,生成的结果再返回给Jython消息接收者。Jython消息接收者会为返回的Jython对象创建一个AXIOM结构。接下来,响应经由处理器链发送给传输发送者。传输发送者再将响应发送给客户端。对每个交换的SOAP消息来说,前面所述的过程都会执行一遍。
部署时,Axis2引擎会读取Jython脚本的注解,并完成动态Jython类型到静态Java类型的映射。这一过程称为数据绑定。相应的匹配类型映射完成之后,会创建服务的XML Schema。下面的步骤描述了如何生成Jython服务的XML Schema:
生成的AxisService会交给Axis2引擎。最后由Axis2引擎生成WSDL。
Apache Axis2可以以这种方式进行扩展,来支持基于JVM的脚本语言。扩展之后,用户就可以暴露服务、用JVM脚本语言扩展编写服务客户端了。
关于作者
Heshan Suriyaarachchi是WSO2公司的一名软件工程师,是WSO2企业服务总线(ESB)团队的成员。Heshan具备Web服务、SOA、中间件和分布式系统的相关经验。他喜欢打篮球,业余时间还参与开源项目。
他的博客是:http://heshans.blogspot.com/
查看英文原文:How to Extend the Axis2 Framework to Support JVM Based Scripting Languages