Axis2 是下一代的 Apache Axis ,它的体系结构和原来的 Axis1.x 有所不同。它体现出更灵活、有效和可配置性。尽管它的体系结构是新的,但在 Axis1.x 版本下有些良好的概念还是保存下来了,如: handler 在 axis2 中依然保留。
1、 Axis2 所体现的特点有:
Speed :速度快,使用自己的对象模型和 StAX 来解析 achieve 。
Low memory foot print :
AXIOM :使用自己的轻量级对象模型 AXIOM ,用于消息处理, axiom 是具有可扩展性、高性能和开发便利的优点。
Hot Deployment :可进行热部署,在部署新的服务时不需要重新启动服务。
Asynchronous Web Services : 支持异步服务。
MEP Support : 支持消息交换模式( Message Exchange Patterns : MEPs ) ,MEP 是内嵌式的,支持 WSDL2.0 中的基本的 MEPs 。
Flexibility :具有灵活性,使得开发者自由向引擎中插入扩展功能。
Stability :稳定性。定义一系列的公布的接口,这些接口相对于其余的 Axis 改变得相对较慢。
Component-Oriented Deployment : 面向组件的部署。可以轻松定义可复用的网络或 handler 来实现常规应用程序的处理或将其分配给其伙伴。
Transport Framework :
WSDL 支持: 支 WSDL 1.1 和 WSDL 2.0 版本 。
Add-ons :
Composition and Extensibility: 模块支持组合和扩展功能。
Axis2 的 samples : binary 发布中的 samples/userguide/src 目录下
2、 Web Services Using Axis2
使用 axis2 写 web services 有两种方法
ü 使用 Axis2 的基本接口( Primary API )来实现业务逻辑
ü 从 WSDL 文件生成 Skeleton ,再实现业务逻辑
1) 使用 Axis2 的基本接口( Primary API )来实现业务逻辑
主要的操作是:
A :写实现类
B :写一个 services.xml 来解释 web service
C :为 web 服务创建一个 aar 文档
D :将文档部署
步骤一:编写类文件,描述 web service 的业务逻辑
public class MyService{
public void ping(OMElement element){
......
}
public OMElement echo(OMElement element){
......
}
}
// 这个类中给了两个方法,一个是只有输入,另一个是有输入和输出,输入输出类型都是 OMElement |
步骤二:为 web service 编写配置文件 services.xml
一个 services.xml 文件中可以写多个 web 服务的配置信息,可以对一组相关的服务 进行配置管理,使用 <ServiceGroup> 元素包含多个 <service> 元素
<service > <description> This is a sample Web Service with two operations, echo and ping. </description> <!- - 描述服务的类名 -- > <parameter name="ServiceClass" locked="false">userguide.example1.MyService</parameter> <!— 分别描述服务中的操作,每个操作都有相应的 MessageReceiver ,方法若是接收输入,返回输出信息使用的是 RawXMLINOutMessageReceiver 类,如要想使用 WS-Addressing ,需要有元素 actionMapping --> <operation name="echo"> <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> <actionMapping>urn:echo</actionMapping> </operation> <operation name="ping"> <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> <actionMapping>urn:ping</actionMapping> </operation> </service> |
步骤三:创建 archive 文件
Archive 文件的目录结构如下图所示,在当前目录下,创建一个 META-INF 目录, services.xml 文件就存放于此目录,当前目录下存放的是源文件,可以先创建一个 jar 文件,再将其更改扩展名。
可以将命令行切换到 example1 目录下,键入命令: jar cvf MyService.jar .
之后将 jar 更为 aar
步骤四:部署文件
将 aar 文件复制到 axis2 的 WEB-INF 目录下的 service 目录下,或者使用它提供的 upload service 接口直接部署。
REST: 第二代 Web services 使用的体系结构,而不是使用 SOAP 。 REST 代表: Representational State Transfer 。表示每一个 URL 都表示一个对象资源。可以使用 HTTP Get 获得对象的内容,或者是删除、或对对象进行更改。
The main advantages of REST web services are:
Lightweight - not a lot of extra xml markup
Human Readable Results
Easy to build - no toolkits required
SOAP also has some advantages:
Easy to consume - sometimes
Rigid - type checking, adheres to a contract
Development tools
2) 从 WSDL 文件生成 Skeleton ,再实现业务逻辑
步骤一:根据 WSDL 文件生成 skeleton
使用 axis2 提供的 WSDL2Java 工具生成 skeleton ,工具使用的参数说明如下
Usage WSDL2Code -uri <Location of WSDL> : WSDL file location -o <output Location> : output file location -a : Generate async style code only. Default is off -s : Generate sync style code only. Default is off. takes precedence over -a -p <package name> : set custom package name -l <language> : valid languages are java and csharp. Default is java -t : Generate TestCase to test the generated code -ss : Generate server side code (i.e. skeletons). Default is off -sd : Generate service descriptor (i.e. services.xml). Default is off. Valid with -ss -d <databinding> : valid databinding(s) are adb, xmlbeans and jaxme. Default is adb -g Generates all the classes. valid only with the -ss -pn <port_name> : name of port in the presence of multiple ports -sn <service_name> : name of service in the presence of multiple services -u : unpacks the databinding classes -r <repository_path> : path of the repository against which code is generated |
将例子中给的 Axis2SampleDocLit.wsdl 生成它的 skeleton ,命令行如下
D:\ws_tools\axis2-std-1.0-bin>WSDL2Java -uri samples\wsdl\Axis2SampleDocLit.wsdl
-ss -sd -d xmlbeans -o samples\tt -p org.apache.axis2.userguide 将生成的文件放于 samples 目录下的 tt 目录下。
步骤二:实现商业逻辑
在 src 目录下的目录中找到 Axis2SampleDocLitTypeSkeleton.java 文件,它就是 web service 的 skeleton ,对其中的方法进行编辑来实现商业逻辑。
步骤三: services.xml
生成 skeleton 时,服务的配置文件 services.xml 文件是自动生成的,存放于 resources 目录下。
步骤四:打包( packaging )
将类文件打包形成 aar 文件,然后将其部署到 axis2 下的 services 目录下。使用 WSDL2Java 工具生成 skeleton 时同时产生的数据绑定类在 schemaorg_apache_xmlbeans 目录下,也需要将其复制到类路径下,将 skeleton 和支持的文件进行编译。将需要的目录文件以下面的结构存放,编译之后打包生成 aar 文件。
即将 services.xml 文件放于 META-INF 目录下,将也将 schemaorg_apache-xmlbeans 目录和 skeleton 所在的源文件目录放于一个目录下。同时将 wsdl 文件也放于 META-INF 目录下。
对 perf 的操作如下:
在 src 目录下, javac –classpath .;%axis2classpath% org\apache\axis2\userguide\*.java
编译成功之后,将 schemaorg_apache_xmlbeans 目录拷贝到 src 目录下,建立一个 META-INF 目录,将 resources 目录下的 services.xml 文件和 *.wsdl 文件复制到 META-INF 目录下
在 src 目录下,运行 jar 命令 jar -cfv perf.jar META-INF org schemaorg_apache_xmlbeans
将 perf.jar 改名为 aar 部署到 tomcat 容器中。
或者是在编辑完 skeleton 后,运行生成的 build.xml ,即 ant 命令,则 ant 会对程序进行编译,成功之后,把生成的 build 目录下的 classes 下的 org 目录和 META-INF 还有 resources
目录下的 schemaorg_apache_xmlbeans 目录添加到一个 jar 文件即可,更改 jar 扩展名为 aar 扩展名。
3、 Web Service 客户端使用Axis2调用服务
客户端调用使用可以使用阻塞和非阻塞 API 。
阻塞模式( Blocking API ):一旦服务被调用,客户端处于阻塞状态,它不能执行其他的操作,除非收到服务端发送的响应信息或是出错信息。(同步模式调用)
非阻塞模式( Non-Blocking API ):这是一种基于回调或者是轮询的 API 。当服务调用以后,客户端立刻能获得控制权进行其他操作,服务端的返回消息使用提供的 callback 对象得到。这样可以使得客户端应用程序可以同时调用多个 web services 而不用阻塞已经调用的操作。(异步模式调用)它们都是在 API 层实现。
根据 API 层的异步调用和传输层的异步调用 ,可以得到四种不同模式来调用 web services 。
API (Blocking/ |
Dual Trans |
Description |
Blocking |
No |
Simplest and the familiar invocation pattern |
Non-Blocking |
No |
Using callbacks or polling |
Blocking |
Yes |
This is useful when the service operation is IN-OUT in nature but the transport used is One-Way (e.g. SMTP) |
Non-Blocking |
Yes |
This is can be used to gain the maximum asynchronous behavior. No blocking in the API level and also in the transport level |
客户端调用 web 服务也有两种方法:
ü 编写 axis2 的主要的 API
ü 使用产生的 Stub 编写
1) 使用 Axis2 的原始的 API 编写客户端来调用 Web Service
测试的例子在 Eclipse 集成开发环境下使用 ,例子见 axis2 的 samples 或是 F:\proTest\axis2\ClientInvoke 下的实例。
2) 使用 axis2 的代码生成绑定数据来编写 service 。
使用 WSDL2Java 命令来生成 stub ,对于 Axis2SampleDocLit.wsdl 操作如下:
D:\ws_tools\axis2-std-1.0-bin\samples\wsdl>WSDL2Java -uri ..\..\samples\wsdl\Axi
s2SampleDocLit.wsdl -o ..\..\samples\axisDocLitStub -p org.apache.axis2.userguide
编辑 axisDocLitStub\src\org\apache\axis2\userguide 目录下的
Axis2SampleDocLitServiceStub.java 文件,编译时可以直接使用 WSDL2Java 生成的 build.xml 文件使用 ant 命令进行编译。
4、 模块(Module)
为一个给定服务自定义模块步骤有:
(1) 创建模块的实现
(2) 创建 handler
(3) 创建 module.xml 文件
(4) 如果需要自定义 phases ,则要修改 axis2.xml
(5) 修改 services.xml 文件使之在部署时结合 engage 模块
(6) 在一个 *.mar 文件中打包
(7) 将模块在 axis2 中部署
例子:在 MyService 服务中添加一个 logging 模块
Logging 模块的功能是它包含一个 handler ,此 handler 能够记录被传递的消息。在 axis2 中,使用 .mar 文件来部署模块。模块的结构如下图所示:
步骤一 : LoggingModule 类
LoggingModule 是 axis2 模块的实现类, axis2 的模块应该实现 org.apache.axis2.modules.Module 接口的方法 :
// 实始化模块操作
Public void init(ConfigurationContext configContext,AxisModule module) throws AxisFault;
// 模块结束的处理
Public void shutdown(AxisConfiguration axisSystem) throws AxisFault;
Public void engageNotify(AxisDescription axisDescription) throws AxisFault;
此处的 loggingModule 中这三个方法的实现为空。
步骤二 : LogHandler
Axis2 中的 module 可以包含有一个或更多个 handler , handler 可以在不同阶段( phase )处理各种各样的 SOAP 头。要编写一个 handler ,需要实现 org.apache.axis2.engin.Handler 类。便利其见, org.apache.axis2.handlers.AbstractHandler 类提供 Handler 接口的抽象实现。在 hander 中,方法 invoke 和 revoke 表示如下:
Public void invoke(MessageContext ctx)// 将控制权交给 handler 时由 axis2 的引擎调用 invoke
Public void revoke(MessageContext ctx)// 当 hander 被撤消时由 axis2 引擎来调用 revoke 方法
位置: F:\protest\axis2\myservicemodule\loggingmodule
步骤三 : module.xml
Module.xml 文件包含了对特殊模块的部署配置。它包含的信息详细如:模块的实现类(如 LoggingModule 类可以在不同的阶段运行), module.xml 文件配置信息中主要的元素有表现了不同阶段的说明:
Inflow :代表了 handler chain 在一个消息到来时运行
Outflow :代表了 handler chain 在消息离开时运行
Outfaultflow :代表 handler chain 将在出现故障并且故障离开时运行
Infaultflow :代表 handler chain 将在出现故障并且故障进入时运行。
步骤四 :修改 axis2.xml 文件
因为“ loggingPhase ”是由模块的编写者自己定义的,它不是 axis2 预先定义的,所以需要针其介绍到 axis2.xml 文件中,这样 axis2 的引擎可以知道在哪儿以不同的“ flows (如 InFlow,OutFlow )”安放 handler 。更改后的 axis2.xml 文件见 axis2 user’s guide 的第四部分。
Axis2.xml 文件中定义的是几个 phases 。
步骤五 :修改 services.xml 文件
在 services.xml 文件中添加 module 元素,使用 ref 来指向使用的模块,如:
<module ref=”logging”/>
步骤六 :打包 packaging
在部署模块之前,需要创建一个 *.mar 文件 , 对于 loggingmodule 创建的模块文件为 logging.mar ,使用 jar 生成 logging.jar 文件,再将扩展名更改。
先编译系统: F:\proTest\axis2\MyServiceModule>javac -classpath .;%axis2classpath% userguide\loggingmodule\*.java
步骤七:部署模块
将 mar 文件放入 axis2 的 WEB-INF 的 modules 目录下。
对于日志文件的修改需要,在 tomcat 下,更改 log4j.properties 文件,属性文件的位置在 webapps\axis2\WEB-INF\classes 目录下,将 log4j.rootCategory=ERROR,LOGFILE 改为 log4j.rootCategory=INFO,ERROR,LOGFILE
5、 其他例子
现实例子说明使用 axis2 的功能 。
Google spell checker sample
Google search sample
Amazon queuing sample
Google spell checker sample : 提供的服务是拼写检查,使用了 blocking 和 non-blocking 模式来调用服务。 \samples\googleSpellcheck
Google Search Sample: 包含一个检查程序,它使用了在 SOAP API 之上的检查。客户端使用 non-blocking 模式。 Samples\googleSearch
Amazon Queuing Service :说明如何使用 Amazon 查询服务。它有两个用户接口,一个是用于入队( enqueue ),另一个是出队( dequeue )。例子位置 samples\amazonQS