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
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.
Supported configurations: When
you run the
wsimport tool and enable asynchronous
invocation through the use of the JAX-WS enableAsyncMapping binding
declaration, ensure that the corresponding response message your WSDL
file does not contain parts. When a response message does not contain
parts, the request acts as a two-way request, but the actual response
that is sent back is empty. The
wsimport tool does
not correctly handle a void response. To avoid this scenario, you
can remove the output message from the operation which makes your
operation a one-way operation or you can add a
<wsdl:part> to
your message. For more information on the usage, syntax and parameters
for the
wsimport tool, see the wsimport command
for JAX-WS applications documentation.
sptcfg
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 the javax.xml.ws.AsyncHandler interface,
which contains the application code that is run when an asynchronous
response is received from the server. The javax.xml.ws.AsyncHandler interface
contains the handleResponse(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 a javax.xml.ws.Response object.
The response object returns the response content when the get() 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's java.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 the setExecutor and getExecutor 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 type javax.xml.ws.Response from the invokeAsync 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 of true.
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 a Response.cancel() method
on the object returned from a polling invocation or a Future.cancel() method
on the object returned from a callback invocation. The cancel response
does not affect the server when processing a request.
Avoid trouble: The location
of the asynchronous listener is sent to the server, so that the service
can reply to the client. On Windows operating
systems, the local host name is used by default, because it is compatible
with Dynamic Host Configuration Protocol (DHCP). However, if the server
cannot resolve the host name, the client application does not receive
replies from the target service. For example, a client application
is hosted on the workstation myhost.bar.com. In the following SOAP
message header, the client application sends the short name myhost
as its host details. Unless the target server can resolve myhost to
myhost.bar.com, subsequent replies do not reach the client application:
<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
gotcha
Example
The following example illustrates a web service interface
with methods for asynchronous requests from the client.
@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 the Future.isDone() method.
Note that the Future.get() method does not provide
a meaningful response and is not similar to the Response.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();