You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ch...@apache.org on 2006/09/26 09:07:36 UTC
svn commit: r449932 [2/2] - in /webservices/axis2/trunk/java/xdocs/1_1:
userguide1.html userguide2.html userguide3.html userguide4.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=449932&r1=449931&r2=449932
==============================================================================
--- webservices/axis2/trunk/java/xdocs/1_1/userguide3.html (original)
+++ webservices/axis2/trunk/java/xdocs/1_1/userguide3.html Tue Sep 26 00:07:35 2006
@@ -1,522 +1,525 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
- <title>Axis2 User's Guide</title>
-</head>
-
-<body lang="en-US" dir="ltr">
-<h4><a name="Axis2_User's_Guide">Axis2 User's Guide</a></h4>
-
-<p><i>User Feedback: <a
-href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a></i>. Prefix
-subject with [Axis2]. To subscribe to mailing list see <a
-href="http://ws.apache.org/axis2/mail-lists.html">here.</a></p>
-
-<p align="right">Pages: <a href="userguide.html">Content</a>, <a
-href="userguide1.html">1</a>, <a href="userguide2.html">2</a>, <b>3</b>, <a
-href="userguide4.html">4</a>, <a href="userguide5.html">5</a></p>
-
-<p><b><font size="4">Note (on samples):</font></b> 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 <b><font
-color="#000000">"samples\userguide\src"</font></b> directory of the binary
-distribution. So... let's explore the samples.</p>
-
-<h2><a name="Web_Service_Clients_Using_Axis2">Web Service Clients Using
-Axis2</a></h2>
-
-<p>Now let's see how we can write a Web Service Client to use this Web
-Service.</p>
-
-<p>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.</p>
-
-<p>Many Web service engines provide the users with a Blocking and
-Non-Blocking client APIs.</p>
-<ul>
- <li><p style="margin-bottom: 0in"><b>Blocking API</b> -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.</p>
- </li>
- <li><p><b>Non-Blocking API </b>- 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.</p>
- </li>
-</ul>
-
-<p>Both these mechanisms work in the API level. Let's name the asynchronous
-behavior that we can get using the <strong>Non-Blocking API</strong> as
-<b>API Level Asynchrony.</b></p>
-
-<p>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 <strong>two
-separate transport connections for request and response</strong>. The
-asynchronous behavior that we gain using this solution can be called
-<b>Transport Level Asynchrony</b>.</p>
-
-<p>By combining API Level Asynchrony & Transport Level Asynchrony we can
-obtain four different invocation patterns for Web services as shown in the
-following table.</p>
-<a name="table1"></a>
-
-<table width="100%" border="1" cellpadding="0" cellspacing="0">
- <tbody>
- <tr>
- <td width="33%" height="19"><p><strong>API
- (Blocking/Non-Blocking)</strong></p>
- </td>
- <td width="33%"><p><strong> Dual Transports (Yes/No)</strong></p>
- </td>
- <td width="33%"><p><strong>Description</strong></p>
- </td>
- </tr>
- <tr>
- <td width="33%" height="19"><p>Blocking</p>
- </td>
- <td width="33%"><p>No</p>
- </td>
- <td width="33%"><p>Simplest and the familiar invocation pattern</p>
- </td>
- </tr>
- <tr>
- <td width="33%" height="19"><p>Non-Blocking</p>
- </td>
- <td width="33%"><p>No</p>
- </td>
- <td width="33%"><p>Using callbacks or polling</p>
- </td>
- </tr>
- <tr>
- <td width="33%" height="19"><p>Blocking</p>
- </td>
- <td width="33%"><p>Yes</p>
- </td>
- <td width="33%"><p>This is useful when the service operation is IN-OUT
- in nature but the transport used is One-Way (e.g. SMTP)</p>
- </td>
- </tr>
- <tr>
- <td width="33%" height="19"><p>Non-Blocking</p>
- </td>
- <td width="33%"><p>Yes</p>
- </td>
- <td width="33%"><p>This is can be used to gain the maximum asynchronous
- behavior. No blocking in the API level and also in the transport
- level</p>
- </td>
- </tr>
- </tbody>
-</table>
-
-<p>Axis2 provides the user with all these possibilities to invoke Web
-Services.</p>
-
-<p>Below we describe how to write Web Services Clients using Axis2. This can
-be done in two methods:</p>
-<ol>
- <li><a href="#Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">Using
- the Axis2's primary APIs</a></li>
- <li><p><a
- href="#Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">Using
- stubs generated with data binding support</a>, making the life easy for
- developers writing Web Service client applications</p>
- </li>
-</ol>
-
-<h3><a name="Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">Writing
-Web Service Clients Using Axis2's Primary APIs</a></h3>
-
-<h4><a name="EchoBlockingClient">EchoBlockingClient</a></h4>
-
-<p>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.</p>
-<source><pre> try {
- OMElement payload = ClientUtil.getEchoOMElement();
- <span style="color: #24C113">
- 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);
- </span>
- System.out.println(result);
-
- } catch (AxisFault axisFault) {
- axisFault.printStackTrace();
- }
-}</pre>
-</source>
-<p>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. </p>
-
-<h4><a name="PingClient">PingClient</a></h4>
-
-<p>In the Web Service "MyService" we had an IN-ONLY operation with the name
-"ping" (see <a href="userguide2.html#Web_Services_Using_Axis2">Web Services
-Using Axis2</a>). Let's write a client to invoke this operation. The client
-code is as follows:</p>
-<pre> 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();
- }</pre>
-
-<p>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".</p>
-
-<p>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...</p>
-
-<h4><a name="EchoNonBlockingClient">EchoNonBlockingClient</a></h4>
-
-<p>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.</p>
-
-<p>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:</p>
-<pre style="margin-bottom: 0.2in">serviceClient.sendReceiveNonblocking(payload, callback);</pre>
-
-<p>The invocation accepts a callback object as a parameter. Axis2 client API
-provides an abstract Callback with the following methods:</p>
-<pre>public abstract void onComplete(AsyncResult result);
-public abstract void onError(Exception e);
-public boolean isComplete() {}</pre>
-
-<p>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.</p>
-
-<p>To run the sample client ( EchoNonBlockingClient) you can simply use the
-"testEchoNonBlockingClient" target of the ant file found at the
-"Axis2Home/samples" directory.</p>
-
-<h4><a name="EchoNonBlockingDualClient">EchoNonBlockingDualClient</a></h4>
-
-<p>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. </p>
-
-<p>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).
-<a href="http://www.w3.org/2002/ws/addr/" target="_blank">WS-Addressing</a>
-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)</p>
-
-<p>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<strong>. The ultimate
-asynchrony!!</strong></p>
-<pre> 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
- }
- }</pre>
-
-<p><font color="#0000ff"><font color="#000000">The boolean flag (value true)
-in the "<b>options.setUseSeparateListener(...)</b>" method informs the Axis2
-engine to use separate transport connections for request and response.
-Finally "<b>service.finalizeInvoke()</b>" informs the Axis2 engine to stop
-the client side listener started to retrieve the response.</font></font></p>
-
-<p>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.</p>
-
-<h5>Engaging Addressing in Server Side</h5>
-According to the Axis2 architecture, addressing module put its handlers in
-the "<strong>pre-dispatch</strong>" phase (See <a
-href="Axis2ArchitectureGuide.html" target="_blank">Architecture Guide</a> 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.
-<pre style="margin-bottom: 0.2in"> <module ref="addressing"/></pre>
-
-<p>Note: <font color="#000000">Once you change the "axis2.xml" you need to
-restart the servlet container.</font></p>
-
-<h5>Engaging Addressing in Client Side</h5>
-There are two ways of doing that. <br>
-One is to get the addressing-<version>.mar from modules folder of the
-std-bin distribution. And then making that available in your classpath. <br>
-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. <br>
-If you have extracted the standard binary distribution to, say,
-$user_home/axis2/dist, then put the following line just before sender = new
-ServiceClient();
-<pre>ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);</pre>
-Then replace "sender = new ServiceClient();" line with "sender = new
-ServiceClient(configContext, null);"
-
-<p>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.</p>
-
-<h4><a name="EchoBlockingDualClient">EchoBlockingDualClient</a></h4>
-
-<p>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 <a
-href="#EchoNonBlockingDualClient">EchoNonBlockingDualClient</a>, 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.</p>
-
-<p>See <a href="http-transport.html" target="_blank">Configuring
-Transports</a> for use different transports.</p>
-
-<h3><a
-name="Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">Writing
-Web Service Clients using Code Generation with Data Binding Support</a></h3>
-
-<p>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:</p>
-<pre style="margin-bottom: 0.2in">WSDL2Java -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide</pre>
-
-<p>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).</p>
-
-<!--<h4><a name="Client_for_echoVoid_Operation">Client for echoVoid
-Operation</a></h4>
-
-<p>Following code fragment shows the necessary code for utilizing the
-echoVoid operation of the Axis2SampleDocLitPortType that we have already
-deployed. In this operation, a blank SOAP body element is sent to the Web
-Service and the same SOAP envelope is echoed back.</p>
-<pre> 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/Axis2SampleDocLitPortType");
- stub.echoVoid();
-
-} catch (Exception e) {
- e.printStackTrace();
-}</pre>-->
-
-
-<h4><a name="Client_for_echoString_Operation">Client for echoString
-Operation</a></h4>
-
-<p>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.</p>
-<pre>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();
- }</pre>
-
-<p>Similarly following code fragments show client side code for
-echoStringArray operation and echoStruct operation respectively.</p>
-
-<h4><a name="Client_for_echoStringArray_Operation">Client for echoStringArray
-Operation</a></h4>
-<pre>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();
- }</pre>
-
-<h4><a name="Client_for_echoStruct_Operation">Client for echoStruct
-Operation</a></h4>
-<pre>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();
-}</pre>
-
-<p align="right"><a href="userguide2.html"><img src="images/arrow_left.gif">
-Previous</a> | <a href="userguide4.html">Next <img
-src="images/arrow_right.gif"></a></p>
-
-<p>Pages: <a href="userguide.html">Content</a>, <a
-href="userguide1.html">1</a>, <a href="userguide2.html">2</a>, <b>3</b>, <a
-href="userguide4.html">4</a>, <a href="userguide5.html">5</a></p>
-</body>
-</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Axis2 User's Guide</title>
+</head>
+
+<body lang="en-US" dir="ltr">
+<h4><a name="Axis2_User's_Guide">Axis2 User's Guide</a></h4>
+
+<p><i>User Feedback: <a
+href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a></i>. Prefix
+subject with [Axis2]. To subscribe to mailing list see <a
+href="http://ws.apache.org/axis2/mail-lists.html">here.</a></p>
+
+<p align="right">Pages: <a href="userguide.html">Content</a>, <a
+href="userguide1.html">1</a>, <a href="userguide2.html">2</a>, <b>3</b>, <a
+href="userguide4.html">4</a>, <a href="userguide5.html">5</a></p>
+
+<p><b><font size="4">Note (on samples):</font></b> 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 <b><font
+color="#000000">"samples\userguide\src"</font></b> directory of the binary
+distribution. So... let's explore the samples.</p>
+
+<h2><a name="Web_Service_Clients_Using_Axis2">Web Service Clients Using
+Axis2</a></h2>
+
+<p>Now let's see how we can write a Web service Client to use this Web
+service.</p>
+
+<p>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.</p>
+
+<p>Many Web service engines provide the users with a Blocking and
+Non-Blocking client APIs.</p>
+<ul>
+ <li><p style="margin-bottom: 0in"><b>Blocking API</b> -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.</p>
+ </li>
+ <li><p><b>Non-Blocking API </b>- 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.</p>
+ </li>
+</ul>
+
+<p>Both these mechanisms work in the API level. Let's name the asynchronous
+behavior that we can get using the <strong>Non-Blocking API</strong> as
+<b>API Level Asynchrony.</b></p>
+
+<p>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 <strong>two
+separate transport connections for request and response</strong>. The
+asynchronous behavior that we gain using this solution can be called
+<b>Transport Level Asynchrony</b>.</p>
+
+<p>By combining API Level Asynchrony & Transport Level Asynchrony we can
+obtain four different invocation patterns for Web services as shown in the
+following table.</p>
+<a name="table1"></a>
+
+<table width="100%" border="1" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td width="33%" height="19"><p><strong>API
+ (Blocking/Non-Blocking)</strong></p>
+ </td>
+ <td width="33%"><p><strong> Dual Transports (Yes/No)</strong></p>
+ </td>
+ <td width="33%"><p><strong>Description</strong></p>
+ </td>
+ </tr>
+ <tr>
+ <td width="33%" height="19"><p>Blocking</p>
+ </td>
+ <td width="33%"><p>No</p>
+ </td>
+ <td width="33%"><p>Simplest and the familiar invocation pattern</p>
+ </td>
+ </tr>
+ <tr>
+ <td width="33%" height="19"><p>Non-Blocking</p>
+ </td>
+ <td width="33%"><p>No</p>
+ </td>
+ <td width="33%"><p>Using callbacks or polling</p>
+ </td>
+ </tr>
+ <tr>
+ <td width="33%" height="19"><p>Blocking</p>
+ </td>
+ <td width="33%"><p>Yes</p>
+ </td>
+ <td width="33%"><p>This is useful when the service operation is IN-OUT
+ in nature but the transport used is One-Way (e.g. SMTP)</p>
+ </td>
+ </tr>
+ <tr>
+ <td width="33%" height="19"><p>Non-Blocking</p>
+ </td>
+ <td width="33%"><p>Yes</p>
+ </td>
+ <td width="33%"><p>This is can be used to gain the maximum asynchronous
+ behavior. No blocking in the API level and also in the transport
+ level</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Axis2 provides the user with all these possibilities to invoke Web
+services.</p>
+
+<p>Below we describe how to write Web services Clients using Axis2. This can
+be done in two methods:</p>
+<ol>
+ <li><a href="#Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">Using
+ the Axis2's primary APIs</a></li>
+ <li><p><a
+ href="#Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">Using
+ stubs generated with data binding support</a>, making the life easy for
+ developers writing Web service client applications</p>
+ </li>
+</ol>
+
+<h3><a name="Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">Writing
+Web Service Clients Using Axis2's Primary APIs</a></h3>
+
+<h4><a name="EchoBlockingClient">EchoBlockingClient</a></h4>
+
+<p>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.</p>
+<source><pre> try {
+ OMElement payload = ClientUtil.getEchoOMElement();
+ <span style="color: #24C113">
+ 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);
+ </span>
+ System.out.println(result);
+
+ } catch (AxisFault axisFault) {
+ axisFault.printStackTrace();
+ }
+}</pre>
+</source>
+<p>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. </p>
+
+<h4><a name="PingClient">PingClient</a></h4>
+
+<p>In the Web service "MyService" we had an IN-ONLY operation with the name
+"ping" (see <a href="userguide2.html#Web_Services_Using_Axis2">Web Services
+Using Axis2</a>). Let's write a client to invoke this operation. The client
+code is as follows:</p>
+<pre> 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();
+ }</pre>
+
+<p>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".</p>
+
+<p>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...</p>
+
+<h4><a name="EchoNonBlockingClient">EchoNonBlockingClient</a></h4>
+
+<p>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.</p>
+
+<p>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:</p>
+<pre style="margin-bottom: 0.2in">serviceClient.sendReceiveNonblocking(payload, callback);</pre>
+
+<p>The invocation accepts a callback object as a parameter. Axis2 client API
+provides an abstract Callback with the following methods:</p>
+<pre>public abstract void onComplete(AsyncResult result);
+public abstract void onError(Exception e);
+public boolean isComplete() {}</pre>
+
+<p>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.</p>
+
+<p>To run the sample client ( EchoNonBlockingClient) you can simply use the
+"testEchoNonBlockingClient" target of the ant file found at the
+"Axis2Home/samples" directory.</p>
+
+<h4><a name="EchoNonBlockingDualClient">EchoNonBlockingDualClient</a></h4>
+
+<p>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. </p>
+
+<p>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).
+<a href="http://www.w3.org/2002/ws/addr/" target="_blank">WS-Addressing</a>
+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)</p>
+
+<p>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<strong>. The ultimate
+asynchrony!!</strong></p>
+<pre> 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
+ }
+ }</pre>
+
+<p><font color="#0000ff"><font color="#000000">The boolean flag (value true)
+in the "<b>options.setUseSeparateListener(...)</b>" method informs the Axis2
+engine to use separate transport connections for request and response.
+Finally "<b>service.finalizeInvoke()</b>" informs the Axis2 engine to stop
+the client side listener started to retrieve the response.</font></font></p>
+
+<p>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.</p>
+
+<h5>Engaging Addressing in Server Side</h5>
+According to the Axis2 architecture, addressing module put its handlers in
+the "<strong>pre-dispatch</strong>" phase (See <a
+href="Axis2ArchitectureGuide.html" target="_blank">Architecture Guide</a> 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.
+<pre style="margin-bottom: 0.2in"> <module ref="addressing"/></pre>
+
+<p>Note: <font color="#000000">Once you change the "axis2.xml" you need to
+restart the servlet container.</font></p>
+
+<h5>Engaging Addressing in Client Side</h5>
+There are two ways of doing that. <br>
+One is to get the addressing-<version>.mar from modules folder of the
+std-bin distribution. And then making that available in your classpath. <br>
+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. <br>
+If you have extracted the standard binary distribution to, say,
+$user_home/axis2/dist, then put the following line just before sender = new
+ServiceClient();
+<pre>ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);</pre>
+Then replace "sender = new ServiceClient();" line with "sender = new
+ServiceClient(configContext, null);"
+
+<p>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.</p>
+
+<h4><a name="EchoBlockingDualClient">EchoBlockingDualClient</a></h4>
+
+<p>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 <a
+href="#EchoNonBlockingDualClient">EchoNonBlockingDualClient</a>, 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.</p>
+
+<p>See <a href="http-transport.html" target="_blank">Configuring
+Transports</a> for use different transports.</p>
+
+<h3><a
+name="Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">Writing
+Web Service Clients using Code Generation with Data Binding Support</a></h3>
+
+<p>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:</p>
+
+<p>Windows users can use the following command in the console:</p>
+<pre style="margin-bottom: 0.2in">WSDL2Java.bat -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide</pre>
+
+<p>Linux users should switch the file separator to:</p>
+<pre style="margin-bottom: 0.2in">WSDL2Java.sh -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -d xmlbeans -o ..\samples\src -p org.apache.axis2.userguide</pre>
+
+<p>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).</p>
+<!--<h4><a name="Client_for_echoVoid_Operation">Client for echoVoid
+Operation</a></h4>
+
+<p>Following code fragment shows the necessary code for utilizing the
+echoVoid operation of the Axis2SampleDocLitPortType that we have already
+deployed. In this operation, a blank SOAP body element is sent to the Web
+Service and the same SOAP envelope is echoed back.</p>
+<pre> 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/Axis2SampleDocLitPortType");
+stub.echoVoid();
+
+} catch (Exception e) {
+e.printStackTrace();
+}</pre>-->
+
+<h4><a name="Client_for_echoString_Operation">Client for echoString
+Operation</a></h4>
+
+<p>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.</p>
+<pre>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();
+ }</pre>
+
+<p>Similarly following code fragments show client side code for
+echoStringArray operation and echoStruct operation respectively.</p>
+
+<h4><a name="Client_for_echoStringArray_Operation">Client for echoStringArray
+Operation</a></h4>
+<pre>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();
+ }</pre>
+
+<h4><a name="Client_for_echoStruct_Operation">Client for echoStruct
+Operation</a></h4>
+<pre>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();
+}</pre>
+
+<p align="right"><a href="userguide2.html"><img src="images/arrow_left.gif">
+Previous</a> | <a href="userguide4.html">Next <img
+src="images/arrow_right.gif"></a></p>
+
+<p>Pages: <a href="userguide.html">Content</a>, <a
+href="userguide1.html">1</a>, <a href="userguide2.html">2</a>, <b>3</b>, <a
+href="userguide4.html">4</a>, <a href="userguide5.html">5</a></p>
+</body>
+</html>
Modified: webservices/axis2/trunk/java/xdocs/1_1/userguide4.html
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/xdocs/1_1/userguide4.html?view=diff&rev=449932&r1=449931&r2=449932
==============================================================================
--- webservices/axis2/trunk/java/xdocs/1_1/userguide4.html (original)
+++ webservices/axis2/trunk/java/xdocs/1_1/userguide4.html Tue Sep 26 00:07:35 2006
@@ -29,7 +29,7 @@
more details about modules in Axis2). Let's create a custom module and deploy
it to the MyService which we created earlier. Following steps show the
actions that need to be performed to deploy a custom module for a given Web
-Service:</p>
+service:</p>
<ol>
<li><p style="margin-bottom: 0in">Create the Module Implementation</p>
</li>
@@ -256,16 +256,16 @@
descriptions for the logging module and by changing the "axis2.xml" we have
created the required phases for the logging module. Next step is to
"<b>engage</b>" (use) this module in one of our services. For this, let's use
-the same Web Service that we have used throughout the user's guide,
+the same Web service that we have used throughout the user's guide,
MyService. However, since we need to modify the "services.xml" of MyService
-in order to engage this module, we use a separate Web Service, but with the
+in order to engage this module, we use a separate Web service, but with the
similar operations. The code for this service can be found in the
"Axis2Home/samples/userguide/src/userguide/example2" directory. The simple
changes that we have done to "services.xml' are shown in green in the
following lines of xml.</p>
<pre><service name="<font color="#33cc00">MyServiceWithModule</font>">
<description>
- This is a sample Web Service with a logging module engaged.
+ This is a sample Web service with a logging module engaged.
</description>
<font color="#33cc00"><module ref="logging"/></font>
<parameter name="ServiceClass" locked="xsd:false">userguide.example2.MyService</parameter>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org