Return-Path: Delivered-To: apmail-ws-axis-dev-archive@www.apache.org Received: (qmail 88440 invoked from network); 28 Sep 2006 03:40:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 28 Sep 2006 03:40:17 -0000 Received: (qmail 84457 invoked by uid 500); 28 Sep 2006 03:40:17 -0000 Delivered-To: apmail-ws-axis-dev-archive@ws.apache.org Received: (qmail 84181 invoked by uid 500); 28 Sep 2006 03:40:15 -0000 Mailing-List: contact axis-cvs-help@ws.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list axis-cvs@ws.apache.org Received: (qmail 84170 invoked by uid 500); 28 Sep 2006 03:40:15 -0000 Delivered-To: apmail-ws-axis2-cvs@ws.apache.org Received: (qmail 84165 invoked by uid 99); 28 Sep 2006 03:40:15 -0000 Received: from idunn.apache.osuosl.org (HELO idunn.apache.osuosl.org) (140.211.166.84) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 Sep 2006 20:40:15 -0700 X-ASF-Spam-Status: No, hits=-9.4 required=5.0 tests=ALL_TRUSTED,NO_REAL_NAME Received: from [140.211.166.113] ([140.211.166.113:65419] helo=eris.apache.org) by idunn.apache.osuosl.org (ecelerity 2.1.1.8 r(12930)) with ESMTP id CE/80-05478-C144B154 for ; Wed, 27 Sep 2006 20:40:12 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 40A5D1A981A; Wed, 27 Sep 2006 20:40:10 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r450677 - /webservices/axis2/trunk/java/xdocs/1_1/userguide3.html Date: Thu, 28 Sep 2006 03:40:09 -0000 To: axis2-cvs@ws.apache.org From: chatra@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20060928034010.40A5D1A981A@eris.apache.org> X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: chatra Date: Wed Sep 27 20:40:09 2006 New Revision: 450677 URL: http://svn.apache.org/viewvc?view=rev&rev=450677 Log: final review by Hasmin. Thanks Modified: webservices/axis2/trunk/java/xdocs/1_1/userguide3.html Modified: webservices/axis2/trunk/java/xdocs/1_1/userguide3.html URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/xdocs/1_1/userguide3.html?view=diff&rev=450677&r1=450676&r2=450677 ============================================================================== --- webservices/axis2/trunk/java/xdocs/1_1/userguide3.html (original) +++ webservices/axis2/trunk/java/xdocs/1_1/userguide3.html Wed Sep 27 20:40:09 2006 @@ -1,525 +1,524 @@ - - - - - Axis2 User's Guide - - - -

Axis2 User's Guide

- -

User Feedback: axis-user@ws.apache.org. Prefix -subject with [Axis2]. To subscribe to mailing list see here.

- -

Pages: Content, 1, 2, 3, 4, 5

- -

Note (on samples): In this page of the user's -guide we will look at how to write Web service Clients using Axis2. All -samples mentioned in this guide are located at the "samples\userguide\src" directory of the binary -distribution. So... let's explore the samples.

- -

Web Service Clients Using -Axis2

- -

Now let's see how we can write a Web service Client to use this Web -service.

- -

Web services can be used to provide wide range of functionality to the -users ranging from simple, less time consuming  operations such as -"getStockQuote"  to time consuming business services. When we utilize (invoke -using client applications) these Web service we cannot use some simple -generic invocation paradigm that suites all the timing complexities involved -in the service operations. For example, if we use a single transport channel -(such as HTTP) to invoke a Web service with an IN-OUT operation that takes -long time to complete, then most of the time we may end up with "connection -time outs". On the other hand, if there are simultaneous service invocations -that  we need to perform from a single client application, then the use of a -"blocking" client API will degrade the performance of the client application. -Similarly there are various other consequences such as One-Way transports -that come in to play when we need them. Let's try to analyze some common -service invocation paradigms.

- -

Many Web service engines provide the users with a Blocking and -Non-Blocking client APIs.

-
    -
  • Blocking API -Once the service - invocation is called, the client application hangs and only gets control - back when the operation completes, after which client receives a response - or a fault. This is the simplest way of invoking Web services and it also - suites many business situations.

    -
  • -
  • Non-Blocking API - This is a callback or polling based API, - hence once a service invocation is called, the client application - immediately gets the control back and the response is retrieved using the - callback object provided. This approach provides the flexibility to the - client application to invoke several Web services simultaneously without - blocking the operation already invoked.

    -
  • -
- -

Both these mechanisms work in the API level. Let's name the  asynchronous -behavior that we can get using the Non-Blocking API as -API Level Asynchrony.

