客户端的调用
Web services提供的服务多种多样,有的可以马上获得结果,有的要消耗很长的时间。所以,我们需要多种调用方式来对付不同的情况。
大多数的Web services都提供
阻塞(Blocking)和
非阻塞(Non-Blocking)两种APIs. 这两个概念以前应该学过,简单说一下。
Blocking API - 调用端要等被调用的函数运行完毕才继续往下走。
Non-Bloking API - 调用端运行完调用函数以后就直接往下走了,调用端和被调用端是异步执行的。返回值是用回调函数来实现的。
这种异步叫做
API层异步(
API Level Asynchrony)。他们只用到一个连接来发送和接收消息,而且,如果是那种需要运行很长时间的函数,还会碰到Time Out 错误,如果用两个连接分别处理发送和接收消息,调用的时间就可以缩短,也可以解决Time Out 问题。用两个连接来分别处理发送和接收消息,叫做
传输层异步(
Transport Level Asynchrony)。
API |
传输 |
描述 |
阻塞 |
1连接 |
简单的传统用法 |
非阻塞 |
1连接 |
使用回调或者轮询 |
阻塞 |
2连接 |
Service是有返回值的,但是它的传输是单路。(比如 SMTP) |
非阻塞 |
2连接 |
最大程度的异步执行 |
理论真无聊,还是来看实例吧。
打开 Eclipse, 创建一个新Project, 新建一个叫userguide.clients的包, 把"samples\userguide\src\userguide\clients" 下面的文件都copy到那个包下面, 把AXIS2的lib下面的jar都加到ilbrary里面去(应该不用全加,懒一点就全加了吧.) 发现了关于echo的调用的方式, 居然有五个:
EchoBlockingClient
EchoBlockingDualClient
EchoBlockingWsaBasedClient
EchoNonBlockingClient
EchoNonBlockingDualClient
一个一个看吧.
EchoBlockingClient.java
public class EchoBlockingClient {
private static EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP,
false);
//Blocking invocation
OMElement result = call.invokeBlocking("echo",
payload);
StringWriter writer = new StringWriter();
result.serializeWithCache(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
}
和一代几乎一样, 弄一个EndpointReference, 再弄一个call, 其他不一样,但是也很简单, 弄一个OMElement作为参数, 返回也是一个OMElement. 可惜运行居然有错.
再来看双通道的版本
EchoBlockingDualClient.java
public class EchoBlockingDualClient {
private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Call call = new Call();
call.setTo(targetEPR);
call.engageModule(new QName(Constants.MODULE_ADDRESSING));
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP,
true);
//Blocking Invocation
OMElement result = call.invokeBlocking("echo",
payload);
StringWriter writer = new StringWriter();
result.serializeWithCache(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//Need to close the Client Side Listener.
call.close();
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
加了一句engageModule, 这句话好像没什么用,我删掉这句话也能运行的, 然后setTransportInfo最后一个参数改成了true. 关于setTransportInfo的三个参数, 第一个是发送的Transport, 第二个是接收的Transport, 第三个是"是否双通道", 支持的搭配形式如下:
http, http, true
http, http, false
http,smtp,true
smtp,http,true
smtp,smtp,true
看下一个吧,EchoNonBlockingClient,这个是单通道的非阻塞模式:
public class EchoNonBlockingClient {
private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Call call = new Call();
call.setTo(targetEPR);
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP,
false);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
try {
StringWriter writer = new StringWriter();
result.getResponseEnvelope().serializeWithCache(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
} catch (XMLStreamException e) {
reportError(e);
}
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
call.invokeNonBlocking("echo", payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
不同的地方,只是调用的方法从invokeBlocking变成了invokeNonBlocking,然后写了一个简单的匿名Callback类作为回调函数。关于这个Callback类,它是一个抽象类,其中有两个方法:onComplete和reportError,都是client端必须实现的,他还有一个Field,就是complete,可以用来设置和查询调用是否完成。可惜也不能运行,和上面的错误一样,是在createSOAPMessage的时候报null错误。
看下一个EchoNonBlockingDualClient,非阻塞的双通道:
public class EchoNonBlockingDualClient {
private static EndpointReference targetEPR = new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getEchoOMElement();
Call call = new Call();
call.setTo(targetEPR);
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
call.engageModule(new QName(Constants.MODULE_ADDRESSING));
call.setTransportInfo(Constants.TRANSPORT_HTTP,
Constants.TRANSPORT_HTTP,
true);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
try {
StringWriter writer = new StringWriter();
result.getResponseEnvelope().serializeWithCache(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
} catch (XMLStreamException e) {
reportError(e);
}
}
public void reportError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
call.invokeNonBlocking("echo", payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
call.close();
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
双通道和单通道基本没什么不同,只是双通道的时候,它总是要设定engageModule,然后多了一个call.close();,自己关闭监听器(close the Client Side Listener)。
以上这些都是需要返回值的调用,如果不需要返回值呢,看看PingClient
public class PingClient {
private static EndpointReference targetEPR = new EndpointReference("http://localhost:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMElement payload = ClientUtil.getPingOMElement();
MessageSender msgSender = new MessageSender();
msgSender.setTo(targetEPR);
msgSender.setSenderTransport(Constants.TRANSPORT_HTTP);
msgSender.send("ping", payload);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
}
呵呵,这也忒简单了一点,就一个msgSender.send就搞定了。
Client端的调用组合基本看完了,但是还有一个EchoBlockingWsaBasedClient,这是什么东啊? 还有那个engageModule是用来做啥的?先不管它们吧。
看看那个我认为最有用的工具:WSDL2Java,在bin目录下面有WSDL2Java.bat和WSDL2Java.sh,这个工具是用来干啥的呢,和一代一样,是用来生成stub的,就是说别人发布了Web Service以后,就会有一个wsdl文件,这个工具可以根据wsdl生成几个class,把底层的调用都wrap起来了,然后你用的时候就像普通函数调用一样。
演练一下吧,从命令行走到samples\wsdl目录下面,看到Axis2SampleDocLit.wsdl,执行..\..\bin\WSDL2Java.bat -uri Axis2SampleDocLit.wsdl,目录下面一下子多了两个目录,不管schemaorg_apache_xmlbeans,把codegen目录copy到Eclipse的一个Project里面去,哇,好多class啊,不看别的,就看Axis2SampleDocLitPortTypeStub,里面有三个函数是Web Service提供的:echoStringArray,echoStruct和echoString,哈哈,什么Call类了,MessageContext了,都在里面了,使用起来嘛,就像这样:
try {
Axis2SampleDocLitPortTypeStub stub= new Axis2SampleDocLitPortTypeStub(null, "http://localhost:8080/axis2/services/Axis2SampleDocLitPortType");
//Create the request document to be sent.
EchoStringParamDocument reqDoc= EchoStringParamDocument.Factory.newInstance();
reqDoc.setEchoStringParam("Axis2 Echo");
//invokes the web service.
EchoStringReturnDocument resDoc=stub.echoString(reqDoc);
System.out.println(resDoc.getEchoStringReturn());
} catch (Exception e) {
e.printStackTrace();
}
就是创一个stub,再创一个参数类(EchoStringParamDocument),然后调用函数传参数,和普通的函数调用没有区别。如果你在命令行输入WSDL2Java.bat,会看到它的帮助提示如下:
Usage WSDL2Code -uri <Location of WSDL> :WSDL file location
-o <output Location> : output file location
-a : Generate async style code only. Default if off
-s : Generate sync style code only. Default if 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. axis2.xml).Default is off.Valid with -ss
分享到:
相关推荐
Axis2是Apache软件基金会开发的一款基于Java的Web服务...通过深入学习这些知识点,你将能够熟练地使用Axis2来开发、部署和管理Web服务,为你的项目提供强大的服务支持。这个压缩包中的资料将是你学习过程中宝贵的资源。
通过本文的学习,相信读者不仅能掌握Axis2的基本操作,还能深刻理解WebService在现代软件工程中的关键作用。未来,随着更多新技术的融合,Axis2的应用前景将更加广阔,为开发者带来更多的机遇与挑战。
这篇博客"axis2学习——客户端的开发"主要探讨了如何使用Axis2来创建和操作Web服务的客户端。 首先,让我们了解什么是Apache Axis2。Axis2是Axis1的下一代版本,它提供了更高效、更灵活的服务框架。它是基于模块化...
Axis2是Apache软件基金会开发的一款基于Java的Web服务框架,它是Apache SOAP(Simple Object Access Protocol)项目的后续产品,专门用于构建高效、灵活且可扩展的Web服务。在本"Axis2学习文档"中,我们将深入探讨 ...
### Axis2 开发 Web Services 入门 #### 知识点概述 本文旨在介绍如何使用 Axis2 开发 ...对于初学者来说,这是一个非常实用且全面的学习指南,能够帮助他们快速掌握 Axis2 和 Web Services 的基本原理和技术要点。
Axis2是Apache软件基金会开发的一款用于构建Web服务的开源框架,它基于SOAP协议,并且支持WS-*标准。本文将深入探讨使用Axis2开发Web服务的相关知识点,包括Axis2的基础概念、环境搭建、服务创建与发布、Eclipse集成...
标题中的“axis2学习——开发自定义的axis2服务”表明了本文主要涉及Apache Axis2框架,这是一个用于构建Web服务和SOA(Service-Oriented Architecture)应用的开放源码平台。Axis2允许开发者创建、部署和管理服务,...
AXIS2是Apache软件基金会开发的一个开放源代码的Web服务框架,主要用于构建高效、灵活且可扩展的Web服务。...通过学习这些资料,你将能够有效地利用AXIS2开发高效、可靠的Web服务,并且具备解决实际问题的能力。
Axis2是Apache软件基金会开发的一款开源Web服务框架,主要用于构建高效、灵活且可扩展的Web服务。本笔记将深入探讨Axis2的核心概念、版本差异、安装配置以及在实际项目中的应用。 1. **核心概念** - **SOAP**: ...
【Axis2学习教程-全面学习AXIS】是一个针对Java开发者的教程,专注于教授如何使用Axis2这一流行的WebService引擎。Axis2是Apache软件基金会开发的Web服务框架,它为创建和部署Web服务提供了一种高效且灵活的方式。在...
Apache Axis2是Apache软件基金会开发的一个Web服务引擎,它提供了高效且灵活的Web服务解决方案。 **Web服务**是一种在互联网上不同系统间交换数据的方式,它允许应用程序之间通过标准协议进行通信。Web服务通常使用...
用户可以通过官方文档学习如何配置Axis2、创建服务、调用服务以及使用各种特性。此外,社区论坛和邮件列表也是获取问题解答和支持的重要资源。 ### Axis2与其他技术的集成 - **WS-Security**: 支持WS-Security标准...
这些文档对于学习和理解如何使用和扩展Axis2至关重要,它们通常包括HTML格式的在线文档,PDF文件,以及可能的源码注释。 3. `axis2-1.6.1-src.zip`:源代码包,包含了Axis2 1.6.1的所有源代码,供开发者深入研究或...
这些文件可能包含上述提到的API参考、教程和示例代码,它们是学习和开发基于Axis或Axis2的Web服务不可或缺的资源。通过仔细阅读这些文档,开发者可以掌握如何使用Axis或Axis2来创建符合WS-I标准、高性能的Web服务,...
学习者可以通过分析这个样本项目来更好地理解和实践Spring与Axis2结合开发Web服务的过程。 总之,"Spring + Axis2 开发 WebService"涵盖了从设计、实现、部署到消费Web服务的全过程,涉及到Spring框架的高级特性...
Axis2是Apache软件基金会开发的一个开源Web服务框架,主要用于构建高度可扩展且模块化的Web服务。这个框架基于SOAP(简单对象访问协议)和WS-*(Web服务*规范集),为开发者提供了一种高效且灵活的方式来创建和部署...
相较于其他Web服务框架,如CXF和Gson,AXIS2提供了更丰富的功能集和更高的灵活性,但可能对初学者来说,学习曲线较陡峭。 总之,AXIS2是一个强大的Web服务开发工具,它简化了基于WSDL的服务开发流程,使开发者能够...
在本压缩包中,你将找到关于Axis2的学习资料,包括开发文章、插件包以及一个名为“countservice”的示例服务。 首先,让我们深入理解一下Axis2的核心概念和功能。Axis2是Web服务引擎,它负责处理SOAP消息并提供与...
通过学习和分析这些示例,开发者能够快速掌握Seasar2 Axis2的使用方法,并将其应用到自己的项目中。 总结起来,Seasar2 Axis2实例展示了如何利用这两个强大的工具集来构建高效、可扩展的Web服务应用。通过对Seasar2...