异步调用是指客户端发出调用服务端的请求,不必一直等待服务器的响应,在服务器返回结果之前,客户端可以执行其他的操作。
客户端异步调用web service ,服务端web service与普通web service一样,没有特殊要求,客户端基本有两种实现方式:
- 在客户端使用多线程,每个线程负责一个web service,也就是说一个线程对应一个web service,主线程并不负责web service的调用,这样可以模拟实现web service的异步调用。
- RPCServiceClient 类提供了一个 invokeNonBlocking 方法可以通过异步的方式来访问 WebService。
服务器端:
public class AsyncCallService {
public String getName(){
try {
System.out.println("getName方法正在执行。。。。。。");
//为了效果掩饰,服务端休眠3秒
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "异步调用返回";
}
}
客户端:
一、多线程实现方式:
public class AsyncCallServiceClient implements Runnable{
private RPCServiceClient client;
public AsyncCallServiceClient(RPCServiceClient client){
this.client = client;
}
@Override
public void run() {
try {
//调用的方法
final QName qName = new QName("http://test.com","getName");
//传参
Object[] oArgs = new Object[]{};
Class[] rtnType = new Class[]{String.class};
String result = (String) client.invokeBlocking(qName, oArgs, rtnType)[0];
System.out.println(result);
} catch (AxisFault e) {
e.printStackTrace();
}
}
}
public class AsyncCallServiceClient2 implements Runnable{
@Override
public void run() {
System.out.println("线程2执行。。。。。。");
}
}
public class AsyncCallMain {
public static void main(String[] args) {
try {
RPCServiceClient client = new RPCServiceClient();
Options options = client.getOptions();
EndpointReference targetEPR = new EndpointReference("http://localhost:8080/mywebservice/services/asyncCallService");
options.setTo(targetEPR);
Thread t1 = new Thread(new AsyncCallServiceClient(client));
Thread t2 = new Thread(new AsyncCallServiceClient2());
t1.start();
t2.start();
System.out.println("主函数剩余操作执行。。。");
} catch (AxisFault e) {
e.printStackTrace();
}
}
}
执行结果:
服务器:
客户端:
二、RPCServiceClient提供的invokeNonBlocking方法
public class AsyncCallServiceClient {
public static void main(String[] args) {
try {
RPCServiceClient client = new RPCServiceClient();
Options options = client.getOptions();
EndpointReference targetEPR = new EndpointReference("http://localhost:8080/mywebservice/services/asyncCallService");
options.setTo(targetEPR);
//调用的方法
final QName qName = new QName("http://test.com","getName");
//传参
Object[] oArgs = new Object[]{};
//异步调用
client.invokeNonBlocking(qName, oArgs, new AxisCallback() {
//异步调用时执行的方法
/**
* 返回xml格式的数据:
* <?xml version="1.0" encoding="utf-8"?>
* <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
* <soapenv:Header></soapenv:Header>
* <soapenv:Body>
* <ns:getNameResponse xmlns:ns="http://test.com">
* <ns:return>异步调用返回</ns:return>
* </ns:getNameResponse>
* </soapenv:Body>
* </soapenv:Envelope>
*
* 通过解析该xml数据,取得返回值
*/
@Override
public void onMessage(MessageContext context) {
Iterator it = context.getEnvelope().getChildElements();
while(it.hasNext()){
Object obj = it.next();
if(obj instanceof OMElement){
OMElement ome = (OMElement)obj;
OMElement firstEle = ome.getFirstElement();
if(firstEle != null && !firstEle.equals("")){
firstEle = firstEle.getFirstElement();
System.out.println("返回值信息:"+firstEle.getText());
}
}
}
}
@Override
public void onFault(MessageContext context) {
}
@Override
public void onError(Exception exception) {
}
@Override
public void onComplete() {
}
});
System.out.println("异步调用!!!!!!");
//阻止程序退出
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}