- -

Both these mechanisms use single transport connection to send the request -and to receive the response. They severely lags the capability of using two -transport connections for the request and the response (either One-Way or -Two-Way). So both these mechanisms fail to address the problem of long -running transactions (the transport connection may time-out before the -operation completes). A possible solution would be to use two -separate transport connections for request and response. The -asynchronous behavior that we gain using this solution can be called -Transport Level Asynchrony.

- -

By combining API Level Asynchrony & Transport Level Asynchrony we can -obtain four different invocation patterns for Web services as shown in the -following table.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API - (Blocking/Non-Blocking)

-

 Dual Transports (Yes/No)

-

Description

-

Blocking

-

No

-

Simplest and the familiar invocation pattern

-

Non-Blocking

-

No

-

Using callbacks or polling

-

Blocking

-

Yes

-

This is useful when the service operation is IN-OUT - in nature but the transport used is One-Way (e.g. SMTP)

-

Non-Blocking

-

Yes

-

This is can be used to gain the maximum asynchronous - behavior. No blocking in the API level and also in the transport - level

-
- -

Axis2 provides the user with all these possibilities to invoke Web -services.

- -

Below we describe how to write Web services Clients using Axis2. This can -be done in two methods:

-
    -
  1. Using - the Axis2's primary APIs
  2. -
  3. Using - stubs generated with data binding support, making the life easy for - developers writing Web service client applications

    -
  4. -
- -

Writing -Web Service Clients Using Axis2's Primary APIs

- -

EchoBlockingClient

- -

Axis2 provides the user with several invocation patterns for Web services, -ranging from pure blocking single channel invocations to a non-blocking dual -channel invocations. Let's first see how we can write a client to invoke -"echo" operation of "MyService" using the simplest blocking invocation. The -client code you need to write is as follows.

-
  try {
-            OMElement payload = ClientUtil.getEchoOMElement();
-                        
-            Options options = new Options();
-            options.setTo(targetEPR); // this sets the location of MyService service
-            
-            ServiceClient serviceClient = new ServiceClient();
-            serviceClient.setOptions(options);
-
-            OMElement result = serviceClient.sendReceive(payload);
-            
-            System.out.println(result);
-
-        } catch (AxisFault axisFault) {
-            axisFault.printStackTrace();
-        } 
-}
- -

The green lines shows the set of operations that you need to perform in -order to invoke a Web service. The rest is used to create the OMElement that -needs to be sent and display the response OMElement. To test this client, use -the provided ant build file that can be found in the -"Axis2Home/samples/userguide" directory. Run the "testEchoBlockingClient" -target . If you can see the response OMElement printed in your command line,  -then you have successfully tested the client.

- -

PingClient

- -

In the Web service "MyService" we had an IN-ONLY operation with the name -"ping" (see Web Services -Using Axis2). Let's write a client to invoke this operation. The client -code is as follows:

-
 try {
-       OMElement payload = ClientUtil.getPingOMElement();
-       Options options = new Options();
-       options.setTo(targetEPR);
-       ServiceClient serviceClient = new ServiceClient();
-       serviceClient.setOptions(options);
-       serviceClient.fireAndForget(payload);
-        /**
-         * We have to block this thread untill we send the request , the problem
-         * is if we go out of the main thread , then request wont send ,so
-         * you have to wait some time :)
-         */
-       Thread.sleep(500);
-     } 
-catch (AxisFault axisFault) {
-            axisFault.printStackTrace();
-     }
- -

Since we are accessing an IN-ONLY operation we can directly use the -"fireAndForget()" in ServiceClient to invoke this operation , and that will -not block the invocation, hence it will return the control immediately back -to the client. You can test this client by running the target -"testPingClient" of the ant build file at "Axis2Home/samples/userguide".

- -

We have invoked the two operations in our service. Are we done? No! There -are lot more to explore. Let's see some other ways to invoke the same -operations...

- -

EchoNonBlockingClient

- -

In the EchoBlockingClient once the "serviceClient.sendReceive(payload);" -is called, the client is blocked till the operation is completed. This -behavior is not desirable when there are many Web service invocations to be -done in a single client application or within a GUI. A solution would be to -use a Non-Blocking API to invoke Web services. Axis2 provides a callback -based non-blocking API for users.

- -

A sample client for this can be found under -"Axis2Home/samples/userguide/src/userguide/clients" with the name -EchoNonBlockingClient. If we consider the changes that user may have to do -with respect to the "EchoBlockingClient" that we have already seen, it will -be as follows:

-
serviceClient.sendReceiveNonblocking(payload, callback);
- -

