| Asynchronous web services with JBoss WS |
| Written by Mark S. | |||||
|
Developing rigorous and responsive web service client applications has always been a challenge for architects and developers working with SOA. JAX-WS 2.0 comes with one effective solution to this problem: asynchronous web service invocation. In this article, we will provide an exposition of this technology with examples built upon the reference implementation.
The JAX-WS programming model offers two models for invoking operations asynchronously – polling and callback. Both methods allow the client to continue processing while waiting for a response. Let's see an example taken from the JAX-WS suite examples:
package org.jboss.test.ws.jaxws.samples.asynchronous;
import java.util.concurrent.Future;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
@WebService(name = "Endpoint", targetNamespace = "http://org.jboss.ws/jaxws/asynchronous")
@SOAPBinding(style = Style.RPC)
public interface Endpoint
{
@WebMethod(operationName = "echo")
public Response
And this is the Service implementation class:
package org.jboss.test.ws.jaxws.samples.asynchronous;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import org.jboss.logging.Logger;
@WebService(name = "Endpoint", targetNamespace = "http://org.jboss.ws/jaxws/asynchronous")
@SOAPBinding(style = Style.RPC)
public class EndpointBean
{
private static Logger log = Logger.getLogger(EndpointBean.class);
@WebMethod
@WebResult(name = "result")
public String echo(@WebParam(name = "String_1") String msg)
{
log.info("echo: " + msg);
return msg;
}
}
As you can see the SEI has two methods echoAsynch each one is implementing a different strategy:
public Response<String> echoAsync(@WebParam(name = "String_1") String string1); This will use a pollig or "pull strategy" : once the initial request is made the client is free to pursue other work until the request completes. This enables the client to execute other tasks that don't depend on the outcome of the request. Once the request completes, the response is made available to the client. On the other hand, using this method: public Future<?> echoAsync(@WebParam(name = "String_1") String string1, @WebParam(name = "asyncHandler") AsyncHandler<String> asyncHandler); the actual response is processed by the specified AsyncHandler implementation. Once the response is made available to the callback handler, the code flow is much the same as with polling client.
The web service client
We'll examine at first the Dynamic Proxy approach: the dynamic proxy is the high level API to access web services, here you create an instance of a client proxy using one of getPort methods on the Service.
package org.jboss.test.ws.jaxws.samples.asynchronous;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.xml.namespace.QName;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
import javax.xml.ws.Service;
import junit.framework.Test;
import org.jboss.wsf.test.JBossWSTest;
import org.jboss.wsf.test.JBossWSTestSetup;
public class AsynchronousProxyTestCase extends JBossWSTest
{
private String targetNS = "http://org.jboss.ws/jaxws/asynchronous";
private Exception handlerException;
private boolean asyncHandlerCalled;
public static Test suite()
{
return new JBossWSTestSetup(AsynchronousProxyTestCase.class, "jaxws-samples-asynchronous.war");
}
public void testInvokeAsync() throws Exception
{
Endpoint port = createProxy();
Response response = port.echoAsync("Async");
// access future
String retStr = (String) response.get();
assertEquals("Async", retStr);
}
public void testInvokeAsyncHandler() throws Exception
{
AsyncHandler
As this class extends JBossWS test suite, it will implement a "suite" method used to setup and deploy your web service on JBoss:
public static Test suite()
public void testInvokeAsync() throws Exception {
public void testInvokeAsyncHandler() throws Exception
Web Service client with Dispatcher
package org.jboss.test.ws.jaxws.samples.asynchronous;
import java.io.IOException;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Response;
import javax.xml.ws.Service;
import javax.xml.ws.Service.Mode;
import junit.framework.Test;
import org.jboss.wsf.test.JBossWSTest;
import org.jboss.wsf.test.JBossWSTestSetup;
import org.jboss.wsf.common.DOMUtils;
import org.jboss.wsf.common.DOMWriter;
import org.w3c.dom.Element;
public class AsynchronousDispatchTestCase extends JBossWSTest
{
private String targetNS = "http://org.jboss.ws/jaxws/asynchronous";
private String reqPayload = "
Message: In this mode, client applications work directly with protocol-specific message structures. E.g., when used with a SOAP protocol binding, a client application would work directly with a SOAP message. Message Payload (as in this sample): client applications work with the payload of messages rather than the messages themselves. E.g., when used with a SOAP protocol binding, a client application would work with the contents of the SOAP Body rather than the SOAP message as a whole.
JBoss.org Search
Custom Search
Only registered users can write comments!
Powered by !JoomlaComment 3.26
3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |




Callback calls process the response on a different thread from the one the client is running on. This allows the client to gain some control over performance if there are many concurrent asynchronous requests.