写点什么

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

  • 2010-09-07
  • 本文字数:3888 字

    阅读完需:约 13 分钟

本文介绍了如何扩展 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 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2010-09-07 00:003037
用户头像

发布了 151 篇内容, 共 64.7 次阅读, 收获喜欢 18 次。

关注

评论

发布
暂无评论
发现更多内容

在线极限词,敏感词,违禁词查询工具

入门小站

工具

ThreadPoolExecutor 任务提交原码分析

new life

ThreadPoolExecutor

面对DNS劫持,只能坐以待毙吗?

阿里巴巴云原生

阿里云 云原生 云拨测 DNS劫持 产品活动

KubeMeet 深圳站完整议题出炉!快来 get 云原生边缘计算硬核技术干货

阿里巴巴云原生

阿里云 云原生 边缘计算 KubeMeet 线下活动

企业数字化转型与SAP云平台

汪子熙

SAP 11月日更 SAP数字化转型 SAP云平台

GaussDB NoSQL架构设计分享

华为云开发者联盟

nosql 云原生 GaussDB 超融合 多模数据库

时序序列分类算法概述

云智慧AIOps社区

大数据 算法 时间序列 智能运维

博文推荐 | 一文带你看懂 Pulsar 的消息保留和过期策略

Apache Pulsar

架构 云原生 中间件 干货 Apache Pulsar

Podman是什么

耳东@Erdong

容器 11月日更 Podman

Apollo选型及优势介绍

小鲍侃java

11月日更

火出边际的Serverless,你居然还不了解?

华为云开发者联盟

云计算 Serverless 运维 云原生 敏捷

TypeScript 类型系统

HoneyMoose

架构训练营 - 模块四

Geek_9de3de

架构实战营

大数据训练营一期0908作业

朱磊

containerd镜像层过大问题

ilinux

linux实战清理挖矿病毒kthreaddi

入门小站

Linux

flutter开发中vscode插件推荐1

坚果

flutter vscode 11月日更

博文推荐|Pulsar 的消息存储机制和 Bookie 的 GC 机制原理

Apache Pulsar

存储 Apache Pulsar 消息中间件 Apache BookKeeper bookie

到底什么样的ABAP系统能运行Fiori应用

汪子熙

SAP abap Fiori 11月日更

纪念林徽因

TypeScript 是弱类型

HoneyMoose

dart系列之:在dart中使用packages

程序那些事

Java flutter dart 程序那些事 11月日更

CSS奇技淫巧之滤镜

Augus

CSS 11月日更

【Promise 源码学习】第九篇 - Promise.resolve 和 Promise.reject 的实现

Brave

源码 Promise 11月日更

大数据训练营一期0919作业

朱磊

【Flutter 专题】06 图解基础【登录】页面并学习相关 Widget

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

Vue进阶(幺玖幺):ECharts 实现地图功能

No Silver Bullet

Vue eCharts 11月日更

详解低延时高音质:丢包、抖动与 last mile 优化那些事儿

声网

音频体验 RTE技术详解 last mile 优化

版本化ASP.NET Core WebApi

喵叔

11月日更

大数据训练营一期0829作业

朱磊

告诉你!操作系统是个大骗子!

博文视点Broadview

扩展Axis2框架,支持基于JVM的脚本语言_Java_Heshan Suriyaarachchi_InfoQ精选文章