The invocation accepts a callback object as a parameter. Axis2 client API -provides an abstract Callback with the following methods:

-
public abstract void onComplete(AsyncResult result);
-public abstract void onError(Exception e);
-public boolean isComplete() {}
- -

The user is expected to implement the "onComplete " and "onError " methods -of their extended call back class. Axis2 engine calls the onComplete method -once the Web service response is received by the Axis2 Client API -(ServiceClient). This will eliminate the blocking nature of the Web service -invocations and provides the user with the flexibility to use Non Blocking -API for Web service Clients.

- -

To run the sample client ( EchoNonBlockingClient) you can simply use the -"testEchoNonBlockingClient" target of the ant file found at the -"Axis2Home/samples" directory.

- -

EchoNonBlockingDualClient

- -

The solution provided by the Non-Blocking API has one limitation when it -comes to  Web service invocations which takes long time to complete. The -limitation is due to the use of single transport connection to invoke the Web -service and to retrieve the response. In other words, client API provides a -non blocking invocation mechanism for the users, but the request and the -response comes in a single transport (Two-Way transport) connection (like -HTTP). Long running Web service invocations or Web service invocations using -One-Way transports (like SMTP) cannot be utilized by simply using a non -blocking invocation.

- -

The trivial solution is to use separate transport connections (either -One-Way or Two-Way) for the request and response. The next problem that needs -to be solved is the correlation (correlating the request and the response). -WS-Addressing -provides a neat solution to this using <wsa:MessageID> and -<wsa:RelatesTo> headers. Axis2 provides support for addressing  based -correlation mechanism and a complying Client API to invoke Web services with -two transport connections. (Core of Axis2 does not depend on WS-Addressing, -but contains a set of parameters like in addressing that can be populated in -any means. WS-Addressing is one of the users that may populate them. Even the -transports can populate these. Hence Axis2 has the flexibility to use -different versions of addressing)

- -

Users can select between Blocking or Non-Blocking APIs for the Web service -clients with two transport connections. By simply using a boolean flag, the -same API can be used to invoke Web services (IN-OUT operations) using two -separate transport connections. Let's see how it's done using an example. -Following code fragment shows how to invoke the same "echo" operation using -Non-Blocking API with two transport connections. The ultimate -asynchrony!!

-
  try {
-            OMElement payload = ClientUtil.getEchoOMElement();
-
-            Options options = new Options();
-            options.setTo(targetEPR);
-            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
-            options.setUseSeparateListener(true);
-            options.setAction("urn:echo");  // this is the action mapping we put within the service.xml
-
-            //Callback to handle the response
-            Callback callback = new Callback() {
-                public void onComplete(AsyncResult result) {
-                    System.out.println(result.getResponseEnvelope());
-                }
-
-                public void onError(Exception e) {
-                    e.printStackTrace();
-                }
-            };
-
-            //Non-Blocking Invocation
-            sender = new ServiceClient();
-            sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
-            sender.setOptions(options);
-            sender.sendReceiveNonBlocking(payload, callback);
-
-            //Wait till the callback receives the response.
-            while (!callback.isComplete()) {
-                Thread.sleep(1000);
-            }
-            //Need to close the Client Side Listener.
-
-        } catch (AxisFault axisFault) {
-            axisFault.printStackTrace();
-        } catch (Exception ex) {
-            ex.printStackTrace();
-        } finally {
-            try {
-                sender.finalizeInvoke();
-            } catch (AxisFault axisFault) {
-                //have to ignore this
-            }
-        }
- -

The boolean flag (value true) -in the "options.setUseSeparateListener(...)" method informs the Axis2 -engine to use separate transport connections for request and response. -Finally "service.finalizeInvoke()" informs the Axis2 engine to stop -the client side listener started to retrieve the response.

- -

Before we run the sample client we have one more step to perform. As -mentioned earlier Axis2 uses addressing based correlation mechanism, hence we -need to "engage" addressing module in both client and server sides.

- -
Engaging Addressing in Server Side
-According to the Axis2 architecture, addressing module put its handlers in -the "pre-dispatch" phase (See Architecture Guide for -more details about phases)  and hence "engaging" means simply adding module -reference in the "axis2.xml" (NOT the "services.xml"). Now add the following -line to the "axis2.xml" that you can find in the -"/webapps/axis2/WEB-INF/conf" directory in the servlet container. -
 <module ref="addressing"/>
- -

Note: Once you change the "axis2.xml" you need to -restart the servlet container.

