Return-Path: Delivered-To: apmail-ws-axis-cvs-archive@www.apache.org Received: (qmail 78156 invoked from network); 19 Jan 2006 16:26:21 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 19 Jan 2006 16:26:21 -0000 Received: (qmail 15815 invoked by uid 500); 19 Jan 2006 16:26:19 -0000 Delivered-To: apmail-ws-axis-cvs-archive@ws.apache.org Received: (qmail 15678 invoked by uid 500); 19 Jan 2006 16:26:17 -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 15552 invoked by uid 500); 19 Jan 2006 16:26:16 -0000 Delivered-To: apmail-ws-axis2-cvs@ws.apache.org Received: (qmail 15472 invoked by uid 99); 19 Jan 2006 16:26:15 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 19 Jan 2006 08:26:15 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Thu, 19 Jan 2006 08:26:05 -0800 Received: (qmail 77443 invoked by uid 65534); 19 Jan 2006 16:25:44 -0000 Message-ID: <20060119162544.77442.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r370524 [6/11] - in /webservices/axis2/site: ./ 0_93/ 0_93/adb/ 0_93/tools/idea-guide/ 0_94/ 0_94/adb/ 0_94/images/ 0_94/tools/idea/ modules/ modules/addressing/ modules/wss4j/ modules/wss4j/0_94/0.94/ multiproject/axis2-Samples/ multiproje... Date: Thu, 19 Jan 2006 16:25:06 -0000 To: axis2-cvs@ws.apache.org From: chinthaka@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Modified: webservices/axis2/site/0_94/userguide.html URL: http://svn.apache.org/viewcvs/webservices/axis2/site/0_94/userguide.html?rev=370524&r1=370523&r2=370524&view=diff ============================================================================== --- webservices/axis2/site/0_94/userguide.html (original) +++ webservices/axis2/site/0_94/userguide.html Thu Jan 19 08:22:01 2006 @@ -2,139 +2,1327 @@ @import url("../style/maven-base.css"); @import url("../style/maven-theme.css");

Axis2 User's Guide

Ver sion 0.94

User Feedback: axis-user@ws.apache.org

Contents

Next Page

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


