38.5. Implementing an Asynchronous Client with the Callback Approach
Overview
An alternative approach to making an asynchronous operation invocation is to implement a callback class. You then call the asynchronous remote method that takes the callback object as a parameter. The runtime returns the response to the callback object.
To implement an application that uses callbacks, do the following:
- Create a callback class that implements the
AsyncHandler
interface.NoteYour callback object can perform any amount of response processing required by your application. - Make remote invocations using the
operationNameAsync()
that takes the callback object as a parameter and returns aFuture<?>
object. - If your client requires access to the response data, you can poll the returned
Future<?>
object'sisDone()
method to see if the remote endpoint has sent the response.TipIf the callback object does all of the response processing, it is not necessary to check if the response has arrived.
Implementing the callback
The callback class must implement the
javax.xml.ws.AsyncHandler
interface. The interface defines a single method:
void handleResponse(Response<T> res);
The Apache CXF runtime calls the
handleResponse()
method to notify the client that the response has arrived. Example 38.8, “The javax.xml.ws.AsyncHandler
Interface” shows an outline of the AsyncHandler
interface that you must implement.
Example 38.8. The javax.xml.ws.AsyncHandler
Interface
public interface javax.xml.ws.AsyncHandler { void handleResponse(Response<T> res) }
Example 38.9, “Callback Implementation Class” shows a callback class for the greetMeSometime operation defined in Example 38.1, “WSDL Contract for Asynchronous Example”.
Example 38.9. Callback Implementation Class
package demo.hw.client; import javax.xml.ws.AsyncHandler; import javax.xml.ws.Response; import org.apache.hello_world_async_soap_http.types.*; public class GreeterAsyncHandler implements AsyncHandler<GreetMeSometimeResponse> { 1 private GreetMeSometimeResponse reply; 2 public void handleResponse(Response<GreetMeSometimeResponse> response) { try { reply = response.get(); } catch (Exception ex) { ex.printStackTrace(); } } 3 public String getResponse() { return reply.getResponseType(); } }
The callback implementation shown in Example 38.9, “Callback Implementation Class” does the following:
- 1
- Defines a member variable,
response
, that holds the response returned from the remote endpoint. - 2
- Implements
handleResponse()
.This implementation simply extracts the response and assigns it to the member variablereply
. - 3
- Implements an added method called
getResponse()
.This method is a convenience method that extracts the data fromreply
and returns it.
Implementing the consumer
Example 38.10, “Callback Approach for an Asynchronous Operation Call” illustrates a client that uses the callback approach to make an asynchronous call to the GreetMeSometime operation defined in Example 38.1, “WSDL Contract for Asynchronous Example”.
Example 38.10. Callback Approach for an Asynchronous Operation Call
package demo.hw.client; import java.io.File; import java.util.concurrent.Future; import javax.xml.namespace.QName; import javax.xml.ws.Response; import org.apache.hello_world_async_soap_http.*; public final class Client { ... public static void main(String args[]) throws Exception { ... // Callback approach 1 GreeterAsyncHandler callback = new GreeterAsyncHandler(); 2 Future<?> response = port.greetMeSometimeAsync(System.getProperty("user.name"), callback); 3 while (!response.isDone()) { // Do some work } 4 resp = callback.getResponse(); ... System.exit(0); } }
The code in Example 38.10, “Callback Approach for an Asynchronous Operation Call” does the following:
- 1
- Instantiates a callback object.
- 2
- Invokes the
greetMeSometimeAsync()
that takes the callback object on the proxy.The method call returns theFuture<?>
object to the client immediately. The Apache CXF runtime handles the details of receiving the reply from the remote endpoint, invoking the callback object'shandleResponse()
method, and populating theResponse<GreetMeSometimeResponse>
object.NoteThe runtime transmits the request to the remote endpoint'sgreetMeSometime()
method and handles the details of the asynchronous nature of the call without the remote endpoint's knowledge. The endpoint, and therefore the service implementation, does not need to worry about the details of how the client intends to wait for a response. - 3
- Uses the returned
Future<?>
object'sisDone()
method to check if the response has arrived from the remote endpoint. - 4
- Invokes the callback object's
getResponse()
method to get the response data.