- 浏览: 497247 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (301)
- Swing技术 (1)
- Linux (1)
- Javascript (22)
- 数据结构和算法 (3)
- J2SE (36)
- workflow (5)
- 设计模式 (14)
- web service (19)
- Ajax (14)
- 中间件 & 服务器 (8)
- 多线程 (9)
- Oracle (52)
- sys & soft (10)
- JMS (3)
- sso (9)
- android (11)
- struts2 (10)
- web协议 (2)
- 分布式 (2)
- PM (2)
- OLAP (3)
- Redis (2)
- Hibernate (7)
- ibatis (2)
- SQLServer (1)
- maven (3)
- Spring (7)
- Jsp (2)
- slf4j (1)
- jQuery (15)
- 权限 (1)
- 系统集成 (1)
- 笔记 (1)
- Freemarker (2)
- 项目管理 (1)
- eclipse (3)
- GIS (1)
- NoSql (3)
- win10 (1)
- win10网络 (2)
- 底层 (3)
- 数据库 (0)
最新评论
-
kabuto_v:
请问那种图,uml图是怎么画出来的呢?是您自己手工画的,还是有 ...
FastJSON 序列化、反序列化实现 -
梦行Monxin商城系统:
电商实例、业务并发、网站并发及解决方法 -
rockethj8:
client 㓟有一个参数是可以忽略一些URL 不进行验证登录 ...
SSO 之 (单点登录)实施中遇到的几个问题 -
mengxiangfeiyan:
好啊。。。。。
Oracle删除表,删除数据以及恢复数据、利用现有表创建新表
本文是在理解官方指南的基础上,用实例实现Axis2提供的4种调用机制,并给出测试结果。
Blog: http://zhangjunhd.blog.51cto.com/
1.使用Axis2的底层API开发Web Service Server端
1.1创建一个WebService(取名为MyService)
在MyService中有两个operations,如下所示。
public void ping(OMElement element){}//IN-ONLY模式。仅仅接收OMElement,并对其处理。
public OMElement echo(OMElement element){}//IN_OUT模式。接收OMElemen,并返回OMElement。
1.2如何写Web Service
1)创建实现服务的类。
2)创建services.xml来解析这个Web Service。
3)将其打包成一个*.aar文档(Axis Archive)。
4)部署Web Service。
1.2.1 创建实现服务的类
此类中提供的方法必须与Web Service(在services.xml中声明)中的operations对应。除非你提供了数据绑定,否则所有的方法只能接收一个参数,其类型为OMElement。
public class MyService{
public void ping(OMElement element){...}
public OMElement echo(OMElement element){...}
}
MyService.java
package userguide.example1;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import javax.xml.stream.XMLStreamException;
public class MyService {
public OMElement echo(OMElement element) throws XMLStreamException {
//Praparing the OMElement so that it can be attached to another OM Tree.
//First the OMElement should be completely build in case it is not fully built and still
//some of the xml is in the stream.
element.build();
//Secondly the OMElement should be detached from the current OMTree so that it can
// be attached some other OM Tree. Once detached the OmTree will remove its
// connections to this OMElement.
element.detach();
return element;
}
public void ping(OMElement element) throws XMLStreamException {
//Do some processing
}
public void pingF(OMElement element) throws AxisFault{
throw new AxisFault("Fault being thrown");
}
}
1.2.2 创建services.xml
Axis2使用services.xml来充当一个Web Servicea的配置文件。每一个使用Axis2部署的Web Service都必须拥有一个services.xml。
<services>
<description>
This is a sample Web Service with two operations,echo and ping.
</description>
<parameter name=”ServiceClass” locked=”false”>
userguide.example1.MyService
</parameter>
<operation name=”echo”>
<messageReceiver class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver”/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name=”ping”>
<messageReceiver class=”org.apache.receivers.RawXMLINOnlyMessageReceiver”/>
<actionMapping>urn:ping</actionMapping>
</operation>
</service>
注:The actionMapping is required only if you want to enable WS-Addressing.
可以创建一个services.xml,其中包含一组服务。这样在运行期,你可以在这些服务间共享信息。
<serviceGroup>
<service name=”Service1”>
<!--details for Services1-->
</service>
<service name=”Service2”>
<!--details for Services2-->
</service>
<module ref=”ModuleName”/>
<parameter name=”serviceGroupParam1” locked=”false”>value1</parameter>
</serviceGroup>
注:name of the service is a compulsory attribute.
1.2.3打包与部署
这里不再详述,参见《基于Tomcat5.0和Axis2开发Web Service应用实例 》。
2.使用Axis2底层APIs实现Web Service客户端
2.1ClientUtil
创建一个客户端通用的SOAP包装Util文件。封装"getEchoOMElement"和"getPingOMElement"分别对应"echo"和"ping"这两个operation。
ClientUtil.java
package userguide.clients;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
public class ClientUtil {
public static OMElement getEchoOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);
return method;
}
public static OMElement getPingOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("ping", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Ping String "));
method.addChild(value);
return method;
}
}
2.2EchoBlockingClient
Axis2向用户提供了从blocking single channel调用到non-blocking dual channel调用的多种调用Web Service的模式。下面用最简单的blocking调用机制来实现”MyService”中的"echo" operation。
EchoBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for synchronous single channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
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();
Options options = new Options();
options.setTo(targetEPR); // this sets the location of MyService service
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
OMElement result = sender.sendReceive(payload);
System.out.println(result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
绿色部分显示了为了调用一个Web Service而需要对operation作的设置。剩下的部分是用来创建OMElement,用来发送和显示相应的OMElement。
结果:
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
2.3 PingClient
在”MyService”中,我们有一种IN-ONLY模式的名为"ping"的operation。应用它的客户端代码如下:
PingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for fire-and-forget service invocation
* Message Exchage Pattern IN-Only
*/
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();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
/**
* We have to block this thread untill we send the request , the problem
* is if we go out of the main thread , then request wont send ,so
* you have to wait some time
*/
Thread.sleep(500);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
由于我们在访问一个IN-ONLY模式的operation,所以我们可以直接使用ServiceClient中的"fireAndForget()"方法来调用这个operation。而且那样做的话,不会阻塞发起端,因此,它会立刻将控制权返回给客户端。
2.4 EchoNonBlockingClient
在客户端EchoBlockingClient,一旦调用"serviceClient.sendReceive(payload);",客户端将会被阻塞直到operation完成。这种方式在有很多Web Service需要在一个单一的客户端应用程序中启动时很不可取。一种解决方法是使用Non-Blocking API来调用这些Web Services。Axis2提供给用户一种基于回叫机制的non-blocking API。
EchoNonBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
/**
* Sample for asynchronous single channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoNonBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
sender = new ServiceClient();
sender.setOptions(options);
sender.sendReceiveNonBlocking(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();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) { }
}
}
}
结果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
sender.sendReceiveNonBlocking(payload, callback);这个调用接受一个callback对象作为参数。Axis2客户端API提供了一个抽象类CallBack,其中提供了方法:
public abstract void onComplete(AsyncResult result);
public abstract void onError(Exception e);
public boolean isComplete() {}
用户需要重写"onComplete " 和 "onError "方法。一旦客户端收到Web Service的response,onComplete方法将会被调用,这样将中止阻塞状态。
2.5EchoNonBlockingDualClient
当调用的Web Service需要很长一段时间来完成时,这种由Non-Blocking API提供的解决方式将有一定的局限性。这种局限性是由使用单一的传输连接来调用Web Service并接收response造成的。换句话说,客户端提供一种没有阻塞的调用机制,但request和response的传输使用单一的传输(双工方式)连接(如HTTP)。长时间运行的Web Service调用或Web Service调用使用单工传输方式(如SMTP)不能简单地利用一个没有阻塞的调用。
一种尝试地解决方法是request和response各自使用单独的传输连接(单工或双工均可)。这种方式产生的问题是如何解决相关性(关联request和response)。WS-Addressing提供了一种很好的解决方法,在头中使用<wsa:MessageID> 和 <wsa:RelatesTo> 标签。Axis2对这种基于关联机制的寻址方式提供了支持。
用户可以选择Blocking 或Non-Blocking APIs的Web Service,并使用两个传输连接。通过使用一个布尔标记,同一个API可以调用多个在两个传输连接上的Web Services(IN-OUT operations)。下例使用Non-Blocking API 以及两个传输连接来实现上文中提到的"echo" operation。
EchoNonBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
import javax.xml.namespace.QName;
/**
* Sample for asynchronous dual channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
* Ulitmate asynchronous service invocation sample.
*/
public class EchoNonBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
options.setAction("urn:echo"); // this is the action mapping we put within the service.xml
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);//见注解①
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//have to ignore this
}
}
}
}
注解①
RE: [Axis2] 0.95 WS-Addressing web SERVICE-SIDE: module not found
I now have managed to get EchoNonBlockingDualClient working. I still can't get the original code to work, where ever I put addressing-0.95.mar, but the ConfigurationContext works.
The code I ended up with was:
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"C:\\axis2", null);
sender = new ServiceClient(sysContext, null);
with no need, obviously, for the .engageModule method.
I did discover though that the directory which the ConfigurationContext points to has to have two directories within it: "conf", which must contain the axis.xml configuration file, and the "modules" directory which contains addressing-0.95.mar.
在方法"options.setUseSeparateListener(...)"中的布尔标记通知通知Axis2引擎使用两个不同的传输连接来分别处理request和response。Finally中的 "serviceClient.finalizeInvoke()"方法通知Axis2引擎停用客户端的用于接收response的listener。
在我们运行客户端的例程之前,我们还有一件事情要做。如前面提到的,Axis2使用基于地址的关联机制,因此我们必须在服务器端和客户端“搭建”寻址模块。
结果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://59.14.131.187:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__
</wsa:To>
<wsa:ReplyTo>
<wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:From>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:From>
<wsa:FaultTo>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:FaultTo>
<wsa:MessageID>
urn:uuid:B087CBB98F1B51A24711742241136206
</wsa:MessageID>
<wsa:Action>urn:echo</wsa:Action>
<wsa:RelatesTo wsa:RelationshipType="wsa:Reply">
urn:uuid:CA4B9513377E6E9E1511742241130391
</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
[SimpleHTTPServer] Stop called
2.6 实现服务器端的寻址
根据Axis2的结构,寻址模块在"pre-dispatch"阶段已经给出它的句柄。因此,所谓的“搭建”仅仅是在”axis2.xml”(注意不是services.xml)增加一个模块的引用。现在将下面这行字加入到axis2.xml,该文件在"/webapps/axis2/WEB-INF/conf"目录下。
<module ref="addressing"/>
注: 一旦你改变了axis2.xml,你必须重启这个servlet容器,改变才能生效。
2.7 实现客户端的寻址
有两种方式。
一种方法是在%Axis2_HOME%\axis2-std-1.0-bin\modules目录下得到addressing-<version>.mar。并且在你的classpath中对其可见。(此种方法目前,我还没有调试成功,具体见注解①。下面的第二种方法可用)
另一种方法是创建一个ConfigurationContext,指定一个repository位置。Axis2支持repository的方式来保存服务和模块。
你可以使用二进制distribution作为repository,只要它含有一个Axis2 repository认可的repository结构(其中应包含services和modules目录)。ConfigurationContext 中含有Axis2体系的运行时的上下文信息。
如果你解压一个标准的二进制distribution到目录(譬如)$user_home/axis2/dist, 那么在 sender = new ServiceClient();之前加入(具体见EchoNonBlockingDualClient.java):
new ServiceClient();之前加入(具体见EchoNonBlockingDualClient.java):
ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
用"sender = new ServiceClient(configContext, null);" 替换 "sender = new ServiceClient();"
这样可以在客户端和服务器端都实现寻址。
2.8 EchoBlockingDualClient
这又是一个两路的传输的request/response客户端,但这次,我们使用一个Blocking API。实现机制和EchoNonBlockingDualClient差不多,唯一的不同是,这里不需要使用一个callback对象来处理response。
EchoBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import java.io.StringWriter;
/**
* Sample for synchronous dual channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setAction("urn:echo");
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
//Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
StringWriter writer = new StringWriter();
result.serialize(XMLOutputFactory.newInstance().createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//
}
}
}
}
结果:
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>Axis2 Echo String </example1:Text>
</example1:echo>
[SimpleHTTPServer] Stop called
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/25592
Blog: http://zhangjunhd.blog.51cto.com/
1.使用Axis2的底层API开发Web Service Server端
1.1创建一个WebService(取名为MyService)
在MyService中有两个operations,如下所示。
public void ping(OMElement element){}//IN-ONLY模式。仅仅接收OMElement,并对其处理。
public OMElement echo(OMElement element){}//IN_OUT模式。接收OMElemen,并返回OMElement。
1.2如何写Web Service
1)创建实现服务的类。
2)创建services.xml来解析这个Web Service。
3)将其打包成一个*.aar文档(Axis Archive)。
4)部署Web Service。
1.2.1 创建实现服务的类
此类中提供的方法必须与Web Service(在services.xml中声明)中的operations对应。除非你提供了数据绑定,否则所有的方法只能接收一个参数,其类型为OMElement。
public class MyService{
public void ping(OMElement element){...}
public OMElement echo(OMElement element){...}
}
MyService.java
package userguide.example1;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import javax.xml.stream.XMLStreamException;
public class MyService {
public OMElement echo(OMElement element) throws XMLStreamException {
//Praparing the OMElement so that it can be attached to another OM Tree.
//First the OMElement should be completely build in case it is not fully built and still
//some of the xml is in the stream.
element.build();
//Secondly the OMElement should be detached from the current OMTree so that it can
// be attached some other OM Tree. Once detached the OmTree will remove its
// connections to this OMElement.
element.detach();
return element;
}
public void ping(OMElement element) throws XMLStreamException {
//Do some processing
}
public void pingF(OMElement element) throws AxisFault{
throw new AxisFault("Fault being thrown");
}
}
1.2.2 创建services.xml
Axis2使用services.xml来充当一个Web Servicea的配置文件。每一个使用Axis2部署的Web Service都必须拥有一个services.xml。
<services>
<description>
This is a sample Web Service with two operations,echo and ping.
</description>
<parameter name=”ServiceClass” locked=”false”>
userguide.example1.MyService
</parameter>
<operation name=”echo”>
<messageReceiver class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver”/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name=”ping”>
<messageReceiver class=”org.apache.receivers.RawXMLINOnlyMessageReceiver”/>
<actionMapping>urn:ping</actionMapping>
</operation>
</service>
注:The actionMapping is required only if you want to enable WS-Addressing.
可以创建一个services.xml,其中包含一组服务。这样在运行期,你可以在这些服务间共享信息。
<serviceGroup>
<service name=”Service1”>
<!--details for Services1-->
</service>
<service name=”Service2”>
<!--details for Services2-->
</service>
<module ref=”ModuleName”/>
<parameter name=”serviceGroupParam1” locked=”false”>value1</parameter>
</serviceGroup>
注:name of the service is a compulsory attribute.
1.2.3打包与部署
这里不再详述,参见《基于Tomcat5.0和Axis2开发Web Service应用实例 》。
2.使用Axis2底层APIs实现Web Service客户端
2.1ClientUtil
创建一个客户端通用的SOAP包装Util文件。封装"getEchoOMElement"和"getPingOMElement"分别对应"echo"和"ping"这两个operation。
ClientUtil.java
package userguide.clients;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
public class ClientUtil {
public static OMElement getEchoOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);
return method;
}
public static OMElement getPingOMElement() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("ping", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Ping String "));
method.addChild(value);
return method;
}
}
2.2EchoBlockingClient
Axis2向用户提供了从blocking single channel调用到non-blocking dual channel调用的多种调用Web Service的模式。下面用最简单的blocking调用机制来实现”MyService”中的"echo" operation。
EchoBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for synchronous single channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
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();
Options options = new Options();
options.setTo(targetEPR); // this sets the location of MyService service
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
OMElement result = sender.sendReceive(payload);
System.out.println(result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
绿色部分显示了为了调用一个Web Service而需要对operation作的设置。剩下的部分是用来创建OMElement,用来发送和显示相应的OMElement。
结果:
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
2.3 PingClient
在”MyService”中,我们有一种IN-ONLY模式的名为"ping"的operation。应用它的客户端代码如下:
PingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
/**
* Sample for fire-and-forget service invocation
* Message Exchage Pattern IN-Only
*/
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();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
/**
* We have to block this thread untill we send the request , the problem
* is if we go out of the main thread , then request wont send ,so
* you have to wait some time
*/
Thread.sleep(500);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
由于我们在访问一个IN-ONLY模式的operation,所以我们可以直接使用ServiceClient中的"fireAndForget()"方法来调用这个operation。而且那样做的话,不会阻塞发起端,因此,它会立刻将控制权返回给客户端。
2.4 EchoNonBlockingClient
在客户端EchoBlockingClient,一旦调用"serviceClient.sendReceive(payload);",客户端将会被阻塞直到operation完成。这种方式在有很多Web Service需要在一个单一的客户端应用程序中启动时很不可取。一种解决方法是使用Non-Blocking API来调用这些Web Services。Axis2提供给用户一种基于回叫机制的non-blocking API。
EchoNonBlockingClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
/**
* Sample for asynchronous single channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoNonBlockingClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
sender = new ServiceClient();
sender.setOptions(options);
sender.sendReceiveNonBlocking(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();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) { }
}
}
}
结果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1"
xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
sender.sendReceiveNonBlocking(payload, callback);这个调用接受一个callback对象作为参数。Axis2客户端API提供了一个抽象类CallBack,其中提供了方法:
public abstract void onComplete(AsyncResult result);
public abstract void onError(Exception e);
public boolean isComplete() {}
用户需要重写"onComplete " 和 "onError "方法。一旦客户端收到Web Service的response,onComplete方法将会被调用,这样将中止阻塞状态。
2.5EchoNonBlockingDualClient
当调用的Web Service需要很长一段时间来完成时,这种由Non-Blocking API提供的解决方式将有一定的局限性。这种局限性是由使用单一的传输连接来调用Web Service并接收response造成的。换句话说,客户端提供一种没有阻塞的调用机制,但request和response的传输使用单一的传输(双工方式)连接(如HTTP)。长时间运行的Web Service调用或Web Service调用使用单工传输方式(如SMTP)不能简单地利用一个没有阻塞的调用。
一种尝试地解决方法是request和response各自使用单独的传输连接(单工或双工均可)。这种方式产生的问题是如何解决相关性(关联request和response)。WS-Addressing提供了一种很好的解决方法,在头中使用<wsa:MessageID> 和 <wsa:RelatesTo> 标签。Axis2对这种基于关联机制的寻址方式提供了支持。
用户可以选择Blocking 或Non-Blocking APIs的Web Service,并使用两个传输连接。通过使用一个布尔标记,同一个API可以调用多个在两个传输连接上的Web Services(IN-OUT operations)。下例使用Non-Blocking API 以及两个传输连接来实现上文中提到的"echo" operation。
EchoNonBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AsyncResult;
import org.apache.axis2.client.async.Callback;
import javax.xml.namespace.QName;
/**
* Sample for asynchronous dual channel non-blocking service invocation.
* Message Exchage Pattern IN-OUT
* Ulitmate asynchronous service invocation sample.
*/
public class EchoNonBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
options.setAction("urn:echo"); // this is the action mapping we put within the service.xml
//Callback to handle the response
Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}
public void onError(Exception e) {
e.printStackTrace();
}
};
//Non-Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);//见注解①
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//have to ignore this
}
}
}
}
注解①
RE: [Axis2] 0.95 WS-Addressing web SERVICE-SIDE: module not found
I now have managed to get EchoNonBlockingDualClient working. I still can't get the original code to work, where ever I put addressing-0.95.mar, but the ConfigurationContext works.
The code I ended up with was:
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"C:\\axis2", null);
sender = new ServiceClient(sysContext, null);
with no need, obviously, for the .engageModule method.
I did discover though that the directory which the ConfigurationContext points to has to have two directories within it: "conf", which must contain the axis.xml configuration file, and the "modules" directory which contains addressing-0.95.mar.
在方法"options.setUseSeparateListener(...)"中的布尔标记通知通知Axis2引擎使用两个不同的传输连接来分别处理request和response。Finally中的 "serviceClient.finalizeInvoke()"方法通知Axis2引擎停用客户端的用于接收response的listener。
在我们运行客户端的例程之前,我们还有一件事情要做。如前面提到的,Axis2使用基于地址的关联机制,因此我们必须在服务器端和客户端“搭建”寻址模块。
结果:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://59.14.131.187:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__
</wsa:To>
<wsa:ReplyTo>
<wsa:Address>
http://www.w3.org/2005/08/addressing/anonymous
</wsa:Address>
</wsa:ReplyTo>
<wsa:From>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:From>
<wsa:FaultTo>
<wsa:Address>
http://127.0.0.1:8080/axis2/services/MyService
</wsa:Address>
</wsa:FaultTo>
<wsa:MessageID>
urn:uuid:B087CBB98F1B51A24711742241136206
</wsa:MessageID>
<wsa:Action>urn:echo</wsa:Action>
<wsa:RelatesTo wsa:RelationshipType="wsa:Reply">
urn:uuid:CA4B9513377E6E9E1511742241130391
</wsa:RelatesTo>
</soapenv:Header>
<soapenv:Body>
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>
Axis2 Echo String
</example1:Text>
</example1:echo>
</soapenv:Body>
</soapenv:Envelope>
[SimpleHTTPServer] Stop called
2.6 实现服务器端的寻址
根据Axis2的结构,寻址模块在"pre-dispatch"阶段已经给出它的句柄。因此,所谓的“搭建”仅仅是在”axis2.xml”(注意不是services.xml)增加一个模块的引用。现在将下面这行字加入到axis2.xml,该文件在"/webapps/axis2/WEB-INF/conf"目录下。
<module ref="addressing"/>
注: 一旦你改变了axis2.xml,你必须重启这个servlet容器,改变才能生效。
2.7 实现客户端的寻址
有两种方式。
一种方法是在%Axis2_HOME%\axis2-std-1.0-bin\modules目录下得到addressing-<version>.mar。并且在你的classpath中对其可见。(此种方法目前,我还没有调试成功,具体见注解①。下面的第二种方法可用)
另一种方法是创建一个ConfigurationContext,指定一个repository位置。Axis2支持repository的方式来保存服务和模块。
你可以使用二进制distribution作为repository,只要它含有一个Axis2 repository认可的repository结构(其中应包含services和modules目录)。ConfigurationContext 中含有Axis2体系的运行时的上下文信息。
如果你解压一个标准的二进制distribution到目录(譬如)$user_home/axis2/dist, 那么在 sender = new ServiceClient();之前加入(具体见EchoNonBlockingDualClient.java):
new ServiceClient();之前加入(具体见EchoNonBlockingDualClient.java):
ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
用"sender = new ServiceClient(configContext, null);" 替换 "sender = new ServiceClient();"
这样可以在客户端和服务器端都实现寻址。
2.8 EchoBlockingDualClient
这又是一个两路的传输的request/response客户端,但这次,我们使用一个Blocking API。实现机制和EchoNonBlockingDualClient差不多,唯一的不同是,这里不需要使用一个callback对象来处理response。
EchoBlockingDualClient.java
package userguide.clients;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import java.io.StringWriter;
/**
* Sample for synchronous dual channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public class EchoBlockingDualClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
ServiceClient sender = null;
try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();
options.setTo(targetEPR);
options.setAction("urn:echo");
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
//Blocking Invocation
ConfigurationContext sysContext = ConfigurationContextFactory
.createConfigurationContextFromFileSystem(
"D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);
sender = new ServiceClient(sysContext, null);
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
StringWriter writer = new StringWriter();
result.serialize(XMLOutputFactory.newInstance().createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally{
try {
sender.finalizeInvoke();
} catch (AxisFault axisFault) {
//
}
}
}
}
结果:
<example1:echo xmlns:example1="http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
<example1:Text>Axis2 Echo String </example1:Text>
</example1:echo>
[SimpleHTTPServer] Stop called
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/25592
发表评论
-
FastJSON 序列化、反序列化实现
2016-01-06 15:48 4851http://www.csdn.net/ar ... -
VPN专题笔记
2014-08-24 20:55 0安卓系统 使用VPN 教程 http://bbs.ptbus ... -
JAVA中使用FTPClient上传下载
2013-05-28 23:58 960JAVA中使用FTPClient上传下载 分类: JAVA 2 ... -
ftp
2013-05-28 23:57 843FTP服务器,则是在互联网上提供存储空间的计算机,它们依照 ... -
Websphere服务器内存如何修改
2012-12-05 10:31 1706一、jxl的java.lang.OutOfMemoryErro ... -
webservice开发指南
2012-09-28 23:44 2813http://www.360doc.com/co ... -
Websphere入门篇(一)-was6.0安装
2012-10-24 23:35 1220http://www.hashei.me/2009/04/wa ... -
关于 WebSphere 的应用部署
2012-10-15 00:36 935关于 WebSphere 的应用部署 http://www.c ...
相关推荐
总的来说,`org.apache.axis2.eclipse.service.plugin_1.7.8`是一个强大的工具,它简化了在Eclipse中使用Apache Axis2进行Web服务开发的工作流程,提升了开发者的生产力。通过集成开发环境的便利性,开发者可以更...
Web Service 远程调用技术 Web Service 是一种跨编程语言和跨操作系统平台的远程调用技术,通过 SOAP ...使用 Axis2 框架开发 Web Service 需要使用 Axis2 的工具生成 WSDL 文件,并使用 Axis2 的 API 调用 Web 服务。
【如何使用Eclipse开发Web Service】 在开发Web Service时,Eclipse作为一个强大的集成开发环境(IDE),提供了便捷的工具和插件支持。本篇将详细阐述如何在Eclipse中进行Web Service的开发。 1. **准备工作** ...
总的来说,Apache Axis2的Eclipse插件为Web服务开发提供了一站式的解决方案,它简化了服务端和客户端代码的生成,使得开发者可以更加专注于业务逻辑,而非底层通信细节。同时,与流行的Eclipse IDE的集成,使得开发...
AXIS简化了Web服务开发过程,使得开发者无需深入了解底层细节就能快速创建服务。 二、环境搭建 1. Java环境:首先确保你已经安装了JDK,并且设置了JAVA_HOME环境变量。 2. Axis下载与安装:从Apache官方网站下载...
【标题】"Axis2_Codegen_Wizard_1.3.0"是一款专为MyEclipse Web开发设计的Axis插件,其主要功能是自动化生成与Web服务相关的代码,极大地简化了开发过程,提高了开发效率。该插件是基于Apache Axis2框架的,Axis2是...
Axis2的核心概念是消息处理器和服务档案(Service Archive,SAR),后者包含了Web服务的所有元数据和实现代码。 Spring框架则是一个广泛使用的Java企业级应用开发框架,其核心特性包括依赖注入(Dependency ...
Axis1是Apache组织开发的一个开源Java Web Service框架,主要用于创建和部署Web服务。它允许开发者在Java平台上构建符合WS-I(Web Services Interoperability Organization)基本Profile标准的Web服务。本项目是一个...
Axis是Apache软件基金会开发的一个开放源代码工具,专门用于构建和部署Web服务。它基于Java平台,提供了强大的支持来实现SOAP(简单对象访问协议)和WSDL(Web服务描述语言)。 在Web服务的世界中,Axis扮演着重要...
1. **生成Stub类**:使用Axis提供的`wsdl2java`工具,根据Web服务的WSDL文件生成Java客户端 stub类和服务器端Skeleton类。 2. **编写服务端代码**:在服务端,通过继承或实现生成的Skeleton类,定义实际的业务逻辑。...
Apache Axis是一个开放源代码的Web服务框架,它允许开发人员将Java类转换为Web服务,并且可以逆向操作,即从Web Service Description Language (WSDL) 文件生成Java代码和相应的JAR文件。 描述中的“直接根据wsdl...
在实际的"Web Service Demo"中,你可能还会看到如何使用常见的开发工具,如Eclipse或Visual Studio,以及如何测试和调试Web服务。此外,现代Web服务还可能涉及到RESTful API的使用,它以更轻量级的方式提供服务,...
1. 复杂性:Axis 的使用需要具备一定的 Java 和 Web 服务开发经验。 2. 配置复杂:Axis 的配置过程较为复杂,需要在项目中添加多个 JAR 包。 3. 版本问题:Axis 的版本问题可能会导致兼容性问题。 Axis 是一个功能...
在WS(Web Service)领域,Axis2是Apache软件基金会开发的一个开放源代码的Web服务引擎,用于处理SOAP消息并提供Web服务的实现。它是一个强大的、高性能的、高度模块化的框架,支持多种协议,如HTTP、HTTPS、JMS等,...
在本文中,我们将深入探讨如何使用Spring Boot框架与Apache Axis2进行集成,以开发Web服务端应用程序。Spring Boot以其简洁的配置和开箱即用的功能,已成为Java领域中开发微服务的首选框架。而Axis2作为流行的Web...
2. **XFire (CXF)**:XFire(现为Apache CXF)是一个更现代的框架,它集成了Spring,使得服务端的开发更加简单,因为大部分逻辑都被封装到了底层API中。XFire支持直接配置生成WSDL,且能与Spring无缝集成,简化了...
Web服务(Web Service)是一种基于互联网的、采用标准XML(Extensible Markup Language)进行通信的软件系统,允许不同...使用这些工具,无论是开发人员还是测试人员,都可以更加专注于业务逻辑,而非底层通信细节。
2. **定制发布**:使用WSDD(Web Service Deployment Descriptor),这种方式更为灵活,允许开发者精细控制WebService的各个方面,包括端口、命名空间等。需要编写一个wsdd.xml文件来描述服务部署详情。 ##### 2.4 ...
它提供了一套简洁的API,支持Web Service的各种标准协议,如JSR181、WSDL2.0、JAXB2和WS-Security等,简化了Web Service应用程序的开发过程。XFire因其与Spring框架的紧密集成而备受青睐,这使得在Spring环境中构建...
5. Axis2或Metro:这些是Java中的Web Service框架,提供了更高级别的抽象,简化了Web服务的开发和部署。 在实际应用中,一个简单的Web Service实例可能包括以下步骤: 1. 定义服务接口:使用Java接口来定义服务的...