- -
Engaging Addressing in Client Side
-There are two ways of doing that.
-One is to get the addressing-<version>.mar from modules folder of the -std-bin distribution. And then making that available in your classpath.
-The second method is to create a ConfigurationContext giving a repository -location. Axis2 has the concept of a repository to keep the services and -modules. You can use the extracted standard binary distribution itself as the -repository as it contains the proper structure of an Axis2 repository (having -services and modules folders inside it). ConfigurationContext has the runtime -context information of Axis2 system.
-If you have extracted the standard binary distribution to, say, -$user_home/axis2/dist, then put the following line just before sender = new -ServiceClient(); -
ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
-Then replace "sender = new ServiceClient();" line with "sender = new -ServiceClient(configContext, null);" - -

This will enable addressing in both client and server sides. Now you can -test the "TestEchoNonBlockingDualClient" using the -"testEchoNonBlockingDualClient" target of the ant file found at -"Axis2Home/samples/userguide" directory. If you see the response OMElement -printed in the client side, then you have successfully tested the Non -Blocking API with two transport channels at the client side.

- -

EchoBlockingDualClient

- -

This is again a Two-Way transport request/response client, but this time, -we use a Blocking API in the client code. Sample code for this can be found -in the "Axis2Home/samples/userguide/src/userguide/clients/" directory and the -explanation is similar to the EchoNonBlockingDualClient, except that -here we do not use a callback object to handle response. This is a very -useful mechanism when the service invocation is IN-OUT in nature and the -transports are One-Way (e.g. SMTP). For the sample client we use two HTTP -connections for request and response. User can test this client using the -"echoBlockingDualClient" target of the ant build file found in the -"Axis2Home/samples/userguide" directory.

- -

See Configuring -Transports for use different transports.

- -

Writing -Web Service Clients using Code Generation with Data Binding Support

- -

Axis2 provides the data binding support for Web service client as well. -The user can generate the required stubs from a given WSDL with the other -supporting classes. Let's generate stubs for the WSDL used earlier to -generate the skeleton for the "Axis2SampleDocLitService". Simply run the -WSDL2Java tool that can be found in the bin directory of the Axis2 -distribution using the following command:

- -

Windows users can use the following command in the console:

-
WSDL2Java.bat -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide
- -

Linux users should switch the file separator to:

-
WSDL2Java.sh -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide
- -

This will generate the required stub "Axis2SampleDocLitServiceStub.java" -that can be used to invoke the Web service Axis2SampleDocLitService. Let's -see how we can use this stub to write Web service clients to utilize the Web -service Axis2SampleDocLitService (the service that we have already -deployed).

- - -

Client for echoString -Operation

- -

Following code fragment shows the necessary code for utilizing the -echoString operation of the Axis2SampleDocLitService that we have already -deployed. The code is very simple to understand and the explanations are in -the form of comments.

