January 27, 2021
Hot Topics:

Using Axis2 and Java for Asynchronous Web Service Invocation on the Client Side

  • By Deepal Jayasinghe
  • Send Email »
  • More Articles »

Apache Axis2 is a complete (supporting all the commonly used web service standards) and fully open source Java web services framework. Like most other web services frameworks, Axis2 contains both server-side and client-side components, and in addition to the most commonly used transports for accessing web services, HTTP and SMTP, Axis2 supports many others (JMS, XMPP, TCP, etc.).

Axis2 also supports asynchronous web services on the client and server sides (See Sidebar 1. Synchronous vs. Asynchronous Web Services). A synchronous web service uses blocking service invocation, while an asynchronous web service use non-blocking invocation (See Sidebar 2. Blocking vs. Non-blocking Service Invocation). On the server side, if your services take a long time to process, you can process them in a non-blocking manner. This means when a message is received, the service will send an acknowledgment and then send the response later.

On the client side, you can invoke the service in a blocking or non-blocking manner. Axis2 supports asynchronous (non-blocking) web service invocations on the client side in two ways. One requires WS-Addressing support, and other does not. This article explains both ways separately with code samples.

Client-side Asynchronous Service Invocation

With web services frameworks, asynchronous support is much more useful for the client side than for the server side. Thus, Axis2 has very good support for client-side asynchronous service invocation (See Sidebar 3. Axis2 Support for Asynchronous Invocation.)

Now that you understand the different types of asynchronous support in Axis2, now it's time to actually use them. First, let's write a service and deploy it in Axis2. Assuming you have set up your IDE with all the related libraries, you will use a very simple deployment mechanism.

Note: Most of the examples discussed here need WS-Address support, so have addressing.mar in your classpath. To do that, simply copy the addressing.mar file into your classpath.

Here is the simple service:

1    package org.sample; 
4    public class EchoService { 
6        public String echo(String value){ 
7            return value; 
8        } 
9    } 

Now let's deploy this service into Axis2 using the following code:

1    package org.sample; 
3    import org.apache.axis2.engine.AxisServer; 
6    public class EchoServer { 
7        public static void main(String[] args) throws Exception { 
8            new AxisServer().deployService(EchoService.class.getName()); 
9        } 
10   } 

Now your service runs on http://localhost:6060/. Let's write the client to invoke the service. The first step is to implement a callback interface, which consists of four methods. Two of these methods address very important behaviors:

  1. What to do when the response is ready
  2. What happens if something goes wrong

Here is your implementation of the callback interface:

1    package org.sample; 
3    import org.apache.axis2.client.async.AxisCallback; 
4    import org.apache.axis2.context.MessageContext; 
5    import org.apache.axiom.soap.SOAPBody; 
8    public class MyCallBack implements AxisCallback { 
9        public void onMessage(MessageContext messageContext) { 
10           SOAPBody msg = messageContext.getEnvelope().getBody(); 
11           System.out.println(msg); 
12       } 
14       public void onFault(MessageContext messageContext) { 
15           messageContext.getFailureReason().printStackTrace(); 
16       } 
18       public void onError(Exception e) { 
19           System.err.println(e.getMessage()); 
20       } 
22       public void onComplete() { 
23           System.out.println("Invocation is complete"); 
24           //In real application you do not need to terminate the program 
25           System.exit(0); 
26       } 
27   } 

As you can see, the interface contains four methods. Now, let's look at each one by one.

  • onMessage – The idea behind onMessage is to invoke user action when a message is received. In your implementation, you have print the message, but depending on the requirements you can implement your code inside the method.
  • onFault – Sometimes you may receive fault as part of the service invocation, and the user might be interested in that. This method helps to achieve that.
  • onError – This method informs the user when something goes wrong on the client side during service invocation.
  • onComplete – This method will notify the user when the message exchange pattern (MEP) is complete. In this example, you terminate the application when Axis2 calls the onComplete method, but in a real application you can implement your user action there.

Application-level Asynchronous Example

With the service up and running and the callback class implemented, you can use your callback class to invoke the service asynchronously. In the first example, you will invoke the service using application-level asynchronous support. The example uses ServiceClient, but you can use any other client (OperationClient, RPCServiceClient or Stubs). The following is the client code, each line of which I will discuss in detail.

1    package org.sample; 
3    import org.apache.axiom.om.OMAbstractFactory; 
4    import org.apache.axiom.om.OMElement; 
5    import org.apache.axiom.om.OMFactory; 
6    import org.apache.axiom.om.OMNamespace; 
7    import org.apache.axis2.addressing.EndpointReference; 
8    import org.apache.axis2.client.Options; 
9    import org.apache.axis2.client.ServiceClient; 
11   public class EchoClient { 
12       public static void main(String[] args) throws Exception { 
13           ServiceClient client = new ServiceClient(); 
14           Options opts = new Options(); 
15           opts.setTo(new EndpointReference("http://localhost:6060/axis2/services/EchoService")); 
16           opts.setAction("urn:echo"); 
17           client.setOptions(opts); 
18           client.sendReceiveNonBlocking(createPayLoad(), new MyCallBack()); 
19           System.out.println("send the message"); 
20           while (true) { 
21               Thread.sleep(100); 
22           } 
23       } 
25       public static OMElement createPayLoad() { 
26           OMFactory fac = OMAbstractFactory.getOMFactory(); 
27           OMNamespace omNs = fac.createOMNamespace( 
28                   "http://sample.org", "ns"); 
29           OMElement method = fac.createOMElement("echo", omNs); 
30           OMElement value = fac.createOMElement("value", omNs); 
31           method.addChild(value); 
32           value.setText("Axis2"); 
33           return method; 
35       } 
36   }

You create an instance of ServiceClient in line 13, and in line 14 you create an Option object. To configure Axis2 on the client side, you need to have an option object. In line 15, you set the endpoint reference of the service or the service URL. Next, you set the SOAPAction, and in line 17, you set the configured option object into the service client instance. In line 18, you invoke the service asynchronously (as you can see, you pass two parameters: an object created from the createPayLoad method and an instance of the MyCallBack class. To invoke a service asynchronously, you need to use sendReceiveNonBlocking in the client API. In line 20-21, you use the while loop to make sure that you do not terminate the main thread. Without the while loop, you will not get the response, but you can try removing it. Lines 25-34 are to create the payload for the web service.

When you run the above code, you will get the following output:

send the message
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<ns:echoResponse xmlns:ns="http://sample.org">
</soapenv:Body> Invocation is complete

Running with TCP Monitor

Now let's run your code with TCP Monitor to see what is actually happening. We'll start TCP monitor on port 8000 and forward that to port 6060. In addition, let's change line 15 as follows:

opts.setTo(new EndpointReference("http://localhost:8000/axis2/services/EchoService"));

The figure below shows the TCP monitor configuration.

TCP Monitor Configuration

When you run with the TCP monitor, you will be able to see both the request and the response in it.

Page 1 of 2

This article was originally published on February 6, 2010

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date