在旧的基于JAX-RPC的webservice编程model中,是不支持异步的service 调用的,在最新的Jax-ws webservice 编程model中,加入了对webservice的异步调用的支持。
首先我来讲一下它的原理,大家不要以为在异步的调用下,从client到server 之间的soap message 流也是异步的,其实不是,Soap/Http 协议在同步跟异步的调用下是一样的,都是客户端的service在运行时打开一个connectin,发送请求,然后接收返回,这些都在同一个connection中。这种方式对我们有什么影响呢? 从客户端程序的角度来讲,没有影响,客户端的编程模型是由WSDL中的messages跟port types 来定义的,只要这些东西没有改变,request 跟response是不是在同一个Tcp/ip 的session 中来发送对与我们来说没由影响,然后从架构跟资源的角度来讲,对我们的影响就大了,把连接层的资源跟应用层的程序运行状态绑定起来是由许多弊端的,假如在异步调用时,程序运行出现了异常,将会导致连接层的资源被一直占用,这样会极大的影响我们程序的,稳定性,可靠性,资源的使用跟性能。
所以WebSphere Application Server V7提供了一个简单的实现,能够实现真实的异步soap Message,下面我们会详细讲解。
当前Jax-ws 提供了两种编程模型。
1.Polling client
2.CallBack client
下面我们分别就这两种编程模型进行讲解。
当你启用了异步调用功能时,当你用工具生成stub时,Jax-ws会给你每个operation 生成三个方法
a.An synchronous method
b.An asynchronous polling method
c.An asynchronous callback method
以下是一个生成的client-side Interface example
import java.util.concurrent.Future;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.Response;
import javax.xml.ws.ResponseWrapper;
@WebService(name = "HelloMessenger", targetNamespace =
"http://hello.itso/")
@XmlSeeAlso({
ObjectFactory.class
})
public interface HelloMessenger {
@WebMethod(operationName = "sayHello")
@RequestWrapper(localName = "sayHello", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHello")
@ResponseWrapper(localName = "sayHelloResponse", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHelloResponse")
//Polling clients
public Response<SayHelloResponse> sayHelloAsync(
@WebParam(name = "arg0", targetNamespace = "")
String arg0);
@WebMethod(operationName = "sayHello")
@RequestWrapper(localName = "sayHello", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHello")
@ResponseWrapper(localName = "sayHelloResponse", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHelloResponse")
// Call back clients
public Future<?> sayHelloAsync(
@WebParam(name = "arg0", targetNamespace = "")
String arg0,
@WebParam(name = "asyncHandler", targetNamespace = "")
AsyncHandler<SayHelloResponse> asyncHandler);
@WebMethod
@WebResult(targetNamespace = "")
@RequestWrapper(localName = "sayHello", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHello")
@ResponseWrapper(localName = "sayHelloResponse", targetNamespace =
"http://hello.itso/", className = "itso.hello.SayHelloResponse")
//同步clients
public String sayHello(
@WebParam(name = "arg0", targetNamespace = "")
String arg0);
}
下面来详细讲述polling clients:
在这种异步模式下,当异步clients调syHelloAsync 方法,将会返回一个response object, 这个response Object 提供了一些方法来让你查询是否response已经返回,是否取消一个response,以及取得返回的response.如以下实例代码,你可以用sayHelloAsync .isDone来检查是否response已经返回。用sayHelloAsync .get()来取得返回的一个包装过的对象(SayHelloResponse),里面包含真实的返回值。
import javax.xml.ws.Response;
import itso.hello.HelloMessenger;
import itso.hello.HelloMessengerService;
import itso.hello.SayHelloResponse;
public class HelloAsyncPollingClient {
public static void main(String... args) throws Exception {
HelloMessengerService service = new HelloMessengerService();
HelloMessenger port = service.getHelloMessengerPort();
Response<SayHelloResponse> sayHelloAsync =
port.sayHelloAsync("Thilde");
//判断是否已经返回
while ( ! sayHelloAsync.isDone() ) {
// Do something useful for now
}
// Web service endpoint has now responded:
//取得包装过的返回对象
SayHelloResponse sayHelloResponse = sayHelloAsync.get();
//取得真实返回值
String message = sayHelloResponse.getReturn();
System.out.println(message);
}
}
Callbacking 模型的client 示例代码如下:
import itso.hello.HelloMessenger;
import itso.hello.HelloMessengerService;
import itso.hello.SayHelloResponse;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
public class HelloAsyncCallbackClient {
public static void main(String... args) throws Exception {
HelloMessengerService service = new HelloMessengerService();
HelloMessenger port = service.getHelloMessengerPort();
port.sayHelloAsync("Teresa", new AsyncHandler<SayHelloResponse>()
{
public void handleResponse(Response<SayHelloResponse> res) {
try {
SayHelloResponse response = res.get();
String message = response.getReturn();
System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
由以上代码可知,callback类型的client要传入一个javax.xml.ws.AsyncHandler类型的匿名内部类,当soap Message 到达时,Jax-ws会调handleResponse这个方法来处理response.
以上就时Polling Client 跟Callback型的异步client的概念及使用示例,开始我也讲过,实际上这种所谓的异步调用有很大的弊端的。在最新的websphere V7上提供一种解决方案。提供了一种真实的异步message的交换方式。在使用时你需要给client-side proxy配置一个特别的属性,示例如下:
Map<String, Object> requestContext =
((BindingProvider)port).getRequestContext():
// Configure the client for wire-level asynchronous message exchange
requestContext.put("com.ibm.websphere.webservices.use.async.mep",
true);
当你启用这种异步message交换机制时,client端会在request发出后在一个单独的channel上来监听和接收response message.当然,client在发出request时,会使用WS-Addressing 来向server提供 ReplyTo endpoint reference(ERP),当请求发出去以后当前的这个connection就会关闭,当servicer处理完请求时,它会根据client端提供的ERP(ReplyTo endpoint reference)重新初始化一个connection 来发送一个response.
当然了,这种机制也有弊端就时可移植性太差,只能在Websphere V7上使用。
分享到:
相关推荐
本实例主要讲解如何使用ksoap2这个库来调用Java或.NET的Web服务。ksoap2是一个轻量级、高效且功能丰富的Android SOAP客户端库。 首先,你需要从给定的下载地址获取ksoap2的库文件:...
这是最早的AJAX调用Web服务的方式,通过创建XMLHttpRequest实例,我们可以向服务器发送HTTP请求,并处理返回的数据。以下是一个基本的示例: ```javascript var xhr = new XMLHttpRequest(); xhr.open('GET', '...
总结来说,"手把手xfire开发WS入门实例"涉及到的知识点涵盖了Web Service的基本概念、核心协议(SOAP和WSDL)、选择Web Service通信方式的比较、开发工具和框架(XFire和Axis),以及相关技术与SOA架构。通过学习...
本实例将详细介绍如何在Android中调用Web服务,以实现一个可运行的解决方案。 一、理解Web服务 Web服务是一种基于互联网的标准,允许应用程序之间交换数据。SOAP是一种XML格式的消息传递协议,常用于企业级服务,...
Web Service ASMX 是一种基于.NET框架的Web服务技术,它允许开发者创建和部署Web服务,供其他应用程序(包括Android应用)调用。本教程将深入讲解如何在Android应用中访问ASMX类型的Web服务。 首先,我们要介绍关键...
传统的ASP.NET Web服务,通常基于ASMX(ASP.NET Web Service)处理程序,工作方式是接收请求后,直接调用对应的方法,通常是同步执行。例如,如果有一个名为`LengthyProcedure`的方法,它接收一个`milliseconds`参数...
本文将详细介绍如何在Android中调用Web Service,并提供一个实例代码的更改,以便进行异步处理,提高应用性能。 首先,我们需要理解Web Service的概念。Web Service是一种基于网络的、能够被其他应用程序(如...
总之,这个压缩包提供了一个深入理解WebService同步与异步调用的实例,同时涵盖了C#、SQL Server数据库操作以及可能的跨域通信和数据交换。通过分析和学习这段代码,你可以提升在Web服务开发和分布式系统通信方面的...
在这个实例中,我们将关注如何在Android应用中调用Web Service,具体是通过使用一个名为KSOAP2的第三方库。 ### KSOAP2简介 KSOAP2是一个轻量级的库,专门用于Android平台,它允许Android应用程序通过HTTP/HTTPS...
Web Service是一种基于开放标准的互操作机制,允许不同应用程序和平台通过互联网进行通信。这种通信是基于XML(eXtensible Markup Language)的,确保数据能够在各种编程语言和操作系统之间无缝传递。 【SOAP】 ...
Call<YourResponseModel> call = service.fetchData(); call.enqueue(new Callback() { @Override public void onResponse(Call<YourResponseModel> call, Response<YourResponseModel> response) { if ...
在Android开发中,与Web Service进行交互是常见的需求,用于实现移动应用与远程服务器的数据交换。本Demo旨在演示如何在Android应用中调用Web Service,从而实现数据的获取和发送。我们将主要关注以下几个方面:XML...
1. **构建SOAP请求**:首先,你需要创建一个`SoapObject`实例,指定Web Service的命名空间和你要调用的方法名。命名空间通常可以在Web Service的WSDL文档中找到,而方法名对应你要执行的服务操作。例如: ```java ...
4. 处理响应:接口方法会返回一个Call对象,通过enqueue()异步调用或者execute()同步调用,并提供Callback处理结果。 五、安全和性能优化 - 使用HTTPS确保数据传输的安全性。 - 使用缓存策略减少网络请求次数,...
创建一个`HttpTransportSE`实例,指定Web Service的WSDL URL。 ```java HttpTransportSE ht = new HttpTransportSE("http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl"); ``` 5. **调用...
5. **调用Web服务**:通过HttpTransportSE对象的`call`方法执行请求。 ```java ht.call(null, envelope); ``` 6. **处理响应**:最后,从envelope中获取并解析响应结果。 ```java SoapObject soapObject = ...
代理类通常会提供`BeginXXX`和`EndXXX`方法对,用于异步调用Web服务方法。 6. **安全性和身份验证**:调用Web服务可能需要身份验证。C#支持多种安全模式,如基本身份验证、Windows身份验证或证书身份验证。这通常...