-
try {
-     //Create the stub by passing the AXIS_HOME and target EPR.
-     //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME 
-     Axis2SampleDocLitPortTypeStub stub= new Axis2SampleDocLitPortTypeStub(null,
-                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
-     //Create the request document to be sent.
-     EchoStringParamDocument  reqDoc= EchoStringParamDocument.Factory.newInstance();
-     reqDoc.setEchoStringParam("Axis2 Echo");
-     //invokes the Web service.
-     EchoStringReturnDocument resDoc=stub.echoString(reqDoc);
-     System.out.println(resDoc.getEchoStringReturn());
-
-    } catch (Exception e) {
-        e.printStackTrace();
-    }
- -

Similarly following code fragments show client side code for -echoStringArray operation and echoStruct operation respectively.

- -

Client for echoStringArray -Operation

-
try {
-     //Create the stub by passing the AXIS_HOME and target EPR.
-     //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME
-     Axis2SampleDocLitPortTypeStub stub = new Axis2SampleDocLitPortTypeStub(null,
-                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
-
-     //Create the request document to be sent.
-     EchoStringArrayParamDocument reqDoc = EchoStringArrayParamDocument.Factory.newInstance();
-     ArrayOfstringLiteral paramArray = ArrayOfstringLiteral.Factory.newInstance();
-
-     paramArray.addString("Axis2");
-     paramArray.addString("Echo");
-
-      reqDoc.setEchoStringArrayParam(paramArray);
-      EchoStringArrayReturnDocument resDoc = stub.echoStringArray(reqDoc);
-
-      //Get the response params
-      String[] resParams = resDoc.getEchoStringArrayReturn().getStringArray();
-
-      for (int i = 0; i < resParams.length; i++) {
-           System.out.println(resParams[i]);
-      }
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
- -

Client for echoStruct -Operation

-
try {
-    //Create the stub by passing the AXIS_HOME and target EPR.
-    //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME
-    Axis2SampleDocLitPortTypeStub stub = new Axis2SampleDocLitPortTypeStub(null, 
-                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
-    //Create the request Document
-    EchoStructParamDocument reqDoc = EchoStructParamDocument.Factory.newInstance();
-
-    //Create the complex type
-    SOAPStruct reqStruct = SOAPStruct.Factory.newInstance();
-
-    reqStruct.setVarFloat(100.50F);
-    reqStruct.setVarInt(10);
-    reqStruct.setVarString("High");
-
-    reqDoc.setEchoStructParam(reqStruct);
-
-    //Service invocation
-    EchoStructReturnDocument resDoc = stub.echoStruct(reqDoc);
-    SOAPStruct resStruct = resDoc.getEchoStructReturn();
-
-    System.out.println("floot Value :" + resStruct.getVarFloat());
-    System.out.println("int Value :" + resStruct.getVarInt());
-    System.out.println("String Value :" + resStruct.getVarString());
-
-} catch (Exception e) {
-    e.printStackTrace();
-}
- -

-Previous | Next

- -

Pages: Content, 1, 2, 3, 4, 5

- - + + + + + Axis2 User's Guide + + + +

Axis2 User's Guide

+ +

User Feedback: axis-user@ws.apache.org. Prefix +subject with [Axis2]. To subscribe to mailing list see here.

+ +

Pages: Content, 1, 2, 3, 4, 5

+ +

Note (on samples): In this page of the user's +guide we will look at how to write Web service Clients using Axis2. All +samples mentioned in this guide are located at the "samples\userguide\src" directory of the binary +distribution. So let's get started!

+ +

Web Service Clients Using +Axis2

+ +

Let's see how we can write a Web service Client to use a Web service.

+ +

Web services can be used to provide a wide-range of functionality to user +from simple, less time consuming  operations such as "getStockQuote"  to time +consuming business services. When we utilize (invoke using client +applications) these Web services we cannot use simple generic invocation +paradigms that suite all the timing complexities involved in the service +operations. For example, if we use a single transport channel (such as HTTP) +to invoke a Web service with an IN-OUT operation that takes a long time to +complete, then most often we may end up with "connection time outs". On the +other hand, if there are simultaneous service invocations that  we need to +perform from a single client application, then the use of a "blocking" client +API will degrade the performance of the client application. Similarly there +are various other consequences such as One-Way transports that come in to +play when we need them. Let's try to analyze some common service invocation +paradigms.

+ +

Many Web service engines provide users with a Blocking and Non-Blocking +client APIs.

+
    +
  • Blocking API -Once the service + invocation is called, the client application hangs and only gets control + back when the operation completes, after which the client receives a + response or a fault. This is the simplest way of invoking Web services + and it also suites many business situations.

    +
  • +
  • Non-Blocking API - This is a callback or polling based API, + hence once a service invocation is called, the client application + immediately gets the control back and the response is retrieved using the + callback object provided. This approach provides the flexibility to the + client application to invoke several Web services simultaneously without + blocking the operation already invoked.

    +
  • +
+ +

Both these mechanisms work in the API level. Let's name the  asynchronous +behavior that we can get using the Non-Blocking API as +API Level Asynchrony.

+ +

Both these mechanisms use single transport connections to send the request +and to receive the response. They severely lag the capability of using two +transport connections for the request and the response (either One-Way or +Two-Way). So both these mechanisms fail to address the problem of long +running transactions (the transport connection may time-out before the +operation completes). A possible solution would be to use two +separate transport connections for request and response. The +asynchronous behavior that we gain using this solution can be called +Transport Level Asynchrony.

+ +

By combining API Level Asynchrony & Transport Level Asynchrony we can +obtain four different invocation patterns for Web services as shown in the +following table.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

API + (Blocking/Non-Blocking)

+

 Dual Transports (Yes/No)

+

Description

+

Blocking

+

No

+

The simplest and more familiar invocation pattern

+

Non-Blocking

+

No

+

Using callbacks or polling

+

Blocking

+

Yes

+

This is useful when the service operation is IN-OUT + in nature but the transport used is One-Way (e.g. SMTP)

+

Non-Blocking

+

Yes

+

This is can be used to gain the maximum asynchronous + behavior. Non blocking in the API level and also in the transport + level

+
+ +

Axis2 provides the user with all these possibilities to invoke Web +services.

+ +

Below we describe how to write Web services Clients using Axis2. This can +be done in two methods:

+
    +
  1. Using + the Axis2's primary APIs
  2. +
  3. Using + stubs generated with data binding support, making life easy for + developers writing Web service client applications

    +
  4. +
+ +

Writing +Web Service Clients Using Axis2's Primary APIs

+ +

EchoBlockingClient

+ +

Axis2 provides the user with several invocation patterns for Web services, +ranging from pure blocking single channel invocations to non-blocking dual +channel invocations. Let's first see how we can write a client to invoke +"echo" operation of "MyService" using the simplest blocking invocation. The +client code you need to write is as follows.

+
  try {
+            OMElement payload = ClientUtil.getEchoOMElement();
+                        
+            Options options = new Options();
+            options.setTo(targetEPR); // this sets the location of MyService service
+            
+            ServiceClient serviceClient = new ServiceClient();
+            serviceClient.setOptions(options);
+
+            OMElement result = serviceClient.sendReceive(payload);
+            
+            System.out.println(result);
+
+        } catch (AxisFault axisFault) {
+            axisFault.printStackTrace();
+        } 
+}
+ +

The green lines show the set of operations that you need to perform in +order to invoke a Web service. The rest is used to create the OMElement that +needs to be sent and display the response OMElement. To test this client, use +the provided ant build file that can be found in the +"Axis2Home/samples/userguide" directory. Run the "testEchoBlockingClient" +target . If you can see the response OMElement printed in your command line,  +then you have successfully tested the client.

+ +

PingClient

+ +

In the Web service "MyService" we had an IN-ONLY operation with the name +"ping" (see Web Services +Using Axis2). Let's write a client to invoke this operation. The client +code is as follows:

+
 try {
+       OMElement payload = ClientUtil.getPingOMElement();
+       Options options = new Options();
+       options.setTo(targetEPR);
+       ServiceClient serviceClient = new ServiceClient();
+       serviceClient.setOptions(options);
+       serviceClient.fireAndForget(payload);
+        /**
+         * We have to block this thread untill we send the request , the problem
+         * is if we go out of the main thread , then request wont send ,so
+         * you have to wait some time :)
+         */
+       Thread.sleep(500);
+     } 
+catch (AxisFault axisFault) {
+            axisFault.printStackTrace();
+     }
+ +

Since we are accessing an IN-ONLY operation we can directly use the +"fireAndForget()" in ServiceClient to invoke this operation. This will not +block the invocation and will return the control immediately back to the +client. You can test this client by running the target "testPingClient" of +the ant build file at "Axis2Home/samples/userguide".

+ +

We have now invoked the two operations in our service. Are we done? No! +There's a lot more to explore. Let's see some other ways to invoke the same +operations.

+ +

EchoNonBlockingClient

+ +

In the EchoBlockingClient once the "serviceClient.sendReceive(payload);" +is called, the client is blocked till the operation is complete. This +behavior is not desirable when there are many Web service invocations to be +done in a single client application or within a GUI. A solution would be to +use a Non-Blocking API to invoke Web services. Axis2 provides a callback +based non-blocking API for users.

+ +

A sample client for this can be found under +"Axis2Home/samples/userguide/src/userguide/clients" with the name +EchoNonBlockingClient. If we consider the changes that users may have to do +with respect to the "EchoBlockingClient" that we have already seen, it will +be as follows:

+
serviceClient.sendReceiveNonblocking(payload, callback);
+ +

The invocation accepts a callback object as a parameter. Axis2 client API +provides an abstract Callback with the following methods:

+
public abstract void onComplete(AsyncResult result);
+public abstract void onError(Exception e);
+public boolean isComplete() {}
+ +

The user is expected to implement the "onComplete " and "onError " methods +of their extended call back class. The Axis2 engine calls the onComplete +method once the Web service response is received by the Axis2 Client API +(ServiceClient). This will eliminate the blocking nature of the Web service +invocation and provide users with the flexibility to use Non Blocking API for +Web service Clients.

+ +

To run the sample client ( EchoNonBlockingClient) you can simply use the +"testEchoNonBlockingClient" target of the ant file found at the +"Axis2Home/samples" directory.

+ +

EchoNonBlockingDualClient

+ +

The solution provided by the Non-Blocking API has one limitation when it +comes to Web service invocations which take a long time to complete. The +limitation is due to the use of single transport connections to invoke the +Web service and to retrieve the response. In other words, client API provides +a non blocking invocation mechanism for users, but the request and the +response come in a single transport (Two-Way transport) connection (like +HTTP). Long running Web service invocations or Web service invocations using +One-Way transports (like SMTP) cannot be utilized by simply using a non +blocking invocation.

+ +

The trivial solution is to use separate transport connections (either +One-Way or Two-Way) for the request and response. The next problem that needs +to be solved is the correlation (correlating the request and the response). +WS-Addressing +provides a neat solution to this using <wsa:MessageID> and +<wsa:RelatesTo> headers. Axis2 provides support for addressing  based +correlation mechanism and a complying Client API to invoke Web services with +two transport connections. (Core of Axis2 does not depend on WS-Addressing, +but contains a set of parameters like in addressing that can be populated in +any means. WS-Addressing is one of the uses that may populate them. Even the +transports can populate these. Hence Axis2 has the flexibility to use +different versions of addressing)

+ +

Users can select between Blocking or Non-Blocking APIs for the Web service +clients with two transport connections. By simply using a boolean flag, the +same API can be used to invoke Web services (IN-OUT operations) using two +separate transport connections. Let's see how it's done using an example. +Following code fragment shows how to invoke the same "echo" operation using +Non-Blocking API with two transport connections. The ultimate +asynchrony!!

+
  try {
+            OMElement payload = ClientUtil.getEchoOMElement();
+
+            Options options = new Options();
+            options.setTo(targetEPR);
+            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
+            options.setUseSeparateListener(true);
+            options.setAction("urn:echo");  // this is the action mapping we put within the service.xml
+
+            //Callback to handle the response
+            Callback callback = new Callback() {
+                public void onComplete(AsyncResult result) {
+                    System.out.println(result.getResponseEnvelope());
+                }
+
+                public void onError(Exception e) {
+                    e.printStackTrace();
+                }
+            };
+
+            //Non-Blocking Invocation
+            sender = new ServiceClient();
+            sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
+            sender.setOptions(options);
+            sender.sendReceiveNonBlocking(payload, callback);
+
+            //Wait till the callback receives the response.
+            while (!callback.isComplete()) {
+                Thread.sleep(1000);
+            }
+            //Need to close the Client Side Listener.
+
+        } catch (AxisFault axisFault) {
+            axisFault.printStackTrace();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            try {
+                sender.finalizeInvoke();
+            } catch (AxisFault axisFault) {
+                //have to ignore this
+            }
+        }
+ +

The boolean flag (value true) +in the "options.setUseSeparateListener(...)" method informs the Axis2 +engine to use separate transport connections for request and response. +Finally "service.finalizeInvoke()" informs the Axis2 engine to stop +the client side listener started to retrieve the response.

+ +

Before we run the sample client we have one more step to perform. As +mentioned earlier Axis2 uses addressing based correlation mechanism, hence we +need to "engage" the addressing module in both client and server sides.

+ +
Engaging Addressing in the Server Side
+According to the Axis2 architecture, addressing module put its handlers in +the "pre-dispatch" phase (See Architecture Guide for +more details about phases)  and hence "engaging" means simply adding module +reference in the "axis2.xml" (NOT the "services.xml"). Now add the following +line to the "axis2.xml" that you can find in the +"/webapps/axis2/WEB-INF/conf" directory in the servlet container. +
 <module ref="addressing"/>
+ +

Note: Once you change the "axis2.xml" you need to +restart the servlet container.

+ +
Engaging Addressing in the Client Side
+There are two ways of doing this.
+One is to get the addressing-<version>.mar from modules folder of the +std-bin distribution. And then making that available in your classpath.
+The second method is to create a ConfigurationContext giving a repository +location. Axis2 has the concept of a repository to keep the services and +modules. You can use the extracted standard binary distribution itself as the +repository as it contains the proper structure of an Axis2 repository (having +the services and modules folders inside it). ConfigurationContext has the +runtime context information of the Axis2 system.
+If you have extracted the standard binary distribution to, say, +$user_home/axis2/dist, then put the following line just before sender = new +ServiceClient(); +
ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
+Then replace "sender = new ServiceClient();" line with "sender = new +ServiceClient(configContext, null);" + +

This will enable addressing in both client and server sides. Now you can +test the "TestEchoNonBlockingDualClient" using the +"testEchoNonBlockingDualClient" target of the ant file found at +"Axis2Home/samples/userguide" directory. If you see the response OMElement +printed in the client side, then you have successfully tested the Non +Blocking API with two transport channels at the client side.

+ +

EchoBlockingDualClient

+ +

This is again a Two-Way transport request/response client, but this time, +we use a Blocking API in the client code. Sample code for this can be found +in the "Axis2Home/samples/userguide/src/userguide/clients/" directory and the +explanation is similar to the EchoNonBlockingDualClient, except that +here we do not use a callback object to handle the response. This is a very +useful mechanism when the service invocation is IN-OUT in nature and the +transports are One-Way (e.g. SMTP). For the sample client we use two HTTP +connections for request and response. Users can test this client using the +"echoBlockingDualClient" target of the ant build file found in the +"Axis2Home/samples/userguide" directory.

+ +

See Configuring +Transports for using different transports.

+ +

Writing +Web Service Clients using Code Generation with Data Binding Support

+ +

Axis2 provides the data binding support for Web service clients as well. +The user can generate the required stubs from a given WSDL with other +supporting classes. Let's generate stubs for the WSDL used earlier to +generate the skeleton for the "Axis2SampleDocLitService". Simply run the +WSDL2Java tool that can be found in the bin directory of the Axis2 +distribution using the following command:

+ +

Windows users can use the following command in the console:

+
WSDL2Java.bat -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide
+ +

Linux users should switch the file separator to:

+
WSDL2Java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -d xmlbeans -o ../samples/src -p org.apache.axis2.userguide
+ +

This will generate the required stub "Axis2SampleDocLitServiceStub.java" +that can be used to invoke the Web service Axis2SampleDocLitService. Let's +see how we can use this stub to write Web service clients to utilize the Web +service Axis2SampleDocLitService (This is the service that we have already +deployed).

+ + +

Client for echoString +Operation

+ +

The following code fragment shows the necessary code for utilizing the +echoString operation of the Axis2SampleDocLitService that we have already +deployed. The code is very simple to understand and the explanations are in +the form of comments.

+
try {
+     //Create the stub by passing the AXIS_HOME and target EPR.
+     //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME 
+     Axis2SampleDocLitPortTypeStub stub= new Axis2SampleDocLitPortTypeStub(null,
+                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
+     //Create the request document to be sent.
+     EchoStringParamDocument  reqDoc= EchoStringParamDocument.Factory.newInstance();
+     reqDoc.setEchoStringParam("Axis2 Echo");
+     //invokes the Web service.
+     EchoStringReturnDocument resDoc=stub.echoString(reqDoc);
+     System.out.println(resDoc.getEchoStringReturn());
+
+    } catch (Exception e) {
+        e.printStackTrace();
+    }
+ +

Similarly the following code fragments show client side code for +echoStringArray operation and echoStruct operation respectively.

+ +

Client for echoStringArray +Operation

+
try {
+     //Create the stub by passing the AXIS_HOME and target EPR.
+     //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME
+     Axis2SampleDocLitPortTypeStub stub = new Axis2SampleDocLitPortTypeStub(null,
+                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
+
+     //Create the request document to be sent.
+     EchoStringArrayParamDocument reqDoc = EchoStringArrayParamDocument.Factory.newInstance();
+     ArrayOfstringLiteral paramArray = ArrayOfstringLiteral.Factory.newInstance();
+
+     paramArray.addString("Axis2");
+     paramArray.addString("Echo");
+
+      reqDoc.setEchoStringArrayParam(paramArray);
+      EchoStringArrayReturnDocument resDoc = stub.echoStringArray(reqDoc);
+
+      //Get the response params
+      String[] resParams = resDoc.getEchoStringArrayReturn().getStringArray();
+
+      for (int i = 0; i < resParams.length; i++) {
+           System.out.println(resParams[i]);
+      }
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+ +

Client for echoStruct +Operation

+
try {
+    //Create the stub by passing the AXIS_HOME and target EPR.
+    //We pass null to the AXIS_HOME and hence the stub will use the current directory as the AXIS_HOME
+    Axis2SampleDocLitPortTypeStub stub = new Axis2SampleDocLitPortTypeStub(null, 
+                                "http://localhost:8080/axis2/services/Axis2SampleDocLitService");
+    //Create the request Document
+    EchoStructParamDocument reqDoc = EchoStructParamDocument.Factory.newInstance();
+
+    //Create the complex type
+    SOAPStruct reqStruct = SOAPStruct.Factory.newInstance();
+
+    reqStruct.setVarFloat(100.50F);
+    reqStruct.setVarInt(10);
+    reqStruct.setVarString("High");
+
+    reqDoc.setEchoStructParam(reqStruct);
+
+    //Service invocation
+    EchoStructReturnDocument resDoc = stub.echoStruct(reqDoc);
+    SOAPStruct resStruct = resDoc.getEchoStructReturn();
+
+    System.out.println("floot Value :" + resStruct.getVarFloat());
+    System.out.println("int Value :" + resStruct.getVarInt());
+    System.out.println("String Value :" + resStruct.getVarString());
+
+} catch (Exception e) {
+    e.printStackTrace();
+}
+ +

+Previous | Next

+ +

Pages: Content, 1, 2, 3, 4, 5

+ + --------------------------------------------------------------------- To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org For additional commands, e-mail: axis-cvs-help@ws.apache.org