Invoking JAX-WS web services asynchronously
Java™ API for XML-Based Web Services (JAX-WS) provides support for invoking web services using an asynchronous client invocation. JAX-WS provides support for both a callback and polling model when calling web services asynchronously. Both the callback model and the polling model are available on the Dispatch client and the Dynamic Proxy client.
Before you begin
Develop a JAX-WS Dynamic Proxy or Dispatch client. When developing Dynamic Proxy clients, after
you generate the portable client artifacts from a Web Services Description Language (WSDL) file by
using the wsimport command, the generated service endpoint interface (SEI) does
not have asynchronous methods included in the interface. Use JAX-WS bindings to add the asynchronous
callback or polling methods on the interface for the Dynamic Proxy client. To enable asynchronous
mappings, you can add the jaxws:enableAsyncMapping
binding declaration to the WSDL
file. For more information on adding binding customizations to generate an asynchronous interface,
see chapter 8 of the JAX-WS specification.
jaxws:enableAsyncMapping
binding declaration, ensure that the corresponding
response message in your WSDL file contains only one <wsdl:part>
element. When a
response message does not contain a <wsdl:part>
element, the request acts as a
two-way request, but the actual response that is sent back is empty. The wsimport
command does not properly handle an empty response message. Also, the wsimport
command doesn’t support enabling asynchronous calls when multiple <wsdl:part>
elements exist in the response message. To avoid these scenarios, you can either remove the response
message from the operation, which makes your operation a one-way operation, or you can add a single
<wsdl:part>
element to your response message.For more information on the usage, syntax and parameters for the wsimport command, see the wsimport command for JAX-WS applications documentation.
About this task
An asynchronous invocation of a web service sends a request to the service endpoint and then
immediately returns control to the client program without waiting for the response to return from
the service. JAX-WS asynchronous web service clients consume web services using either the callback
approach or the polling approach. Using a polling model, a client can issue a request and receive a
response object that is polled to determine if the server has responded. When the server responds,
the actual response is retrieved. Using the callback model, the client provides a callback handler
to accept and process the inbound response object. The handleResponse()
method of
the handler is called when the result is available. Both the polling and callback models enable the
client to focus on continuing to process work without waiting for a response to return, while
providing for a more dynamic and efficient model to invoke web services. Polling invocations are
valid from Enterprise JavaBeans (EJB) clients or Java Platform, Enterprise Edition
(Java EE)
application clients. Callback invocations are valid only from Java EE application clients.
- Using the callback asynchronous invocation model
- To implement an asynchronous invocation that uses the callback model, the client provides an
AsyncHandler
callback handler to accept and process the inbound response object. The client callback handler implements thejavax.xml.ws.AsyncHandler
interface, which contains the application code that is run when an asynchronous response is received from the server. Thejavax.xml.ws.AsyncHandler
interface contains thehandleResponse(java.xml.ws.Response)
method that is called after the run time has received and processed the asynchronous response from the server. The response is delivered to the callback handler in the form of ajavax.xml.ws.Response
object. The response object returns the response content when theget()
method is called. Additionally, if an error was received, then an exception is returned to the client during that call. The response method is then invoked according to the threading model used by the executor method,java.util.concurrent.Executor
on the client'sjava.xml.ws.Service
instance that was used to create the Dynamic Proxy or Dispatch client instance. The executor is used to invoke any asynchronous callbacks registered by the application. Use thesetExecutor
andgetExecutor
methods to modify and retrieve the executor configured for your service.
- Using the polling asynchronous invocation model
- Using the polling model, a client can issue a request and receive a response object that can
subsequently be polled to determine if the server has responded. When the server responds, the
actual response can then be retrieved. The response object returns the response content when the
get()
method is called. The client receives an object of typejavax.xml.ws.Response
from theinvokeAsync
method. That Response object is used to monitor the status of the request to the server, determine when the operation has completed, and to retrieve the response results.
- Using an asynchronous message exchange
- By default, asynchronous client invocations do not have asynchronous behavior of the message
exchange pattern on the wire. The programming model is asynchronous; however, the exchange of
request or response messages with the server is not asynchronous. To use an asynchronous message
exchange, the
com.ibm.websphere.webservices.use.async.mep
property must be set on the client request context with a boolean value oftrue
. When this property is enabled, the messages exchanged between the client and server are different from messages exchanged synchronously. With an asynchronous exchange, the request and response messages have WS-Addressing headers added that provide additional routing information for the messages. Another major difference between asynchronous and synchronous message exchange is that the response is delivered to an asynchronous listener that then delivers that response back to the client. For asynchronous exchanges, there is no timeout that is sent to notify the client to stop listening for a response. To force the client to stop waiting for a response, issue aResponse.cancel()
method on the object returned from a polling invocation or aFuture.cancel()
method on the object returned from a callback invocation. The cancel response does not affect the server when processing a request.
<soapenv:Header>
<wsa:To>http://target.bar.com:81/LiteSecurityService/SecurityService</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://myhost:2146/axis2/services/LiteSecurityService.
WSRMServicePort/AnonOutInOp?IBMwebservicesID=922A5DC38A337C4CEF1168347862705
</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:922A5DC38A337C4CEF1168347862403</wsa:MessageID>
<wsa:Action>getEndpointReference</wsa:Action>
</soapenv:Header>
To
resolve this issue, configure the client to send the location details for the asynchronous listener
in IP format, by adding the following system property to the Java virtual machine. Note that
by transmitting the IP address, you lose the benefits of DHCP.
-Dcom.ibm.websphere.webservices.transportEPRInIPAddr=yes
Procedure
Results
Example
@WebService
public interface CreditRatingService {
// Synchronous operation.
Score getCreditScore(Customer customer);
// Asynchronous operation with polling.
Response<Score> getCreditScoreAsync(Customer customer);
// Asynchronous operation with callback.
Future<?> getQuoteAsync(Customer customer,
AsyncHandler<Score> handler);
}
- Using the callback method
- The callback method requires a callback handler that is shown in the following example. When
using the callback procedure, after a request is made, the callback handler is responsible for
handling the response. The response value is a response or possibly an exception. The
Future<?>
method represents the result of an asynchronous computation and is checked to see if the computation is complete. When you want the application to find out if the request is completed, invoke theFuture.isDone()
method. Note that theFuture.get()
method does not provide a meaningful response and is not similar to theResponse.get()
method.
CreditRatingService svc = ...;
Future<?> invocation = svc.getCreditScoreAsync(customerTom,
new AsyncHandler<Score>() {
public void handleResponse (
Response<Score> response)
{
score = response.get();
// process the request...
}
}
);
- Using the polling method
- The following example illustrates an asynchronous polling client:
CreditRatingService svc = ...;
Response<Score> response = svc.getCreditScoreAsync(customerTom);
while (!response.isDone()) {
// Do something while we wait.
}
score = response.get();