BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

扩展Axis2框架,支持基于JVM的脚本语言

| 作者 Heshan Suriyaarachchi 关注 0 他的粉丝 ,译者 王丽娟 关注 0 他的粉丝 发布于 2010年9月8日. 估计阅读时间: 14 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

本文介绍了如何扩展Axis2框架,以支持Jython、JRuby等基于Java虚拟机(JVM)的脚本语言。文章对这一主题进行了高层次概述,包括Apache Axis2的一些关键概念,以及如何利用Axis2为基于JVM的脚本语言提供扩展。读完此文,开发人员可以扩展Axis2框架,来支持基于JVM的脚本语言。Axis2框架扩展之后,可以轻松做到如下两点:

  1. 将脚本开发为Web服务。
  2. 用所选的脚本语言编写服务客户端。

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服务的实现方法

Web服务是构建面向服务的体系架构(SOA)的一组技术。尽管SOA和Web服务之间的关系通常很容易混淆,但Web服务是一种实现技术,它采用标准协议来执行SOA,理解这一点很重要。开发Web服务的技术中,使用较为广泛的两种是代码优先和契约优先:

使用代码优先的方法,主要关注点是给出代码;你要先编写Java代码,再根据Java代码生成Web服务契约(WSDL)。相比之下,契约优先强调的则是服务契约;你先编写WSDL契约,然后使用Java或代码生成工具实现该契约。契约优先的方法有一些好处,它能促进:

  • 应用之间的松散耦合
  • 多个服务之间的互操作性
  • 抽象的使用,从而隐藏底层的实现细节
  • 所有参与方之间的协作和一致的达成

代码优先的方法则有如下优势:

  • 简单、省时
  • 能将遗留系统暴露为Web服务
  • 不用深入了解WSDL的相关知识

这就是说,在设计服务契约时,你可以在代码优先和契约优先两种技术中择其一。最终的决定则取决于你是更想确保互操作性,还是更想提高生产力。本文将展示如何扩展Apache Axis2,使其对两种方式都进行支持。

扩展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含有一个代码生成模块——Axis2代码生成器(Axis2 Code Generator)。代码生成器能合并多个数据绑定框架,而且易于扩展。因此代码生成工具可以进行扩展,以支持脚本语言。在深入扩展工具的细节之前,让我们先看看Axis2的代码生成器。

考量SOAP处理引擎时,一个关键的附加价值就是基于WSDL的代码生成。代码生成要能:

  1. 为用户提供方便——代码生成工具要帮助用户以简单、有效的方式使用框架。
  2. 充分利用框架。

现在来看看Axis2代码生成器的架构。

工具的架构非常简单。核心部分会处理WSDL文件、生成对象模型。然后根据模板解析生成的对象模型、生成源代码。

扩展Axis2的代码生成器,从而支持脚本语言

代码生成引擎逐个调用扩展,最终会调用组件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消息来说,前面所述的过程都会执行一遍。

如何部署Jython服务

部署时,Axis2引擎会读取Jython脚本的注解,并完成动态Jython类型到静态Java类型的映射。这一过程称为数据绑定。相应的匹配类型映射完成之后,会创建服务的XML Schema。下面的步骤描述了如何生成Jython服务的XML Schema:

  1. 读取Jython服务的注解。
  2. 为Jython服务创建AxisService。
  3. 给每个Jython方法创建一个AxisOperation。
  4. 给操作增加AxisMessage。AxisMessage包含方法参数的类型。
  5. 将所有AxisOperation添加到AxisService中。
  6. 最终为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


感谢沙晓兰对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT