- 浏览: 70593 次
- 性别:
- 来自: 深圳
最新评论
-
dudong0726:
不错
flex MP3播放器开发二(单歌曲播放) -
三尺寒冰:
楼主能共享一下源代码吗???
flex MP3播放器开发三(进度条显示) -
狂放不羁:
引用 另外 Hibernate 生成的 sql 也实在是太难看 ...
我为什么选择 iBatis 而不是 Hibernate(对于正在选型的人的建议) -
jimzhao:
有一个gif,按你的方法处理了一下,可以动画的时候,中间出现很 ...
imagick 处理 gif 切割 或者是 缩放 -
bigplum:
好东西
imagick 处理 gif 切割 或者是 缩放
本文介绍 Axis2 的新体系结构,并说明如何通过 Axis2 部署和使用 Web 服务。本文是有关通过 Axis2 运行时开发 Web 服务的系列文章的第 1 部分(共两部分)。Axis2 是下一代 Apache Axis Simple Object Access Protocol (SOAP) 运行时。
引言
Axis2 是下一代 Apache Axis。Axis2 虽然由 Axis 1.x 处理程序模型提供支持,但它具有更强的灵活性并可扩展到新的体系结构。Axis2 基于新的体系结构进行了全新编写,而且没有采用 Axis 1.x 的常用代码。支持开发 Axis2 的动力是探寻模块化更强、灵活性更高和更有效的体系结构,这种体系结构可以很容易地插入到其他相关 Web 服务标准和协议(如 WS-Security、WS-ReliableMessaging 等)的实现中。
Axis2 的特性包括:
采用名为 AXIOM(AXIs Object Model,Axis 对象模型)的新核心 XML 处理模型
支持 In-Only 和 In-Out 消息交换模式 (MEP)
阻塞和非阻塞客户端 API(应用程序编程接口)
支持内置的 Web 服务寻址 (WS-Addressing)
支持 XMLBeans 数据绑定
新部署模型
支持超文本传输协议 (HTTP)、简单邮件传输协议 (SMTP) 和传输控制协议 (TCP) 等传输协议
本系列文章以 Axis2 0.92 版本为基础。您可以在 Apache 网站获得 Axis2 的最新版本。
回页首
Axis 体系结构概述
图 1. Axis2 体系结构
Axis2 体系结构将逻辑与状态分离;这允许在并行线程中执行逻辑。服务和调用的静态状态和动态状态分别存储在 Description 和 Context 类中。Axis2 体系结构是使用 7 个独立模块实现的。
信息模型:此模块管理 SOAP 引擎的状态。该模型定义一组用于存放状态的类,而引擎管理这些信息对象的生命周期。信息模型包含两种用于存放状态的类。Description 类存放本质上是静态的且存在于 Axis 引擎实例的整个生命周期中的数据(如传输、服务和操作的配置)。Context 类存放调用上下文中有效的服务和操作的动态信息,例如当前请求和响应 SOAP 消息、From 地址、To 地址和其他元素。
XML 处理模型:Axis2 引入了一个名为 AXIOM 的新模型,用于处理 SOAP 消息。AXIOM 使用 StAX (Streaming API for XML) 来解析 XML。StAX 是一个标准的流式 Pull 解析器 Java™ API。AXIOM 非常精巧,不会减慢 XML 信息集的构建速度——换句话说,对象只有在绝对必要时才会创建。总体而言,AXIOM 和 Axis2 所占用的内存要小于 Axis 1 所占用的内存。
SOAP 处理模型:Axis2 体系结构定义了两个管道(或流),分别称为 InPipe (InFlow) 和 OutPipe (OutFlow),用于处理服务器端的请求消息和响应消息。在客户端,这两个管道是反向的——换句话说,SOAP 请求消息流经 OutPipe,而响应消息流经 InPipe。管道或流包含一系列分为阶段的处理程序。阶段按照预先定义的顺序执行,如上面的图 1 所示。除预先定义的阶段和处理程序集外,用户还可以在操作级别、服务级别或全局级别配置用户阶段和相关处理程序。处理程序充当 SOAP 消息的拦截器,可以处理 SOAP 消息的 Header 或 Body。InPipe 是通过以下阶段进行配置的:
TransportIn
PreDispatch
Dispatch
PostDispatch
PolicyDetermination
User phases
Message validation
我们将在本系列文章的第 2 部分中详细介绍上述各阶段。请求消息在通过 Inpipe 中配置的所有阶段后,到达 MessageReceiver,然后由 MessageReceiver 调用实际服务实现。服务器的 OutPipe 包含以下阶段:
Message initialization
Policy determination
User phases
MessageOut
用户配置的阶段位于这两个管道的用户阶段(User phases) 部分。如果在执行这些管道的过程中发生错误,则这些错误将通过 InFaultPipe 或 OutFaultPipe 管道。收到 Fault 消息后,在客户端调用 InFaultPipe;如果某个调用导致将错误发送到客户端,则在服务器端调用 OutFaultPipe。用户可以将处理程序添加到预先定义的阶段,并且按照这些处理程序运行的顺序进行配置。
部署模块:此模块配置 Axis 引擎并部署服务和模块。axis2.xml(在 webapps/axis2/WEB-INF 中)包含 Axis2 引擎的全局配置,包括:
全局模块 (Global modules)
全局接收器 (Global receivers)
传输 (Transports)
用户阶段定义 (User phase definitions)
每个服务的配置都包含在服务存档的 services.xml 文件中。本文稍后将详细讨论此文件。
WSDL 和代码生成:此模块从 WSDL 文件中生成客户端存根和服务器框架代码。Axis2 代码生成器发出采用正确 XML 样式表的 XML 文件,以用所需语言生成代码。
客户端 API:Axis2 客户端 API 调用遵循 WSDL 2.0 定义的 In-Only 和 In-Out 消息模式的操作。客户端 API 支持 In-Out 操作的阻塞和非阻塞调用。
传输:此模块包含与传输层交互的处理程序。传输处理程序有两种类型:TransportListener 和 TransportSender。TransportListener 从传输层接收 SOAP 消息,然后将其传送到 InPipe 进行处理。TransportSender 发送通过指定传输从 OutPipe 接收到的 SOAP 消息。Axis2 提供 HTTP、SMTP 和 TCP 的处理程序。对于 HTTP 传输,服务器端上的 AxisServlet 和客户端上的一个简单的独立 HTTP 服务器(由 Axis2 提供)充当 TransportReceiver。
回页首
部署 Axis2
部署 Axis2 与部署 Axis 1 一样简单。首先在 Axis2 二进制代码分发包的 webapps 目录下查找 Axis2 Web 应用程序 axis2.war。在 servlet 容器中部署此 war 文件。在 Tomcat 中,如果已在服务器配置中将 unpackWARs 设置为 True,则只需将 axis2.war 复制到 $TOMCAT_HOME/webapps 目录即可部署 Axis2。请立即启动 Tomcat 并访问 http://localhost:<port>/axis2。将显示 Axis2 欢迎页,单击此页上的 Validate 链接。您应到达 Axis2 Happiness page,不会出现任何错误。
回页首
开发 StockQuoteService
下面介绍如何使用 In-Only subscribe() 和 In-Out getQuote() 这两个操作来开发 StockQuoteService。subscribe() 操作将预订指定代号的每小时报价,而 getQuote() 将获得指定代号的当前报价。
下面的清单 1 是 StockQuoteService 的实现示例:
清单 1. StockQuoteService 实现
package stock;
import org.apache.axis2.om.OMAbstractFactory;
import org.apache.axis2.om.OMElement;
import org.apache.axis2.om.OMFactory;
import org.apache.axis2.om.OMNamespace;
public class StockQuoteService {
public void subscribe(OMElement in){
String symbol = in.getText();
System.out.println("Subscription request for symbol ="+symbol);
// put the actual subscribe code here...
}
public OMElement getQuote(OMElement in){
// Get the symbol from request message
String symbol = in.getText();
int quote = 0;
if(symbol.equals("IBM")){
quote = 100;
}
// Put more quotes here ...
// Create response
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement resp = fac.createOMElement("getQuoteResponse", omNs);
resp.setText(String.valueOf(quote));
return resp;
}
}
对方法签名感到很疑惑?我们将讨论上述方法中的 OMElement。
回页首
部署服务
部署描述符
在 Axis2 中,服务部署信息包含在 services.xml 文件(在 0.92 以前的版本中,此文件名为 service.xml)中。对于上述 StockQuoteService,服务部署描述符与下面的清单 2 类似。
清单 2. Services.xml
<service name="StockQuoteService">
<parameter name="ServiceClass" locked="xsd:false">
stock.StockQuoteService
</parameter>
<operation name="getQuote">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="subscribe">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
</service>
服务的 name 属性定义服务的名称。Axis2 使用服务的名称创建服务的端点地址,例如 http://localhost:<port>/axis2/services/<nameofservice>。因此,对于 StockQuoteService,服务端点为 http://localhost:<port>/axis2/services/StockQuoteService。ServiceClass 参数指定服务实现类。
每个 <operation> 元素定义服务中一个操作的配置。<operation> 的 name 属性应设置为服务实现类中方法的名称。messageReceiver 元素定义用于处理此操作的消息接收器。Axis2 针对 In-Only 和 In-Out 操作提供了两个无数据绑定的内置 MessageReceivers;org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver 用于 In-Only 操作,而 org.apache.axis2.receivers.RawXMLINOutMessageReceiver 用于 In-Out 操作。如果没有指定 messageReceiver,则 Axis2 将尝试使用 org.apache.axis2.receivers.RawXMLINOutMessageReceiver 作为缺省的 messageReceiver。上述 RAWXML 消息接收器将传入 SOAP 消息的 <Body> 的内容作为 OMElement(OMElement 是 XML 元素的 AXIOM 缩写)传递给服务实现。此操作应作为 OMElement 返回 SOAP 响应的 <Body> 元素包含的 XML 内容。这便解释了为何 subscribe() 和 getQuote() 操作采用和返回 OMElement。
services.xml 还可以包含分为 servicegroup 的多个服务。
打包
Axis 2 服务是作为 Axis Archive (.aar) 打包的。这是一个 JAR 文件(使用 jar 或 zip 实用程序创建),在存档的 META-INF 目录中打包了 services.xml 文件。StockQuoteService 在打包成 StockQuoteService.aar 时将具有以下结构: ./stock/StockQuoteService.class
./META-INF/services.xml
预先打包的 StockQuoteService 存档可以在本文的下载部分中找到。
部署
在 Axis2 中部署服务相当简单,只需将 .aar 文件复制到 servlet 容器的 axis2 Web 应用程序中的 axis2/WEB-INF/services 目录下即可。对于 Tomcat,此位置为 $TOMCAT_HOME/webapps/axis2/WEB-INF/services。
另一种部署服务的好方法是使用 Axis2 管理控制台中的 Upload Service 工具。请转到 http://localhost:<port>/axis2,然后选择 Administration 链接。输入用户名和密码 admin/axis2,然后登录。(您可以在 axis2.xml 中配置用户名/密码。)在工具部分选择 Upload Service 链接,再选择 .aar 文件,然后单击 Upload。就是这样简单!如果上传成功,系统将显示一条绿色成功消息。服务即被部署,而且可随时调用。如果要在远程 Axis2 服务器上部署服务,则此功能非常方便。
回页首
通过 Axis2 使用 Web 服务
Web 服务调用的特性由 MEP、传输协议以及客户端 API 的同步和/或异步行为决定。Axis2 当前支持 WSDL 2.0 定义的 In-Only 和 In-Out MEP。Axis2 客户端 API 支持服务的同步和异步调用。在调用 In-Out 操作时,在 API 级别和传输级别提供异步行为。API 级别异步是通过回滚获得的,它使用一个传输连接来同时传输请求和响应(例如,通过一个 HTTP 连接传输请求和响应)。在传输级别异步中,使用不同的传输连接分别发送请求和接收响应,例如使用 SMTP 进行传输时即如此。
下面是使用 Axis2 客户端 API 调用 In-Only 和 In-Out 操作的详细信息。
调用 In-Only 操作
org.apache.axis2.clientapi.MessageSender 类用于调用 In-Only 操作(如下面的清单 3 所示),而 In-Only 操作调用 StockQuoteService 的 subscribe() 操作。
清单 3. 调用 In-Only 操作
try{
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
// Make the request message
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("subscribe", omNs);
payload.setText("IBM");
// Send the request
MessageSender msgSender = new MessageSender();
msgSender.setTo(targetEPR);
msgSender.setSenderTransport(Constants.TRANSPORT_HTTP);
msgSender.send("subscribe", payload);
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
MessageSender.send() 发送请求消息并将其立即返回。要使用的传输由 MessageSender.setSenderTransport() 指定。此示例通过 HTTP 发送消息。
调用 In-Out 操作
使用 org.apache.axis2.clientapi.Call 类可以方便地调用 In-Out 操作。调用 In-Out 操作时,此 Call 类支持下列 4 种模式:
阻塞单传输模式:这是调用 In-Out Web 服务操作最简单的方式。在操作完成和接收到响应或错误之前,服务调用被阻塞。它使用一个传输连接同时发送和接收响应,如下面的清单 4 所示。
清单 4. 阻塞单传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
// Create request message
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
// Create the call
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP, false);
// Invoke blocking
OMElement result = call.invokeBlocking("getQuote", payload);
System.out.println("Quote ="+result.getText());
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
代码的第一部分使用 AXIOM 创建请求消息。Call.setTransportInfo() 设置用于发送请求和获得响应的传输。Call.setTransportInfo() 操作的 Boolean 参数指出是否要使用不同的传输连接来分别发送请求和接收响应。在本例中,要求用一个 HTTP 连接发送请求和接收响应。
非阻塞单传输模式:在此调用模式中,只使用下面的一个传输连接获得非阻塞调用。如果在一个客户端应用程序中要完成多个 Web 服务调用,而且不希望每次调用都阻塞客户端,则需要此类行为。此时,如果响应可用,则调用立即返回且客户端得以回滚,如下面的清单 5 所示。
清单 5. 非阻塞单传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
//Create the request
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote", omNs);
payload.setText("IBM");
// Create the call
Call call = new Call();
call.setTo(targetEPR);
// Set the transport info.
call.setTransportInfo(org.apache.axis2.Constants.TRANSPORT_HTTP,
org.apache.axis2.Constants.TRANSPORT_HTTP, false);
// Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println("Quote = "
+ result.getResponseEnvelope().getBody().getFirstElement()
.getText());
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
// Invoke non blocking
call.invokeNonBlocking("getQuote", payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
call.close();
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
Call.invokeNonBlocking() 方法立即返回而不阻塞。Call.invokeNonBlocking() 采用 org.apache.axis2.clientapi.CallBack 的对象,如果响应来自服务,则将触发此对象。CallBack 有两个抽象方法 onComplete(AsynchResult) 和 reportError(Exception),需要由具体的 CallBack 类实现这些方法。在服务调用正常完成后,Axis2 引擎调用 onComplete() 方法。在从服务器获得错误消息后,调用 Callback 的 reportError() 方法。Callback.isComplete() 将指出操作调用是否完成。
因为上面两个方法使用一个传输连接来发送和接收消息,所以这些方法不适合长时间运行的事务。原因是在响应可用之前,传输连接可能会超时。要解决此问题,可使用两个不同的连接来分别发送请求和接收响应。但因为使用了其他传输连接来获得响应,因此需要将请求和响应关联起来。Axis2 支持 WS-Addressing,后者通过使用 <wsa:MessageID> 和 <wsa:RelatesTo> Header 可解决此问题。因此,如果使用两个传输,则支持对模块寻址,如下面两个模式所示。
阻塞双传输模式:此模式在以下情况下非常有用:服务操作在本质上是 In-Out,但使用的传输是单向的(如 SMTP)或服务执行需要很长时间且 HTTP 连接超时。请参见下面的清单 6。
清单 6. 阻塞双传输模式
try{
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(
Constants.TRANSPORT_HTTP, Constants.TRANSPORT_HTTP, true);
//Blocking Invocation
OMElement result = call.invokeBlocking("getQuote", payload);
System.out.println("Quote = "+result.getText());
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}catch (Exception ex) {
ex.printStackTrace();
}
非阻塞双传输模式:就 API 级别和传输级别的非阻塞而言,此模式提供了最大的灵活性,如下面的清单 7 所示。
清单 7. 非阻塞双传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(
Constants.TRANSPORT_HTTP, Constants.TRANSPORT_HTTP, true);
// Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println("Quote = "
+ result.getResponseEnvelope().getBody().getFirstElement()
.getText());
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
// Non-Blocking Invocation
call.invokeNonBlocking("getQuote", payload, callback);
// Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
call.close();
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}catch (Exception ex) {
ex.printStackTrace();
}
引言
Axis2 是下一代 Apache Axis。Axis2 虽然由 Axis 1.x 处理程序模型提供支持,但它具有更强的灵活性并可扩展到新的体系结构。Axis2 基于新的体系结构进行了全新编写,而且没有采用 Axis 1.x 的常用代码。支持开发 Axis2 的动力是探寻模块化更强、灵活性更高和更有效的体系结构,这种体系结构可以很容易地插入到其他相关 Web 服务标准和协议(如 WS-Security、WS-ReliableMessaging 等)的实现中。
Axis2 的特性包括:
采用名为 AXIOM(AXIs Object Model,Axis 对象模型)的新核心 XML 处理模型
支持 In-Only 和 In-Out 消息交换模式 (MEP)
阻塞和非阻塞客户端 API(应用程序编程接口)
支持内置的 Web 服务寻址 (WS-Addressing)
支持 XMLBeans 数据绑定
新部署模型
支持超文本传输协议 (HTTP)、简单邮件传输协议 (SMTP) 和传输控制协议 (TCP) 等传输协议
本系列文章以 Axis2 0.92 版本为基础。您可以在 Apache 网站获得 Axis2 的最新版本。
回页首
Axis 体系结构概述
图 1. Axis2 体系结构
Axis2 体系结构将逻辑与状态分离;这允许在并行线程中执行逻辑。服务和调用的静态状态和动态状态分别存储在 Description 和 Context 类中。Axis2 体系结构是使用 7 个独立模块实现的。
信息模型:此模块管理 SOAP 引擎的状态。该模型定义一组用于存放状态的类,而引擎管理这些信息对象的生命周期。信息模型包含两种用于存放状态的类。Description 类存放本质上是静态的且存在于 Axis 引擎实例的整个生命周期中的数据(如传输、服务和操作的配置)。Context 类存放调用上下文中有效的服务和操作的动态信息,例如当前请求和响应 SOAP 消息、From 地址、To 地址和其他元素。
XML 处理模型:Axis2 引入了一个名为 AXIOM 的新模型,用于处理 SOAP 消息。AXIOM 使用 StAX (Streaming API for XML) 来解析 XML。StAX 是一个标准的流式 Pull 解析器 Java™ API。AXIOM 非常精巧,不会减慢 XML 信息集的构建速度——换句话说,对象只有在绝对必要时才会创建。总体而言,AXIOM 和 Axis2 所占用的内存要小于 Axis 1 所占用的内存。
SOAP 处理模型:Axis2 体系结构定义了两个管道(或流),分别称为 InPipe (InFlow) 和 OutPipe (OutFlow),用于处理服务器端的请求消息和响应消息。在客户端,这两个管道是反向的——换句话说,SOAP 请求消息流经 OutPipe,而响应消息流经 InPipe。管道或流包含一系列分为阶段的处理程序。阶段按照预先定义的顺序执行,如上面的图 1 所示。除预先定义的阶段和处理程序集外,用户还可以在操作级别、服务级别或全局级别配置用户阶段和相关处理程序。处理程序充当 SOAP 消息的拦截器,可以处理 SOAP 消息的 Header 或 Body。InPipe 是通过以下阶段进行配置的:
TransportIn
PreDispatch
Dispatch
PostDispatch
PolicyDetermination
User phases
Message validation
我们将在本系列文章的第 2 部分中详细介绍上述各阶段。请求消息在通过 Inpipe 中配置的所有阶段后,到达 MessageReceiver,然后由 MessageReceiver 调用实际服务实现。服务器的 OutPipe 包含以下阶段:
Message initialization
Policy determination
User phases
MessageOut
用户配置的阶段位于这两个管道的用户阶段(User phases) 部分。如果在执行这些管道的过程中发生错误,则这些错误将通过 InFaultPipe 或 OutFaultPipe 管道。收到 Fault 消息后,在客户端调用 InFaultPipe;如果某个调用导致将错误发送到客户端,则在服务器端调用 OutFaultPipe。用户可以将处理程序添加到预先定义的阶段,并且按照这些处理程序运行的顺序进行配置。
部署模块:此模块配置 Axis 引擎并部署服务和模块。axis2.xml(在 webapps/axis2/WEB-INF 中)包含 Axis2 引擎的全局配置,包括:
全局模块 (Global modules)
全局接收器 (Global receivers)
传输 (Transports)
用户阶段定义 (User phase definitions)
每个服务的配置都包含在服务存档的 services.xml 文件中。本文稍后将详细讨论此文件。
WSDL 和代码生成:此模块从 WSDL 文件中生成客户端存根和服务器框架代码。Axis2 代码生成器发出采用正确 XML 样式表的 XML 文件,以用所需语言生成代码。
客户端 API:Axis2 客户端 API 调用遵循 WSDL 2.0 定义的 In-Only 和 In-Out 消息模式的操作。客户端 API 支持 In-Out 操作的阻塞和非阻塞调用。
传输:此模块包含与传输层交互的处理程序。传输处理程序有两种类型:TransportListener 和 TransportSender。TransportListener 从传输层接收 SOAP 消息,然后将其传送到 InPipe 进行处理。TransportSender 发送通过指定传输从 OutPipe 接收到的 SOAP 消息。Axis2 提供 HTTP、SMTP 和 TCP 的处理程序。对于 HTTP 传输,服务器端上的 AxisServlet 和客户端上的一个简单的独立 HTTP 服务器(由 Axis2 提供)充当 TransportReceiver。
回页首
部署 Axis2
部署 Axis2 与部署 Axis 1 一样简单。首先在 Axis2 二进制代码分发包的 webapps 目录下查找 Axis2 Web 应用程序 axis2.war。在 servlet 容器中部署此 war 文件。在 Tomcat 中,如果已在服务器配置中将 unpackWARs 设置为 True,则只需将 axis2.war 复制到 $TOMCAT_HOME/webapps 目录即可部署 Axis2。请立即启动 Tomcat 并访问 http://localhost:<port>/axis2。将显示 Axis2 欢迎页,单击此页上的 Validate 链接。您应到达 Axis2 Happiness page,不会出现任何错误。
回页首
开发 StockQuoteService
下面介绍如何使用 In-Only subscribe() 和 In-Out getQuote() 这两个操作来开发 StockQuoteService。subscribe() 操作将预订指定代号的每小时报价,而 getQuote() 将获得指定代号的当前报价。
下面的清单 1 是 StockQuoteService 的实现示例:
清单 1. StockQuoteService 实现
package stock;
import org.apache.axis2.om.OMAbstractFactory;
import org.apache.axis2.om.OMElement;
import org.apache.axis2.om.OMFactory;
import org.apache.axis2.om.OMNamespace;
public class StockQuoteService {
public void subscribe(OMElement in){
String symbol = in.getText();
System.out.println("Subscription request for symbol ="+symbol);
// put the actual subscribe code here...
}
public OMElement getQuote(OMElement in){
// Get the symbol from request message
String symbol = in.getText();
int quote = 0;
if(symbol.equals("IBM")){
quote = 100;
}
// Put more quotes here ...
// Create response
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement resp = fac.createOMElement("getQuoteResponse", omNs);
resp.setText(String.valueOf(quote));
return resp;
}
}
对方法签名感到很疑惑?我们将讨论上述方法中的 OMElement。
回页首
部署服务
部署描述符
在 Axis2 中,服务部署信息包含在 services.xml 文件(在 0.92 以前的版本中,此文件名为 service.xml)中。对于上述 StockQuoteService,服务部署描述符与下面的清单 2 类似。
清单 2. Services.xml
<service name="StockQuoteService">
<parameter name="ServiceClass" locked="xsd:false">
stock.StockQuoteService
</parameter>
<operation name="getQuote">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="subscribe">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
</service>
服务的 name 属性定义服务的名称。Axis2 使用服务的名称创建服务的端点地址,例如 http://localhost:<port>/axis2/services/<nameofservice>。因此,对于 StockQuoteService,服务端点为 http://localhost:<port>/axis2/services/StockQuoteService。ServiceClass 参数指定服务实现类。
每个 <operation> 元素定义服务中一个操作的配置。<operation> 的 name 属性应设置为服务实现类中方法的名称。messageReceiver 元素定义用于处理此操作的消息接收器。Axis2 针对 In-Only 和 In-Out 操作提供了两个无数据绑定的内置 MessageReceivers;org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver 用于 In-Only 操作,而 org.apache.axis2.receivers.RawXMLINOutMessageReceiver 用于 In-Out 操作。如果没有指定 messageReceiver,则 Axis2 将尝试使用 org.apache.axis2.receivers.RawXMLINOutMessageReceiver 作为缺省的 messageReceiver。上述 RAWXML 消息接收器将传入 SOAP 消息的 <Body> 的内容作为 OMElement(OMElement 是 XML 元素的 AXIOM 缩写)传递给服务实现。此操作应作为 OMElement 返回 SOAP 响应的 <Body> 元素包含的 XML 内容。这便解释了为何 subscribe() 和 getQuote() 操作采用和返回 OMElement。
services.xml 还可以包含分为 servicegroup 的多个服务。
打包
Axis 2 服务是作为 Axis Archive (.aar) 打包的。这是一个 JAR 文件(使用 jar 或 zip 实用程序创建),在存档的 META-INF 目录中打包了 services.xml 文件。StockQuoteService 在打包成 StockQuoteService.aar 时将具有以下结构: ./stock/StockQuoteService.class
./META-INF/services.xml
预先打包的 StockQuoteService 存档可以在本文的下载部分中找到。
部署
在 Axis2 中部署服务相当简单,只需将 .aar 文件复制到 servlet 容器的 axis2 Web 应用程序中的 axis2/WEB-INF/services 目录下即可。对于 Tomcat,此位置为 $TOMCAT_HOME/webapps/axis2/WEB-INF/services。
另一种部署服务的好方法是使用 Axis2 管理控制台中的 Upload Service 工具。请转到 http://localhost:<port>/axis2,然后选择 Administration 链接。输入用户名和密码 admin/axis2,然后登录。(您可以在 axis2.xml 中配置用户名/密码。)在工具部分选择 Upload Service 链接,再选择 .aar 文件,然后单击 Upload。就是这样简单!如果上传成功,系统将显示一条绿色成功消息。服务即被部署,而且可随时调用。如果要在远程 Axis2 服务器上部署服务,则此功能非常方便。
回页首
通过 Axis2 使用 Web 服务
Web 服务调用的特性由 MEP、传输协议以及客户端 API 的同步和/或异步行为决定。Axis2 当前支持 WSDL 2.0 定义的 In-Only 和 In-Out MEP。Axis2 客户端 API 支持服务的同步和异步调用。在调用 In-Out 操作时,在 API 级别和传输级别提供异步行为。API 级别异步是通过回滚获得的,它使用一个传输连接来同时传输请求和响应(例如,通过一个 HTTP 连接传输请求和响应)。在传输级别异步中,使用不同的传输连接分别发送请求和接收响应,例如使用 SMTP 进行传输时即如此。
下面是使用 Axis2 客户端 API 调用 In-Only 和 In-Out 操作的详细信息。
调用 In-Only 操作
org.apache.axis2.clientapi.MessageSender 类用于调用 In-Only 操作(如下面的清单 3 所示),而 In-Only 操作调用 StockQuoteService 的 subscribe() 操作。
清单 3. 调用 In-Only 操作
try{
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
// Make the request message
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("subscribe", omNs);
payload.setText("IBM");
// Send the request
MessageSender msgSender = new MessageSender();
msgSender.setTo(targetEPR);
msgSender.setSenderTransport(Constants.TRANSPORT_HTTP);
msgSender.send("subscribe", payload);
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
MessageSender.send() 发送请求消息并将其立即返回。要使用的传输由 MessageSender.setSenderTransport() 指定。此示例通过 HTTP 发送消息。
调用 In-Out 操作
使用 org.apache.axis2.clientapi.Call 类可以方便地调用 In-Out 操作。调用 In-Out 操作时,此 Call 类支持下列 4 种模式:
阻塞单传输模式:这是调用 In-Out Web 服务操作最简单的方式。在操作完成和接收到响应或错误之前,服务调用被阻塞。它使用一个传输连接同时发送和接收响应,如下面的清单 4 所示。
清单 4. 阻塞单传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
// Create request message
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
// Create the call
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP, false);
// Invoke blocking
OMElement result = call.invokeBlocking("getQuote", payload);
System.out.println("Quote ="+result.getText());
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
代码的第一部分使用 AXIOM 创建请求消息。Call.setTransportInfo() 设置用于发送请求和获得响应的传输。Call.setTransportInfo() 操作的 Boolean 参数指出是否要使用不同的传输连接来分别发送请求和接收响应。在本例中,要求用一个 HTTP 连接发送请求和接收响应。
非阻塞单传输模式:在此调用模式中,只使用下面的一个传输连接获得非阻塞调用。如果在一个客户端应用程序中要完成多个 Web 服务调用,而且不希望每次调用都阻塞客户端,则需要此类行为。此时,如果响应可用,则调用立即返回且客户端得以回滚,如下面的清单 5 所示。
清单 5. 非阻塞单传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
//Create the request
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote", omNs);
payload.setText("IBM");
// Create the call
Call call = new Call();
call.setTo(targetEPR);
// Set the transport info.
call.setTransportInfo(org.apache.axis2.Constants.TRANSPORT_HTTP,
org.apache.axis2.Constants.TRANSPORT_HTTP, false);
// Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println("Quote = "
+ result.getResponseEnvelope().getBody().getFirstElement()
.getText());
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
// Invoke non blocking
call.invokeNonBlocking("getQuote", payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
call.close();
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
Call.invokeNonBlocking() 方法立即返回而不阻塞。Call.invokeNonBlocking() 采用 org.apache.axis2.clientapi.CallBack 的对象,如果响应来自服务,则将触发此对象。CallBack 有两个抽象方法 onComplete(AsynchResult) 和 reportError(Exception),需要由具体的 CallBack 类实现这些方法。在服务调用正常完成后,Axis2 引擎调用 onComplete() 方法。在从服务器获得错误消息后,调用 Callback 的 reportError() 方法。Callback.isComplete() 将指出操作调用是否完成。
因为上面两个方法使用一个传输连接来发送和接收消息,所以这些方法不适合长时间运行的事务。原因是在响应可用之前,传输连接可能会超时。要解决此问题,可使用两个不同的连接来分别发送请求和接收响应。但因为使用了其他传输连接来获得响应,因此需要将请求和响应关联起来。Axis2 支持 WS-Addressing,后者通过使用 <wsa:MessageID> 和 <wsa:RelatesTo> Header 可解决此问题。因此,如果使用两个传输,则支持对模块寻址,如下面两个模式所示。
阻塞双传输模式:此模式在以下情况下非常有用:服务操作在本质上是 In-Out,但使用的传输是单向的(如 SMTP)或服务执行需要很长时间且 HTTP 连接超时。请参见下面的清单 6。
清单 6. 阻塞双传输模式
try{
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(
Constants.TRANSPORT_HTTP, Constants.TRANSPORT_HTTP, true);
//Blocking Invocation
OMElement result = call.invokeBlocking("getQuote", payload);
System.out.println("Quote = "+result.getText());
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}catch (Exception ex) {
ex.printStackTrace();
}
非阻塞双传输模式:就 API 级别和传输级别的非阻塞而言,此模式提供了最大的灵活性,如下面的清单 7 所示。
清单 7. 非阻塞双传输模式
try {
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/StockQuoteService");
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://www.developerworks.com/example", "example");
OMElement payload = fac.createOMElement("getQuote",omNs);
payload.setText("IBM");
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(
Constants.TRANSPORT_HTTP, Constants.TRANSPORT_HTTP, true);
// Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println("Quote = "
+ result.getResponseEnvelope().getBody().getFirstElement()
.getText());
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
// Non-Blocking Invocation
call.invokeNonBlocking("getQuote", payload, callback);
// Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
call.close();
}catch (AxisFault axisFault) {
axisFault.printStackTrace();
}catch (Exception ex) {
ex.printStackTrace();
}
发表评论
-
我的淘宝群号
2011-05-31 12:40 2500人超级群,.淘宝互刷群,互刷信誉,群号码10461296 ... -
HttpClient 爬数据时 出现部分中文编码问题
2010-09-01 22:30 1302<html> <head> <m ... -
java 邮件群发
2010-08-13 22:38 1152摘 要:邮件群发是消息在Internet传递的最好办法,同时 ... -
关于struts2资源文件在页面动态取值问题
2010-04-20 20:16 967类似<s:text name="$ ... -
使用 XStream 把 Java 对象序列化为 XML
2009-05-21 15:04 966XML 序列化用处很多,包括对象持久化和数据传输。但是一些 X ... -
Axis2:会话(Session)管理
2009-05-20 16:07 1569WebService给人最直观的感 ... -
AXIS2中OMElement和Java对象之间的转换
2009-05-20 15:46 1457文章有错误,我要报错 ... -
axis2 开发
2009-05-19 22:03 10781,如果是单独开发,。axis2支持pring的装载,具体参见 ... -
PHP5中调用Java类
2009-05-13 10:28 968平台:Windows xp + apache2.0 + PHP ... -
Tomcat6下Log4j的log4j:ERROR Failed to rename错误解决办法
2009-05-09 00:25 2155Tomcat6下配置log4j log4j配置到tomca ... -
使用dom4j的xpath解析xlm文件
2009-05-08 21:10 1172package com.njusc.xmlTest; ... -
Java和PHP一致的DES编码
2009-05-08 20:38 1674最近在做一个项目需要实现一个SSO,这个项目是由两个Team共 ... -
java 和 php共享memcached数据注意问题
2009-05-08 20:36 1114在很多时候,一台memcached server中的数据,需要 ... -
hibernate-memcached--在Hibernate中使用Memcached作为...
2009-05-08 20:33 1107今天在网上看到一个用Memcached作为Hibernate二 ... -
dom4j实战(一)——使用dom4j从XML中读取数据源配置
2009-05-08 20:30 958目前XML文件的应用越来越广泛,而操作XML的技术更有不少,其 ... -
Java操作XML文件 dom4j 篇
2009-05-08 11:30 816在项目中,我们很多都用到了xml文件,无论是参数配置还是与其它 ...
相关推荐
【用Axis2开发Web Service】是本文的核心主题,轴心技术是Java开发Web服务的一种框架,相较于Axis1,其过程更为简洁。以下是关于使用Axis2开发Web Service的详细步骤和知识点: 1. **实验环境搭建**: - 首先确保...
标题中的“Axis2 Axis WebService Web 服务”指的是Apache Axis2,它是一个强大的Web服务框架,主要用于构建和部署Web服务。Axis2是Apache SOAP(Simple Object Access Protocol)项目的第二代实现,专门设计用于...
在IT行业中,开发和部署Web服务是常见的任务之一,而Apache Axis2是一个广泛使用的Web服务框架,它提供了高效、灵活且可扩展的服务架构。本文将详细介绍如何在Windows和Unix/Linux环境下,利用Apache Axis2和Tomcat...
`axis2-1.5.1-bin.zip`是Axis2的二进制包,它包含了运行和开发Web服务所需的所有基本组件。这个包通常用于本地开发环境或者在服务器上进行手动安装。其中包含的主要文件和目录有: 1. `bin`目录:包含启动和管理...
4. **测试服务**:使用Axis自带的工具或其他第三方工具来测试服务的功能。 总之,Axis提供了一个强大的平台,用于快速开发和部署高质量的Web服务。通过对Axis的工作原理、关键技术WSDL以及环境配置和开发流程的深入...
接下来,我们通过一个简单的例子来演示如何使用Axis2开发Web服务。 ##### 3.1 开发SayHello Web服务 假设我们需要开发一个名为SayHello的Web服务,该服务的功能是从客户端接收用户名,并返回一条问候消息,例如:...
在Web服务的世界里,Axis2是一个高效且强大的工具,它允许开发者创建、部署和使用SOAP Web服务。本教程将详细介绍如何利用Apache Tomcat 5.0作为应用服务器,以及如何结合Axis2来构建Web Service应用程序。 首先,...
通过以上步骤,我们完成了基于 Axis2 的 Web Services 开发环境的搭建,并成功创建了一个简单的 Web Service 示例。此过程不仅涵盖了软件开发的基础环境配置,还涉及了 Web Services 的具体开发和部署流程。对于初学...
在Java世界中,开发Web服务是一项常见的任务,而Apache Axis2是其中一款强大的工具,它为构建和部署Web服务提供了高效、灵活的框架。本文将深入探讨使用Axis2开发Web服务所需的关键知识点,并重点关注jar包的使用。 ...
标题中的“方便Web Service开发的axis2插件”指的是Axis2,这是一个开源的Web服务框架,专门用于简化和加速在Java环境中开发Web服务的过程。它提供了丰富的功能集,包括自动代码生成、服务部署以及多种协议的支持,...
在IT行业中,Axis2是Apache软件基金会开发的一个用于构建Web服务和Web服务客户端的框架,主要基于Java语言。本文将详细讲解如何使用Axis2来发布Web服务以及如何生成客户端代码来调用这些服务。 首先,让我们了解...
1. **Axis2框架**:Axis2是构建和部署Web服务的核心框架,它支持SOAP 1.1、SOAP 1.2、RESTful服务,并且可以处理MTOM(Message Transmission Optimization Mechanism)和SWA(SwA Protocol)等数据传输方式。Axis2的...
在IT行业中,Axis2是一个广泛使用的开放源代码Web服务框架,它是Apache软件基金会下的一个项目,主要用于构建和部署Web服务。本文将详细讲解利用Axis2发布Web服务的两种主要方式,以及它们各自的优缺点。 首先,...
- Axis2:作为Apache Axis的第二代产品,Axis2提供了一种高效、灵活的Web服务开发平台,支持动态和静态服务生成。 2. Axis2环境搭建: - 下载:首先从Apache官方网站下载Axis2的最新稳定版本,包括核心库和相关的...
Axis是Apache组织开发的一款开源Web服务框架,主要用于构建和部署SOAP(Simple Object Access Protocol)服务。Axis分为两个主要版本:Axis1.x和Axis2.x,它们都是Java平台上的Web服务实现,但在设计和功能上有所...