Programming Advanced Features of WebLogic Web Services Using JAX-WS

      

Invoking a Web Service Using Asynchronous Request-Response

The following sections describe how to invoke a Web Service using asynchronous request-response:

 


Overview of the Asynchronous Request-Response Feature

When you invoke a Web Service synchronously, the invoking client application waits for the response to return before it can continue with its work. In cases where the response returns immediately, this method of invoking the Web Service is common. However, because request processing can be delayed, it is often useful for the client application to continue its work and handle the response later on, or in other words, use the asynchronous request-response feature of WebLogic Web Services.

When implementing asynchronous request-response in your client, rather than invoking the operation directly, you invoke an asynchronous flavor of the same operation. (This asynchronous flavor of the operation is automatically generated by the clientgen Ant task.) For example, rather than invoking an operation called addNumbers directly, you would invoke addNumbersAsync instead. The asynchronous flavor of the operation always returns void, even if the original operation returns a value. You then include methods in your client that handle the asynchronous response or failures when it returns later on. You put any business logic that processes the return value of the Web Service operation invoke or a potential failure in these methods.

 


Using Asynchronous Request-Response: Main Steps

The following procedure describes how to create a client that asynchronously invokes an operation in a Web Service. For clarity, it is assumed in the procedure that:

It is further assumed that you have set up an Ant-based development environment and that you have a working build.xml file to which you can add targets for running the jwsc Ant task and deploying the generated service. For more information, see the following sections in Getting Started With WebLogic Web Services Using JAX-WS

 


Creating the Asynchronous Client

The following example shows a simple client file, AsyncClient, that has a single method, AddNumbersTestDrive, that asynchronously invokes the AddNumbersAsync method of the AddNumbersService service. The Java code in bold is described following the code sample.

package examples.webservices.async.client;
import java.util.concurrent.ExecutionException;

import java.util.concurrent.TimeUnit;
import javax.xml.ws.BindingProvider;
import java.util.concurrent.Future;

import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
public class AsyncClient  {
   private AddNumbersPortType port = null;

protected void setUp() throws Exception {
AddNumbersService service = new AddNumbersService();
port = service.getAddNumbersPort();
String serverURI = System.getProperty("wls-server");
((BindingProvider) port).getRequestContext().put(
BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://" + serverURI + "/JAXWS_ASYNC/AddNumbersService");
}
/**

*
* Asynchronous callback handler
*/
class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
private AddNumbersResponse output;
public void handleResponse(Response<AddNumbersResponse> response) {
try {
output = response.get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
AddNumbersResponse getResponse() {
return output;
}
}
   public void AddNumbersTestDrive() throws Exception {

int number1 = 10;
int number2 = 20;
AddNumbersCallbackHandler callbackHandler =
new AddNumbersCallbackHandler();
Future<?> resp = port.addNumbersAsync(number1, number2,
callbackHandler);
      // For the purposes of a test, block until the async call completes

resp.get(5L, TimeUnit.MINUTES);
int result = callbackHandler.getResponse().getReturn();
}
}

When creating the asynchronous client file, you need to perform the following tasks:

  1. Create an asynchronous handler that implements the javax.xml.ws.AsyncHandler<T> interface. The asynchronous handler defines one method, handleResponse, that enables clients to receive callback notifications at the completion of service endpoint operations that are invoked asynchronously. The type should be set to AddNumberResponse.
    class AddNumbersCallbackHandler implements AsyncHandler<AddNumbersResponse> {
    
    private AddNumbersResponse output;
       public void handleResponse(Response<AddNumbersResponse> response) {
    
    try {
    output = response.get();
    } catch (ExecutionException e) {
    e.printStackTrace();
    } catch (InterruptedException e) {
    e.printStackTrace();
             }
    
    }
          AddNumbersResponse getResponse() {
    
    return output;
    }
    }

  2. Instantiate the asynchronous callback handler.
    AddNumbersCallbackHandler callbackHandler = 
    
    new AddNumbersCallbackHandler();

  3. Instantiate the AddNumbersService Web Service and call the asynchronous version of the Web Service method, addNumbersAsync, passing a handle to the asynchronous callback handler.
    AddNumbersService service = new AddNumbersService();
    
    port = service.getAddNumbersPort();
    ...
    Future<?> resp = port.addNumbersAsync(number1, number2,
    
    callbackHandler);

    java.util.concurrent.Future represents the result of an asynchronous computation and provides methods for checking the status of the asynchronous task, getting the result, or canceling the task execution.

  4. Get the result of the asynchronous computation. In this example, a timeout value is specified to wait for the computation to complete.
    resp.get(5L, TimeUnit.MINUTES);
    

  5. Use the callback handler to access the response message.
    int result = callbackHandler.getResponse().getReturn();
    

 


Applying Asynchronous Binding Declaration to WSDL

To generate asynchronous polling and callback methods in the service endpoint interface when the WSDL is compiled, enable the jaxws:enableAsyncMapping binding declaration in the WSDL file.

You can create an external binding declarations file that contains all binding declarations for a specific WSDL or XML Schema document. Then, pass the binding declarations file to the <binding> child element of the wsdlc, jwsc, or clientgen Ant task.

The following provides an example of a binding declarations file that enables the jaxws:enableAsyncMapping binding declaration:

<bindings

xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="AddNumbers.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions">
<package name="examples.webservices.async"/>
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
</bindings>

For more information, see “Creating an External Binding Declarations File Using JAX-WS Binding Declarations” in Getting Started With WebLogic Web Services Using JAX-WS.

 


Updating the build.xml File When Using Asynchronous Request-Response

To update a build.xml file to generate client artifacts and compile the client that invokes a Web Service operation asynchronously, add taskdefs and a build-client target that includes a reference to the external binding declarations file containing the asynchronous binding declaration. See the description following the example for details.

<taskdef name="clientgen"

classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build_client">
<clientgen

type="JAXWS"
wsdl="AddNumbers.wsdl"
destDir="${clientclasses.dir}"
packageName="examples.webservices.async.client">
<binding file="jaxws-binding.xml" />
</clientgen>
<javac
srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
includes="**/*.java"/>
    <javac

srcdir="src" destdir="${clientclass-dir}"
includes="examples/webservices/hello_world/client/**/*.java"/>
</target>

Use the taskdef Ant task to define the full classname of the clientgen Ant tasks. Apply the asynchronous binding declaration by specifying an external binding declarations file, as described in Applying Asynchronous Binding Declaration to WSDL. In this case, the clientgen Ant task generates both synchronous and asynchronous flavors of the Web Service operations in the JAX-WS stubs.