\ No newline at end of file +
  • Web Service Clients Using + Axis2

    + +
  • +
  • Modules

    + +
  • +
  • Other Samples

    + +
  • +
  • Advanced Topics

    + +
  • +

    Introduction

    Welcome to Axis2, the next generation of Apache Axis!!! This User's Guide + will help you to understand what Axis2 has to offer and how to get started + with it. We hope you will benefit from the power of Axis2.

    Attention

      +
    • This User's Guide is written based on + Axis2 standard binary distribution. (The standard binary distribution can + be created from the source distribution using the maven goal $maven + dist-std-bin). + Please + refer + the installation guide for further + information on the + downloadables available in + this release. +
    • +
    • If you are new to Axis, it's highly recommended that you read Axis 1.x User's Guide before you go any further in + this guide.

      +
    • +

    What is Axis2?

    Axis2 is the next generation of Apache Axis. In late August 2004, during + the Axis2 Summit held in Colombo, Sri Lanka, a new architecture for Axis was + introduced which was much more flexible, efficient and configurable. Although + the architecture is new, some of the well established concepts from Axis 1.x + like handlers are preserved in Axis2. Axis2 comes with many new features, + enhancements and industry specification implementations.

    After months of continued discussion and coding in this direction, Axis2 + now delivers the following key features:

      +
    • Speed - Axis2 uses its + own object model and StAX (Streaming API for XML) parsing to achieve + significantly greater speed than earlier versions of Apache Axis. +
    • +
    • Low memory foot print- + Axis2 was designed ground-up keeping low memory foot + print in mind. +
    • +
    • AXIOM - Axis2 comes with + its own light-weight object model, AXIOM, for message processing + which is + extensible, high performance and developer convenient +
    • + +
    • Hot Deployment - Axis2 is equipped with the capability of + deploying web service & handlers while system is up and + running. In + other words, new services can be added to the system without + having to + shut down server.Drop the required Web service archive into + the services + directory in the repository and deployment model will + automatically + deploy the service and make it available for use. +
    • +
    • Asynchronous Web + Services - Axis2 now supports asynchronous web services & + asynchronous web services invocation using non-blocking + clients and + transports . +
    • +
    • MEP Support - Axis2 now + comes handy with the flexibility to support Message + Exchange Patterns + (MEPs) with in-built support for basic MEPs defined in WSDL + 2.0. +
    • +
    • Flexibility - The Axis2 + architecture gives the developer complete freedom to insert + extensions + into the engine for custom header processing, system + management, or + anything else you can imagine. +
    • +
    • Stability - Axis2 + defines a set of published interfaces which change relatively + slowly + compared to the rest of Axis. +
    • +
    • Component-oriented + Deployment - You can easily define reusable networks of Handlers + to implement common patterns of processing for your + applications, or to + distribute to partners. +
    • +
    • Transport Framework - We + have a clean and simple abstraction for integrating + and using Transports + (i.e., senders and listeners for SOAP over various + protocols such as + SMTP, FTP, message-oriented middleware, etc), and + the core of the engine + is completely transport-independent. +
    • +
    • WSDL support - Axis2 + supports the Web + Service Description + Language, version 1.1 + and 2.0, which + allows you + to easily + build stubs to + access remote + services, and + also to + automatically + export + machine-readable + descriptions + of your + deployed + services from + Axis2. +
    • +
    • Add-ons Several web + services specifications have been incorporated including WSS4J for + security, Sandesha for reliable messaging, Kandula which is + an encapsulation of + WS-Coordination, + WS-AtomicTransaction + and + WS-BusinessActivity. +
    • +
    • Composition and + Extensibility - modules and phases improve support for + composability and extensibility. Modules supports + composability and is + able to add support for new WS-* specifications in a + simple and clean + manner. They are however not hot + deployable + as they change the overall behavior of the system. +
    • +

    We hope you enjoy using Axis2. Please note that this is an open-source + effort. If you feel the code could use some new features or fixes, please get + involved and lend us a hand! The Axis developer community welcomes your + participation.

    Let us know what you think!

    Please send your feedback on Axis2 to "axis-user@ws.apache.org" and make + sure to prefix the subject + of the mail with [Axis2]. +

    Axis2 Complete Features List

      +
    1. AXIOM, an XML object model working on StAX (Streaming API for XML) + parsing optimized for SOAP 1.1/1.2 Messages. This has complete XML + infoset support.
    2. +
    3. Support for One-Way Messaging (In-Only) and Request Response Messaging + (In-Out)
    4. +
    5. Module Architecture, mechanism to extend the SOAP Processing Model
    6. +
    7. Module version support , can have multiple versions of the same module + and use them depending on the requirement.
    8. +
    9. Content hierarchy
    10. +
    11. Archive based deployment Model and Directory based deployment model
    12. +
    13. JWS like deployment (making Java class into Web service)
    14. +
    15. WSDL Code Generation Tool for Stub and skeletons
    16. +
    17. WS-Addressing, both the submission (2004/08) and final (2005/08) + versions
    18. +
    19. WSS4J module for security
    20. +
    21. Improved and user friendly Client API
    22. +
    23. WSDL2Java
    24. +
    25. REST (REpresentational State Transfer) Support
    26. +
    27. Transports supports: HTTP, SMTP, TCP, JMS
    28. +
    29. Raw XML providers
    30. +
    31. Support for MTOM/ MIME/ SwA
    32. +
    33. SAAJ implementation
    34. +
    35. DOOM - New Feature
    36. +
    37. Pack/Unpack capability for the generated code- New Feature
    38. +
    39. Axis Data Binding - ADB (Framework and Schema Compiler)
    40. +
    41. Numerous bug fixes since last release
    42. +

    Axis2 Experimental Features List

      +
    1. Sessions scoping for Application, SOAP, Transport and Request + levels
    2. +
    3. Server side Web Service Policy support
    4. +
    5. ?wsdl and ?xsd support
    6. +
    7. Java2WSDL
    8. +
    9. Generating ServiceClient for a given WSDL and invoke the corresponding + service using generated client.
    10. +

    Major Changes Since Last Release

      +
    1. Fixing of memory leaks
    2. +
    3. Client API changes , Introducing ServiceClient instead of MEPClient, + InOnlyMEPClient, InOutMEPClient, Call. (Please note that the above + classes will be deprecated in this release.)
    4. +
    5. Module versioning support , can have multiple versions of the same + module and use them depending on the requirement.
    6. +
    7. Code generator improved to process multi-port WSDL's properly
    8. +
    9. Packing and unpacking options for the code generated classes
    10. +

    Tools Included In This Release

      +
    1. Axis2 Web Application (Web App)
    2. +
    3. WSDL2WS- Eclipse plugin/ Command line + version/ IntelliJ + IDEA plugin +
    4. +
    5. Service Archive Wizard- Eclipse plugin/ IntelliJ + IDEA plugin +
    6. +

    Download above plugins + +

    What's Still To Do?

    See list of what we think needs to be done, and consider helping out if + you're interested & able!

      +
    1. JAX-RPC 1.1 and/or JAX-WS compliance
    2. +
    3. SOAP Encoding
    4. +
    5. Binary serialization and de-serialization support
    6. +
    7. Management Interface for Axis2
    8. +
    9. Implementation of other Transports.
    10. +
    11. Resource framework implementation (WS-RF) and Enterprise web services + such as JSR 109 support
    12. +
    13. Completion of interop tests
    14. +

    Samples

    In the following sections of the user's guide we will look at how to write + and deploy Web Services and how to write Web Service Clients using Axis2. All + the user's guide samples are located at the "samples/userguide/src" directory of the binary + distribution. So... let's explore the + samples.

    Web Services Using Axis2

    Before starting, please check whether you have deployed the "axis2.war" in + your servlet container and it is working properly. (See Installation Guide). User + can select any of the + following two ways of + writing web services + using + Axis2.

      +
    1. Use Axis2's primary interfaces (APIs) and implement + the business logic.
    2. +
    3. Start from the WSDL ->Code generate the + Skeleton ->Implement the Business Logic.

      +
    4. +

    Writing Web Services Using Axis2's Primary APIs

    Creating Web Service (MyService)

    First let's see how we can write a simple Web Service (MyService) using + Axis2's primary interfaces and deploy it. For this purpose we will create a + Web Service with two operations as follows.

    +
    public void ping(OMElement element){} //IN-ONLY operation, just accepts the OMElement and do
    +     some processing.
    +     public OMElement echo(OMElement element){}//IN-OUT operation, accepts an OMElement and
    +     //responds with another OMElement after processing.
    +
    +
    +

    Complete code for this example Web Service (MyService) can be found in the + "Axis2Home/samples/userguide/src" directory under "userguide/example1" + package. As you can see, the two operations are very simple and need no + explanations on what they do. Now let's see how we can write the deployment + descriptors for the service and deploy it.

    How to write the Web Service?

    + Writing a new Web Service with Axis2 + involve four steps: +

      +
    1. Write the Implementation Class +
    2. +
    3. Write a services.xml file to explain the + Web Service +
    4. +
    5. create a *.aar archive (Axis Archive) for + the Web Service +
    6. +
    7. Deploy the Web Service

      +
    8. +

    Step1 :Write the Implementation Class

    Provides a implementation class that provide the business logic for the + Web Service, it should have methods that match the operations in the Web + Service. Unless you have data binding the signature of the methods can have + one parameter of type OMElement.

    +
    public class MyService{
    +     public void ping(OMElement element){
    +     ......
    +     }
    +     public OMElement echo(OMElement element){
    +     ......
    +     }
    +     }
    +
    +
    +

    Step2 :Write the services.xml file

    Axis2 uses "services.xml" to keep configurations for a Web Service. Each + Web Service deployed in Axis2 needs a "services.xml" containing the + configurations. "services.xml" for MyService will be as follows.

    +
    <service >
    +     <description>
    +     This is a sample Web Service with two operations, echo and ping.
    +     </description>
    +     <parameter name="ServiceClass" locked="false">userguide.example1.MyService</parameter>
    +     <operation name="echo">
    +     <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    +     </operation>
    +     <operation name="ping">
    +     <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
    +     </operation>
    +     </service>
    +
    +
    +

    The above XML tags can be explained as follows:

    Name of the service will be the name of the archive file , if and only if + the services.xml contains only one service element.

    Next comes the description and the service class.

    The next two xml tags describe the operations that are available in this + service with respective message receivers. For the "echo" operation we have + used a RawXMLINOutMessageReceiver since it is an IN-OUT + operation. For IN-ONLY operation "ping", we have used + RawXMLINOnlyMessageReceiver as the message receiver.

    You can write a services.xml file to include a group of services instead + of a single service. This makes management and deployment of a set of related + services very easy. At runtime you can share information between these + services within a single interaction using the ServiceGroupContext. If you + hope to use this functionality, the services.xml file should have following + format.

    +
    <serviceGroup>
    +     <service name="Service1">
    +     <!-- details for Service1 -->
    +     </service>
    +     <service name="Service2">
    +     <!-- details for Service2 -->
    +     </service>
    +     <module ref="ModuleName" />
    +     <parameter name="serviceGroupParam1" locked="false">value 1</parameter>
    +     </serviceGroup>
    +
    +
    +

    Note : name of the service is a compulsory attribute

    Step3 :Create the Web Service Archive

    Axis2 use ".aar" (Axis Archive) file as the deployment package for Web + Services. Therefore, for MyService we will use "MyService.aar" with the + "services.xml" packaged in the META-INF as shown in the following picture.

    To create "MyService.aar" user can first create a jar file containing all + the files necessary for the service and then rename the "jar" to "aar" so + that Axis2 understands it as a service archive. This has already been created + in the "Axis2Home/samples/userguide" directory. Now let's use it...

    Step4 :Deploy the Web Service

    Deploying the service is just a matter of dropping the ".aar" in to + "services" directory that can be found in the "\webapps\axis2\WEB-INF" of + your servlet container, hence copy the "MyService.aar" into the + "services" directory. Once these steps are completed, start the + servlet container (if you have not already started) and check the link + "Services" on the Home Page of Axis2 Web Application + (http://localhost:8080/axis2/index.jsp) and see whether the MyService is + deployed properly. If you can see the following output then you have + successfully deployed MyService on Axis2.

    Note: Axis2 provides an easy way to deploy Web Services using the "Upload + Service" tool on Axis2 Web Application's Administration module. (See the Web Administration Guide for + more information on + this)

    Writing Web Services by Code Generating Skeleton

    This is the second method of writing Web Services using Axis2. Let's see + how we can generate the skeleton from a given WSDL and implement the business + logic using Axis2. For this we use Axis2SampleDocLit.wsdl that can be found + in the wsdl directory under samples.

    WSDL2Java Tool

    To generate the skeleton and the required classes you can use the + WSDL2Java tool provided in Axis2. This tool is located in the bin directory + of the distribution and can be executed using the provided scripts (.bat or + .sh). The tool's parameter list is as follows and user can specify these + values depending on their requirements.

    +
    Usage WSDL2Code -uri :WSDL file location
    +     -o : output file location
    +     -a : Generate async style code only. Default if off
    +     -s : Generate sync style code only. Default if off. takes precedence over -a
    +     -p : set custom package name
    +     -l : valid languages are java and csharp. Default is java
    +     -t : Generate TestCase to test the generated code
    +     -ss : Generate server side code (i.e. skeletons).Default is off
    +     -sd : Generate service descriptor (i.e. axis2.xml).Default is off.Valid with -ss
    +
    +
    +

    We will use the tool with the following parameters and generate the + skeleton and the other required classes.

    Windows users can use the following command in the console:

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

    Linux users should switch the file separator:

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

    This will generate the required classes in the src directory inside + samples, and the schema classes in schema directory also + inside samples. Note that these are not source files and should be availed in + the class path in order to compile the generated classes

    Implement the Business Logic

    Locate the skeleton class that can be found under src/userguide directory + with the name "Axis2SampleDocLitPortTypeSkeleton.java". This is the skeleton + for our web service and we can now easily implement the business logic. The + WSDL we have used has three operations: +

      +
    • echoString - Operation that echoes a + String value +
    • +
    • echoStringArray - Operation that accept + string array as the input and echoes them back +
    • +
    • echoStruct - Operation that accept a Struct as the input and echoes + them back.

      +
    • +

    echoString

    Locate the following code segment in the + "Axis2SampleDocLitPortTypeSkeleton.java" and fill the business logic as + shown below.

    +
     public org.soapinterop.xsd.EchoStringArrayReturnDocument
    +      echoStringArray(org.soapinterop.xsd.EchoStringArrayParamDocument param2){
    +      //To do fill this with the necessary business logic
    +      return null;
    +      }
    +
    +
    +

    Once filled with the business logic it will be as follows. The code is + simple and the explanations are given as comments.

    +
    public org.soapinterop.xsd.EchoStringReturnDocument
    +     echoString(org.soapinterop.xsd.EchoStringParamDocument param6) {
    +     //Use the factory to create the output document.
    +     EchoStringReturnDocument retDoc = EchoStringReturnDocument.Factory.newInstance();
    +     //send the string back.
    +     retDoc.setEchoStringReturn(param6.getEchoStringParam());
    +     return retDoc;
    +     }
    +
    +
    +

    Similarly following code fragments shows how you can fill the business + logic for our first web service.

    echoStringArray

    +
    public org.soapinterop.xsd.EchoStringArrayReturnDocument
    +     echoStringArray(org.soapinterop.xsd.EchoStringArrayParamDocument param2) {
    +
    +     //Use the factory to create the output document.
    +     EchoStringArrayReturnDocument retDoc = EchoStringArrayReturnDocument.Factory.newInstance();
    +
    +     //Get the String array from the input parameters.
    +     String[] inParams = param2.getEchoStringArrayParam().getStringArray();
    +     ArrayOfstringLiteral retParams = ArrayOfstringLiteral.Factory.newInstance();
    +     //Set the input parameters to the output parameters for echoing.
    +     for (int i = 0; i < inParams.length; i++) {
    +     retParams.addString(inParams[i]);
    +     }
    +
    +     //return the output document.
    +     retDoc.setEchoStringArrayReturn(retParams);
    +     return retDoc;
    +     }
    +
    +
    +

    echoStruct

    +
    public org.soapinterop.xsd.EchoStructReturnDocument
    +     echoStruct(org.soapinterop.xsd.EchoStructParamDocument param4) {
    +
    +     //Use the factory to create the output document.
    +     EchoStructReturnDocument retDoc = EchoStructReturnDocument.Factory.newInstance();
    +
    +     //Get the SOAPStrcut from the incoming parameters
    +     SOAPStruct inStruct = param4.getEchoStructParam();
    +
    +     //Struct for the sending back
    +     SOAPStruct outStruct = SOAPStruct.Factory.newInstance();
    +
    +     //Fill the outgoing struct
    +     outStruct.setVarFloat(inStruct.getVarFloat());
    +     outStruct.setVarInt(inStruct.getVarInt());
    +     outStruct.setVarString(inStruct.getVarString());
    +     //Set the outgoing document.
    +     retDoc.setEchoStructReturn(outStruct);
    +
    +     return retDoc;
    +     }
    +
    +
    +

    services.xml

    Axis2 uses "services.xml" to hold the configurations for a particular web + service deployed in the Axis2 engine. When we generate the skeleton using the + WSDL2Java tool, it will also generate the required services.xml for this web + service as well. This can be found in the same directory as the skeleton. The + generated services.xml is as follows.

    +
    <!--Auto generated Axis Service XML-->
    +     <service name="Axis2SampleDocLitPortTypeSkeletonTest">
    +     <parameter locked="xsd:false" name="ServiceClass">userguide.Axis2SampleDocLitPortTypeSkeleton</parameter>
    +     <!--Mounting the method echoStringArray-->
    +     <operation name="echoStringArray">
    +     <messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/>
    +     </operation>
    +     <!--Mounting the method echoStruct-->
    +     <operation name="echoStruct">
    +     <messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/>
    +     </operation>
    +     <!--Mounting the method echoString-->
    +     <operation name="echoString">
    +     <messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/>
    +     </operation>
    +     </service>
    +
    +
    +

    First line of the "services.xml" gives the name of the Web Service. This + is used in the URL to the service as the service name. Next comes the + description and the service class. The next xml tags describe the operations + that are available in this service with respective message receivers.

    Packaging

    Next step in the process is to package the classes in a .aar (axis2 + archive) and deploy it in Axis2. When the WSDL2Java tool generate the + skeleton it will also generate the required data binding classes. These + schema related classes are located in the schema directory of the + generated code. Copy this to your class path, compile the skeleton and the + supporting classes. In order to create the .aar file, let's create the + following directory structure with the required files and then simply use jar + command to package it.

    Go to the top level directory where you can find the class files for the + above service (i.e. one level up on the directory structure shown above), + then type the following command in a command line.

    +
    jar -cf Axis2SampleDocLitPortType.aar .
    +
    +
    +

    Deploying the service is just a matter of dropping the ".aar" in to + "services" directory that can be found in the "\webapps\axis2\WEB-INF" of + your servlet container, hence copy the "echo.aar" into the "services" + directory. Once these steps are completed, please start the servlet container + (if you have not already started) and check the link "Services" on the Home Page of + Axis2 Web Application + (http://localhost:8080/axis2/index.jsp) and see + whether the Axis2SampleDocLitPortType is deployed properly. If you can see + the following output then you have successfully deployed + Axis2SampleDocLitPortType on Axis2.

    Note: Axis2 provides an easy way to deploy Web Services using the "Upload + Service" tool on Axis2 Web Application's Administration module. (See the Web Administration Guide for + more information on + this)

    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 and IN-OUT operation that take + 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 of + 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();
    +    
    +
    +    
    +
    +      StringWriter writer = new StringWriter();
    +      result.serializeWithCache(new
    +      OMOutput(XMLOutputFactory.newInstance().createXMLStreamWriter(writer)));
    +      writer.flush();
    +
    +      System.out.println(writer.toString());
    +
    +      } catch (AxisFault axisFault) {
    +      axisFault.printStackTrace();
    +      } catch (XMLStreamException e) {
    +      e.printStackTrace();
    +      }
    +      }
    +
    +
    +

    The green lines shows the set of operations that you need to perform + inorder 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" 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 a 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);
    +
    +      }
    +      catch (AxisFault axisFault) {
    +      axisFault.printStackTrace();
    +      }
    +
    +
    +

    Since we are accessing a 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".

    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 "serviceCleint.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. 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.setListenerTransportProtocol(Constants.TRANSPORT_HTTP);
    +
    +      //The boolean flag informs the axis2 engine to use two separate transport connection
    +      //to retrieve the response.
    +     options.setUseSeparateListener(true);
    +
    +          ServiceClient serviceClinet = new ServiceClinet();
    +     serviceClinet.setOptions(options);
    +
    +    //Callback to handle the response
    +    Callback callback = new Callback() {
    +    public void onComplete(AsyncResult result) {
    +    try {
    +    StringWriter writer = new StringWriter();
    +    result.serializeWithCache(new OMOutput(XMLOutputFactory.newInstance()
    +    .createXMLStreamWriter(writer)));
    +    writer.flush();
    +
    +    System.out.println(writer.toString());
    +
    +    } catch (XMLStreamException e) {
    +    onError(e);
    +    }
    +    }
    +
    +    public void onError(Exception e) {
    +    e.printStackTrace();
    +    }
    +    };
    +
    +    //Non-Blocking Invocation
    +    serviceClinet.sendReceiveNonblocking(payload, callback);
    +
    +    //Wait till the callback receives the response.
    +    while (!callback.isComplete()) {
    +    Thread.sleep(1000);
    +    }
    +    
    +
    +    } catch (AxisFault axisFault) {
    +    axisFault.printStackTrace();
    +    } catch (Exception ex) {
    +    ex.printStackTrace();
    +    }
    +
    +
    +

    The boolean flag (value true) + in the "options.setUseSeparateListener(...)" + method informs the Axis2 + engine to use separate transport connections for + request and response. + Finally "serviceClinet.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 the server side as well. According to + the Axis2 architecture, addressing module is deployed 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" + directory in the + servlet container. +

    +
     <module ref="addressing"/>
    +
    +
    +

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

    This will enable the addressing in the server side. Now you can test the + "TestEchoNonBlockingDualClient" using the "testEchoNonBlockingDualClient" + target of the ant file found at "Axis2Home/samples" 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" 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 "Axis2SampleDocLitPortType". Simply run the + WSDL2Java tool that can be found in the bin directory of the Axis2 + distribution using the following command:

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

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

    Client for echoVoid Operation

    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.

    +
     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();
    +      }
    +
    +
    +

    Client for echoString Operation

    Following code fragment shows the necessary code for utilizing the + echoString operation of the Axis2SampleDocLitPortType 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/Axis2SampleDocLitPortType");
    +     //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/Axis2SampleDocLitPortType");
    +
    +     //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/Axis2SampleDocLitPortType");
    +     //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();
    +     }
    +
    +
    +

    Modules

    Axis2 provides an extended support for modules (See Architecture Guide for more details + about modules in Axis2). Let's + create a custom module and deploy + it to the + MyService which we created + earlier. Following steps shows the + actions that + need to be performed to deploy a + custom module for a given Web + Service:

      +
    1. Create the Module Implementation +
    2. +
    3. Create the Handlers +
    4. +
    5. Create the module.xml +
    6. +
    7. Modify the "axis2.xml" (if you need + custom phases) +
    8. +
    9. Modify the "services.xml" to engage + modules at the deployment time. +
    10. +
    11. Package in a ".mar" (Module Archive) +
    12. +
    13. Deploy the module in Axis2

      +
    14. +

    MyService with a Logging Module

    Let's write a simple logging module for our sample. This module contains + one handler that just logs the message that is passed through it. Axis2 uses + ."mar" (Module Archive) to deploy modules in Axis2. Following diagram shows + the file structure inside that needs to be there in the ".mar" archive. Let's + create all these and see how it works.

    Step1 : LoggingModule Class

    LoggingModule is the implementation class of the Axis2 module. Axis2 + modules should implement the "org.apache.axis2.modules.Module" interface with + the following methods.

    +
    public void init(AxisConfiguration axisSystem) throws AxisFault;//Initialize the module
    +     public void shutdown(AxisConfiguration axisSystem) throws AxisFault;//End of module
    +     processing
    +
    +
    +

    These methods can be used to control the module initialization and the + termination. With the input parameter AxisConfiguration user is provided with + the complete configuration hierarchy. This can be used to fine-tune the + module behavior using the module writers. For the simple logging service we + can keep these methods blank in our implementation class.

    Step2 : LogHandler

    A module in Axis2 can contain, one or more handlers that perform various + SOAP header processing at different phases. (See Architecture Guide + for more information about phases). For the logging module we will write a + handle with the following methods. "public void invoke(MessageContext ctx);" + is the method that is called by Axis2 engine when the control is passed to + the handler. "public void revoke(MessageContext ctx);" is called when the + handlers are revoked by the Axis2 engine.

    +
    public class LogHandler extends AbstractHandler implements Handler {
    +     private Log log = LogFactory.getLog(getClass());
    +     private QName name;
    +
    +     public QName getName() {
    +     return name;
    +     }
    +
    +     public void invoke(MessageContext msgContext) throws AxisFault {
    +     log.info(msgContext.getEnvelope().toString());
    +     }
    +
    +     public void revoke(MessageContext msgContext) {
    +     log.info(msgContext.getEnvelope().toString());
    +     }
    +
    +     public void setName(QName name) {
    +     this.name = name;
    +     }
    +     }
    +
    +
    +

    Step3 : module.xml

    "module.xml" contains the deployment configurations for a particular + module. It contains details such as Implementation class of the module (in + this example it is the "LoggingModule" class and various handlers that will + run in different phases). "module.xml" for the logging module will be as + follows:

    +
    <module name="logging" class="userguide.loggingmodule.LoggingModule ">
    +     <inflow>
    +     <handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
    +     <order phase="loggingPhase" />
    +     </handler>
    +     </inflow>
    +
    +     <outflow>
    +     <handler name="OutFlowLogHandler" class="userguide.loggingmodule.LogHandler">
    +     <order phase="loggingPhase"/>
    +     </handler>
    +     </outflow>
    +
    +     <Outfaultflow>
    +     <handler name="FaultOutFlowLogHandler" class="userguide.loggingmodule.LogHandler">
    +     <order phase="loggingPhase"/>
    +     </handler>
    +     </Outfaultflow>
    +
    +     <INfaultflow>
    +     <handler name="FaultInFlowLogHandler" class="userguide.loggingmodule.LogHandler">
    +     <order phase="loggingPhase"/>
    +     </handler>
    +     </INfaultflow>
    +     </module>
    +
    +
    +

    As it can be seen there are four phases defined in this "module.xml"

      +
    1. inflow - Represents the handler chain that will run when + a message is coming in.
    2. +
    3. outflow - Represents the + handler chain that will run when the message is going out. +
    4. +
    5. Outfaultflow - Represents the + handler chain that will run when there is a fault and the fault is going + out +
    6. +
    7. INfaultflow - Represents the handler chain that will run when + there is a fault and the fault is coming in

      +
    8. +

    Following set of tags describe the name of the handler, handler class and + the phase in which this handler is going to run. "InFlowLogHandler" is the + name given for the particular instance of this handler. The value of class + attribute is the actual implementation class for this handler. Since we are + writing logging handler, we can reuse the same handler in all these phases. + However this may not be the same for all the modules. "<order + phase="loggingPhase" />" describes the phase in which this handler + runs.

    +
    <handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler">
    +     <order phase="loggingPhase" />
    +     </handler>
    +
    +
    +

    To learn more on Phase rules, click on here

    Step 4: Modify the "axis2.xml"

    In this handler the phase "loggingPhase" is defined by the module writer. + It is not a pre-defined handler phase, hence the module writer should + introduce it to the "axis2.xml" (NOT the services.xml) so that Axis2 engine + knows where to place the handler in different "flows" ( InFlow, OutFlow, + etc.). Following xml lines show the respective changes made to the + "axis2.xml" in order to deploy this logging module in Axis2 engine. This is + an extract of the phase section of the "axis2.xml".

    +
    <!-- ================================================= -->
    +     <!-- Phases -->
    +     <!-- ================================================= -->
    +
    +     <phaseOrder type="inflow">
    +     <!-- System pre defined phases -->
    +     <phase name="TransportIn"/>
    +     <phase name="PreDispatch"/>
    +     <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
    +     <handler name="AddressingBasedDispatcher"
    +     class="org.apache.axis2.engine.AddressingBasedDispatcher">
    +     <order phase="Dispatch"/>
    +     </handler>
    +
    +     <handler name="RequestURIBasedDispatcher"
    +     class="org.apache.axis2.engine.RequestURIBasedDispatcher">
    +     <order phase="Dispatch"/>
    +     </handler>
    +
    +     <handler name="SOAPActionBasedDispatcher"
    
    [... 154 lines stripped ...]