blob: 84de379c47d6b2256f9baef839081890d8108370 [file]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="">
<title>Axis2 User's Guide</title>
</head>
<body lang="en-US" dir="ltr">
<h1 align="center"><a name="_Toc96697849" id="_Toc96697849">Apache</a> Axis2
User's Guide</h1>
<p>This guide will help you get started with Axis2, the next generation of
Apache Axis! It describes in details how to write Web services and Web
service clients using Axis2; how to write custom modules and how to use them
with a Web service. Advanced Topics and Samples which are shipped with the
binary distribution of Axis2, are also discussed.</p>
<h2>Content</h2>
<ul>
<li><p><a href="#Introduction">Introduction</a></p>
</li>
<li><p><a href="#Web_Services_Using_Axis2">Web Services Using Axis2</a></p>
<ul>
<li><a href="#Getting_started">Getting Started</a></li>
<li><a href="#Writing_Web_Services_Using Axis2's_Primary_APIs">Writing
Web Services using Axis2 APIs</a>
<ul>
<li><a href="#How_to_write_the_Web_Service_">How to write the Web
Service?</a>
<ul>
<li><a href="#Step1_:Write_the_Implementation_Class">Step1
:Write the Implementation Class</a></li>
<li><a href="#Step2_:Write_the_services_xml_file">Step2 :Write
the services.xml file</a></li>
<li><a href="#Step3_:Create_the_Web_Service_Archive">Step3
:Create the Web Service Archive</a></li>
<li><a href="#Step4_:Deploy_the_Web_Service">Step4 :Deploy the
Web Service</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a
href="#Writing_Web_Services_by_Code_Generating_Skeleton">Writing Web
Services by Code Generating Skeleton</a></p>
<ul>
<li><a href="#How_to_write_the_Web_Service_2">How to write the Web
Service?</a>
<ul>
<li><a href="#Step1_:Generate_skeleton">Step 1: Generate
Skeleton Code</a></li>
<li><a href="#Step2_Implement_Business_Logic">Step2 :Implement
Business Logic</a></li>
<li><a href="#Step3_:Verify_services_xml">Step3 :Verify
services.xml file</a></li>
<li><a href="#Step4_Create_archive">Step4 :Create the Web
Service Archive file</a></li>
<li><a href="#Step5_Deploy_web_service">Step5 :Deploy the Web
Service</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><p><a href="#Web_Service_Clients_Using_Axis2">Web Service Clients Using
Axis2</a></p>
<ul>
<li><a
href="#Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">Writing
Web Service Clients using Axis2's Primary APIs</a>
<ul>
<li><a href="#EchoBlockingClient">EchoBlockingClient</a></li>
<li><a href="#PingClient">PingClient</a></li>
<li><a href="#EchoNonBlockingClient">EchoNonBlockingClient</a></li>
<li><a
href="#EchoNonBlockingDualClient">EchoNonBlockingDualClient</a></li>
<li><a
href="#EchoBlockingDualClient">EchoBlockingDualClient</a></li>
</ul>
</li>
<li><p><a
href="#Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">Writing
Web Service Clients using Code Generation with Data Binding
Support</a></p>
<ul>
<!--<li><a href="#Client_for_echoVoid_Operation">Client
for echoVoid Operation</a></li>-->
<li><a href="#Client_for_echoString_Operation">Client for
echoString Operation</a></li>
<li><a href="#Client_for_echoStringArray_Operation">Client for
echoStringArray Operation</a></li>
<li><a href="#Client_for_echoStruct_Operation">Client for
echoStruct Operation</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a href="#Modules">Modules</a></p>
<ul>
<li><a href="#MyService_with_a_Logging_Module">MyService with a Logging
Module</a>
<ul>
<li><a href="#Step1_:_LoggingModule_Class">Step1 : LoggingModule
Class</a></li>
<li><a href="#Step2_:_LogHandler">Step2 : LogHandler</a></li>
<li><a href="#Step3_:_module_xml">Step3 : module.xml</a></li>
<li><a href="#Step_4:_Modify_the_&quot;axis2_xml&quot;">Step 4:
Modify the "axis2.xml"</a></li>
<li><a href="#Step5_:_Modify_the_&quot;services_xml&quot;">Step5 :
Modify the "services.xml"</a></li>
<li><a href="#Step6_:_Packaging">Step6 : Packaging</a></li>
<li><a href="#Step7_:_Deploy_the_Module_in_Axis2">Step7 : Deploy
the Module in Axis2</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a href="#Other_Samples">Other Samples</a></p>
<ul>
<li><a href="#Google_Spell_Checker_Sample">Google Spell Checker
Sample</a></li>
<li><a href="#Google_Search_Sample">Google Search Sample</a></li>
<li><a href="#Amazon_Queuing_Service">Amazon Queuing Service</a></li>
</ul>
</li>
<li><p>Advanced Topics</p>
<ul>
<li><a href="rest-ws.html" target="_blank">RESTful Web Services</a></li>
<li><a href="tcp-transport.html" target="_blank">TCP Transport</a></li>
<li><a href="mail-transport.html" target="_blank">Mail
Transport</a></li>
<li><a href="http-transport.html" target="_blank">HTTP
Transports</a></li>
<li><a href="jms-transport.html" target="_blank">JMS Transports</a></li>
<li><a href="mtom-guide.html" target="_blank">MTOM with Axis2</a></li>
<li><a href="../modules/wss4j/1_0/security-module.html"
target="_blank">Securing SOAP Messages with Apache Rampart</a></li>
</ul>
</li>
</ul>
<h2><a name="Introduction">Introduction</a></h2>
<p>This User's Guide is written based on <a
href="../download/1_1/download.html/#std-bin">Axis2 standard binary
distribution</a>. The standard binary distribution can be directly <a
href="[preferred]/ws/axis2/1_1/axis2-std-1.1-bin.zip"
title="[preferred]/ws/axis2/1_1/axis2-std-1.1-bin.zip">downloaded</a> or
built using the <a href="../download/1_1/download.html#src">standard source
distribution</a>. If you choose to go for the latter, then <a
href="installationguide.html">Installation Guide</a> will instruct you on how
to build Axis2 Standard Binary Distribution using the Source.</p>
<p>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.</p>
<p>Let us know what you think! Send your feedback on Axis2 to "<a
href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a>". Make sure
to prefix the subject of the mail with [Axis2].</p>
<h2><a name="Web_Services_Using_Axis2">Web Services Using Axis2</a></h2>
<p>In this section, we will learn how to write and deploy Web services using
Axis2. All the samples mentioned in this giude are located in the
<b>"samples\userguide\src"</b> directory of <a
href="../download/1_1/download.html/#std-bin">Axis2 standard binary
distribution</a>.</p>
<h3><a name="Getting_started">Getting Started</a></h3>
<p>Please deploy axis2.war in your servlet container and ensure that it works
fine. <a href="installationguide.html" target="_blank">Installation Guide</a>
gives you step by step instructions on just how to build axis2.war and deploy
it in your servlet container.</p>
<p>Users can use either one of the following methods to write Web services
using Axis2.</p>
<ol>
<li><a href="#Writing_Web_Services_Using Axis2's_Primary_APIs">Use Axis2's
primary interfaces (APIs) and implement the business logic.</a></li>
<li><p><a href="#Writing_Web_Services_by_Code_Generating_Skeleton">Start
from the WSDL -&gt; Code generate the Skeleton -&gt; Implement the
Business Logic.</a></p>
</li>
</ol>
<p>The complete code of the example Web service - MyService which will be
used in this exercise is found in the "Axis2_HOME/samples/userguide/src"
directory of Axis2 binary distribution, under "userguide/example1"
package.</p>
<h3><a name="Writing_Web_Services_Using Axis2's_Primary_APIs">1. Writing Web
Services Using Axis2's Primary APIs</a></h3>
In our example, the web service will have two operations.
<pre>public void ping(OMElement element){} //IN-ONLY operation, just accepts the OMElement and does some processing.
public OMElement echo(OMElement element){}//IN-OUT operation, accepts an OMElement and
// sends back the same again </pre>
<h4><a name="How_to_write_the_Web_Service_">How to write a Web
Service?</a></h4>
Writing a new Web service with Axis2 involves four steps:
<ol>
<li><p style="margin-bottom: 0in">Write the Implementation Class</p>
</li>
<li><p style="margin-bottom: 0in">Write a services.xml file to explain the
Web service</p>
</li>
<li><p style="margin-bottom: 0in">Create a *.aar archive (Axis Archive) for
the Web service</p>
</li>
<li><p style="margin-bottom: 0in">Deploy the Web service</p>
</li>
</ol>
<h4><a name="Step1_:Write_the_Implementation_Class">Step1 :Write the
Implementation Class</a></h4>
<p>An implementation class has the business logic for the Web service and
implements the operations provided by the Web service. Unless you have data
binding, the signature of the methods can have only one parameter of type
OMElement.</p>
<p><span style="color: #FF0000">OMElement is .... </span>For more details see
<a href="http://ws.apache.org/commons/axiom/OMTutorial.html">OM
Tutorial</a>.</p>
<pre>public class MyService{
public void ping(OMElement element){
// Business Logic
......
}
public OMElement echo(OMElement element){
......
}
}</pre>
<h4><a name="Step2_:Write_the_services_xml_file">Step2 :Write the
services.xml file</a></h4>
<p>"services.xml" has the configuration for a web Service. Each web service,
deployed in Axis2 , must have its configuration in "services.xml". The
configuration for MyService is as follows:</p>
<pre>&lt;service &gt;
&lt;description&gt;
This is a sample Web service with two operations, echo and ping.
&lt;/description&gt;
&lt;parameter name="ServiceClass" locked="false"&gt;userguide.example1.MyService&lt;/parameter&gt;
&lt;operation name="echo"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;actionMapping&gt;urn:echo&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;operation name="ping"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/&gt;
&lt;actionMapping&gt;urn:ping&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;/service&gt;</pre>
<p><em>The above XML tags can be explained as follows:</em></p>
<p>1. The description of the service class is provided in the description
tag.</p>
<pre>&lt;service &gt;
&lt;description&gt;
This is a sample Web service with two operations, echo and ping.
&lt;/description&gt;</pre>
<p>2. The name of the service class is provided as a parameter.</p>
<pre>&lt;parameter name="serviceClass" locked="false"&gt;userguide.example1.MyService&lt;/parameter&gt;</pre>
<p>3. The "operation" xml tag describes the operations that are available in
this service with respective message receivers.</p>
<pre> &lt;operation name="echo"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;actionMapping&gt;urn:echo&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;operation name="ping"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/&gt;
&lt;actionMapping&gt;urn:ping&lt;/actionMapping&gt;
&lt;/operation&gt;</pre>
<p>4. Every operation must map to a corresponding MessageReceiver class.
After a message is processed by the handlers, Axis2 engine hands it over to a
MessageReceiver.</p>
<p>5. For the "echo" operation, we have used a
<strong>RawXMLINOutMessageReceiver</strong> since it is an IN-OUT operation.
For IN-ONLY operation "ping", we have used
<strong>RawXMLINOnlyMessageReceiver</strong> as the message receiver.</p>
<p>6. The actionMapping is required only if you want to enable WS-Addressing.
This will be used later in this user guide.</p>
<p>7. 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 the
following format.</p>
<pre>&lt;serviceGroup&gt;
&lt;service name="Service1"&gt;
&lt;!-- details for Service1 --&gt;
&lt;/service&gt;
&lt;service name="Service2"&gt;
&lt;!-- details for Service2 --&gt;
&lt;/service&gt;
&lt;module ref="ModuleName" /&gt;
&lt;parameter name="serviceGroupParam1" locked="false"&gt;value 1&lt;/parameter&gt;
&lt;/serviceGroup&gt;</pre>
<p>Note : name of the service is a compulsory attribute.</p>
<h4><a name="Step3_:Create_the_Web_Service_Archive">Step3 : Create the Web
Service Archive</a></h4>
<p>Axis2 uses ".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 in directory structure shown below.
Please note that the name of the archive file will be same as that of the
service only if the services.xml contains only one service element.</p>
<p><img src="images/userguide/ServiceItems.jpg" name="Graphic1"
align="bottom" width="176" height="91" border="0"></p>
<p>To create the archive file, you can create a jar file containing all the
necessary files and then rename it to .aar file.This archive file can be
found in the "Axis2_HOME/samples/userguide" directory. This file now has to
be deployed.</p>
<h4><a name="Step4_:Deploy_the_Web_Service">Step4 : Deploy the Web
Service</a></h4>
<p>The service can be deployed by dropping dropping the ".aar" file in to
"services" directory in "/webapps/axis2/WEB-INF" of your servlet container.
Start the servlet container (if you have not already started) and check the
link "Services" on the <a href="http://localhost:8080/axis2/"
target="_blank">Home Page of Axis2 Web Application</a>
(http://localhost:8080/axis2) and see whether the MyService is deployed
properly. If you can see the following output then you have successfully
deployed MyService on Axis2. Congratulations !!</p>
<p align="center"><img src="images/userguide/MyServiceDeployed.jpg"
name="Graphic2" align="bottom" border="0"></p>
<p>Note: Axis2 provides an easy way to deploy Web services using the "Upload
Service" tool on Axis2 Web Application's Administration module. Please refer
to the <a href="webadminguide.html" target="_blank">Web Administration
Guide</a> for more information.</p>
<h3><a name="Writing_Web_Services_by_Code_Generating_Skeleton">2. Writing Web
Services by Code Generating Skeleton</a></h3>
<p>This is the second method of writing Web services using Axis2. In this
method, we generate the skeleton from a given WSDL and implement the business
logic in the classes generated. For this example, we will use
Axis2SampleDocLit.wsdl. This can be found in the <b>"samples\wsdl</b>"
directory of the binary distribution.</p>
<h4><a name="How_to_write_the_Web_Service_2">How to write a Web
Service?</a></h4>
This method of writing a Web service with Axis2 involves five steps:
<ol>
<li><p style="margin-bottom: 0in">Generate the skeleton code</p>
</li>
<li><p style="margin-bottom: 0in">Add business logic</p>
</li>
<li><p style="margin-bottom: 0in">Verify generated services.xml</p>
</li>
<li><p style="margin-bottom: 0in">Create a *.aar archive (Axis Archive) for
the Web service</p>
</li>
<li><p style="margin-bottom: 0in">Deploy the Web service</p>
</li>
</ol>
<h4><a name="Step1_:Generate_skeleton">Step1 : Generate Skeleton Code</a></h4>
<p>To generate the skeleton and 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 users can specify these values
depending on their requirements.</p>
<pre>Usage WSDL2Code -uri &lt;Location of WSDL&gt; : WSDL file location
-o &lt;output Location&gt; : output file location
-a : Generate async style code only. Default is off
-s : Generate sync style code only. Default is off. takes precedence over -a
-p &lt;package name&gt; : set custom package name
-l &lt;language&gt; : 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. services.xml). Default is off. Valid with -ss
-d &lt;databinding&gt; : valid databinding(s) are adb, xmlbeans and jaxme. Default is adb
-g Generates all the classes. valid only with the -ss
-pn &lt;port_name&gt; : name of port in the presence of multiple ports
-sn &lt;service_name&gt; : name of service in the presence of multiple services
-u : unpacks the databinding classes
-r &lt;repository_path&gt; : path of the repository against which code is generated</pre>
<p>The parameters for wsdl2java tool in our example are as follows:</p>
<strong>Windows</strong> <!--<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 -ss -sd -d xmlbeans -o ..\samples -p org.apache.axis2.userguide</pre>
<strong>Linux</strong> <!--<p>Linux users should switch the file separator:</p> -->
<pre style="margin-bottom: 0.2in">WSDL2Java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -d xmlbeans -o ../samples -p org.apache.axis2.userguide</pre>
<p>This will generate the required classes in the <b>"sample\src"</b>
directory, and the schema classes in
<strong>"samples\resources\schemaorg_apache_xmlbeans"</strong>
directory<strong></strong>. Note that these are not source files and should
be available in the class path in order to compile the generated classes.</p>
<h4><a name="Step2_Implement_Business_Logic">Step 2: Implement Business
Logic</a></h4>
<p>Implement the business logic in the skeleton class. The skeleton class
"Axis2SampleDocLitServiceSkeleton.java" can be found in
<strong>"samples/src/org/apache/axis2/userguide</strong>" directory. Our
sample WSDL-Axis2SampleDocLit.wsdl in <strong>"samples/wsdl"</strong>
directory has three operations: <!--<li><p style="margin-bottom: 0in">echoVoid  - Operation that does not
accept any input parameters  and also provide no out put parameters. Just
perform some task </p>
</li>-->
</p>
<ul>
<li><p style="margin-bottom: 0in">echoString  - echoes a String value </p>
</li>
<li><p style="margin-bottom: 0in">echoStringArray - echoes a String
Array</p>
</li>
<li><p style="margin-bottom: 0in">echoStruct - echoes a Struct</p>
</li>
</ul>
<!--<h4>echoVoid   </h4>
<p>Locate the following code segment  in
"Axis2SampleDocLitServiceSkeleton.java"  and add the business logic. For
the explanation purpose we do not need anything to be implemented here.</p>
<pre>public void echoVoid(){
//Todo fill this with the necessary business logic
}</pre> -->
<h4><a name="echoString">echoString</a></h4>
<p>Locate the following code segment  in
"Axis2SampleDocLitServiceSkeleton.java"  and add the business logic as shown
below.</p>
<pre> public org.apache.axis2.userguide.xsd.EchoStringReturnDocument echoString
(org.apache.axis2.userguide.xsd.EchoStringParamDocument param4 ){
//Todo fill this with the necessary business logic
throw new java.lang.UnsupportedOperationException();
}
</pre>
<p>Once the business logic is added, the source code appears as below:</p>
<pre>public org.apache.axis2.userguide.xsd.EchoStringReturnDocument echoString
(org.apache.axis2.userguide.xsd.EchoStringParamDocument param4) throws Exception {
//Use the factory to create the output document.
EchoStringReturnDocument retDoc = EchoStringReturnDocument.Factory.newInstance();
//send the string back.
retDoc.setEchoStringReturn(param4.getEchoStringParam());
return retDoc;
}</pre>
<h4><a name="echoStringArray">echoStringArray</a></h4>
<p>The code segment for echoStringArray is shown below:</p>
<pre>public org.apache.axis2.userguide.xsd.EchoStringArrayReturnDocument echoStringArray
(org.apache.axis2.userguide.xsd.EchoStringArrayParamDocument param0) throws Exception {
//Use the factory to create the output document.
EchoStringArrayReturnDocument retDoc = EchoStringArrayReturnDocument.Factory.newInstance();
//Get the String array from the input parameters.
String[] inParams = param0.getEchoStringArrayParam().getStringArray();
ArrayOfstringLiteral retParams = ArrayOfstringLiteral.Factory.newInstance();
//Set the input parameters to the output parameters for echoing.
for (int i = 0; i &lt; inParams.length; i++) {
retParams.addString(inParams[i]);
}
//return the output document.
retDoc.setEchoStringArrayReturn(retParams);
return retDoc;
}</pre>
<h4><a name="echoStruct">echoStruct</a></h4>
<p>The code segment for echoStruct is shown below:</p>
<pre>public org.apache.axis2.userguide.xsd.EchoStructReturnDocument echoStruct
(org.apache.axis2.userguide.xsd.EchoStructParamDocument param2) throws Exception {
//Use the factory to create the output document.
EchoStructReturnDocument retDoc = EchoStructReturnDocument.Factory.newInstance();
//Get the SOAPStrcut from the incoming parameters
SOAPStruct inStruct = param2.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;
}</pre>
<h4><a name="Step3_:Verify_services_xml">Step3 : Verify Generated
services.xml</a></h4>
<p>As mentioned earlier, "services.xml" file holds all the configuration
information for a Web service. When the skeleton is generated using the
WSDL2Java tool, the services.xml file is also generated. This file can be
found in the same directory as the skeleton. The generated services.xml is as
follows.</p>
<pre>&lt;!-- This file was auto-generated from WSDL --&gt;
&lt;!-- by the Apache Axis2 version: #axisVersion# #today# --&gt;
&lt;serviceGroup&gt;
&lt;service name="Axis2SampleDocLitService"&gt;
&lt;messageReceivers&gt;
&lt;messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.userguide.Axis2SampleDocLitServiceMessageReceiverInOut"/&gt;
&lt;/messageReceivers&gt;
&lt;parameter locked="false" name="ServiceClass"&gt;
org.apache.axis2.userguide.Axis2SampleDocLitServiceSkeleton&lt;/parameter&gt;
&lt;operation name="echoStringArray" mep="http://www.w3.org/2004/08/wsdl/in-out"&gt;
&lt;actionMapping&gt;echoStringArray&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;operation name="echoStruct" mep="http://www.w3.org/2004/08/wsdl/in-out"&gt;
&lt;actionMapping&gt;echoStruct&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;operation name="echoString" mep="http://www.w3.org/2004/08/wsdl/in-out"&gt;
&lt;actionMapping&gt;echoString&lt;/actionMapping&gt;
&lt;/operation&gt;
&lt;/service&gt;
&lt;/serviceGroup&gt;</pre>
<p>1. 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.</p>
<p>2. Next comes the description and the service class.</p>
<p>3. The following xml tags describe the operations that are available in
this service with respective message receivers.</p>
<h4><a name="Step4_Create_archive">Step 4: Create Archive File</a></h4>
<p>The next step is to package the classes in an .aar (axis2 archive) and
deploy it in Axis2. When the WSDL2Java tool generates the skeleton, it will
also generate the required data binding classes. These schema related classes
are located in the
<strong>"samples\resources\schemaorg_apache_xmlbeans</strong>" directory of
the generated code. Copy this to your class path, compile the skeleton and
the supporting classes. To create the .aar file, create the following
directory structure with the required files and then jar it up.</p>
<p><img src="images/userguide/DirectoryStructure.jpg" align="bottom"
border="0"></p>
<p>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 run the following on the command line</p>
<pre style="margin-bottom: 0.2in">jar -cf Axis2SampleDocLitService.aar</pre>
<h4><a name="Step5_Deploy_web_service">Step 5: Deploy Web Service</a></h4>
<p>The service can be deployed by dropping dropping the ".aar" file in to
"services" directory in "/webapps/axis2/WEB-INF" of your servlet
container.Start the servlet container (if you have not already started) and
check the link "Services" on the <a href="http://localhost:8080/axis2/"
target="_blank">Home Page of Axis2 Web Application</a>
(http://localhost:8080/axis2) and see whether the Axis2SampleDocLitService is
deployed properly. If you can see the following output then you have
successfully deployed Axis2SampleDocLitService on Axis2. Congratulations
!!</p>
<p align="center"><img src="images/userguide/ServiceDeployed.jpg"
name="Graphic4" align="bottom" border="0"></p>
<p>Note: Axis2 provides an easy way to deploy Web Services using the "Upload
Service" tool on Axis2 Web Application's Administration module. (See the <a
href="webadminguide.html" target="_blank">Web Administration Guide</a> for
more information on this)</p>
<h2><a name="Web_Service_Clients_Using_Axis2">Web Service Clients Using
Axis2</a></h2>
<p>Let's see how we can write a Web service Client using Axis2 in order to
use a Web service. 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 get started!</p>
<p>Web services can be used to provide a wide-range of functionality to user
from simple, less time consuming  operations such as "getStockQuote"  to time
consuming business services. When we utilize (invoke using client
applications) these Web services we cannot use simple generic invocation
paradigms that suite all the timing complexities involved in the service
operations. For example, if we use a single transport channel (such as HTTP)
to invoke a Web service with an IN-OUT operation that takes a long time to
complete, then most often we may end up with "connection time outs". On the
other hand, if there are simultaneous service invocations that  we need to
perform from a single client application, then the use of a "blocking" client
API will degrade the performance of the client application. Similarly there
are various other consequences such as One-Way transports that come in to
play when we need them. Let's try to analyze some common service invocation
paradigms.</p>
<p>Many Web service engines provide 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 the 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 Non-Blocking API as <b>API Level
Asynchrony.</b></p>
<p>Both these mechanisms use single transport connections to send the request
and to receive the response. They severely lag the capability of using two
transport connections for the request and the response (either One-Way or
Two-Way). So both these mechanisms fail to address the problem of long
running transactions (the transport connection may time-out before the
operation completes). A possible solution would be to use two separate
transport connections for request and response. The asynchronous behavior
that we gain using this solution can be called <b>Transport Level
Asynchrony</b>.</p>
<p>By <strong>combining API Level Asynchrony &amp; Transport Level
Asynchrony</strong> 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>The simplest and more 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. Non 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 life easier for
developers writing Web service client applications</p>
</li>
</ol>
<h3><a name="Writing_Web_Service_Clients_using_Axis2's_Primary_APIs">1.
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 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: rgb(36, 193, 19);">
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>1. The lines highlighted in green lines show the set of operations that
you need to perform in order to invoke a Web service.</p>
<p>2. The rest is used to create the OMElement that needs to be sent and
display the response OMElement.</p>
<p>To test this client, use the provided ant build file that can be found in
the "<strong>Axis2_HOME/samples/userguide</strong>" 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. This will not
block the invocation and will return the control immediately back to the
client. You can test this client by running the target "testPingClient" of
the ant build file at "<strong>Axis2Home/samples/userguide</strong>".</p>
<p>We have now invoked the two operations in our service. Are we done? No!
There's a lot more to explore. Let's see some other ways to invoke the same
operations.</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 complete. This
behavior is not desirable when there are many Web service invocations to be
done in a single client application or within a GUI. A solution would be to
use a Non-Blocking API to invoke Web services. Axis2 provides a callback
based non-blocking API for users.</p>
<p>A sample client for this can be found under
"<strong>Axis2_HOME/samples/userguide/src/userguide/clients</strong>" with
the name EchoNonBlockingClient. If we consider the changes that users may
have to do with respect to the "EchoBlockingClient" that we have already
seen, it will be as follows:</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. The Axis2 engine calls the onComplete
method once the Web service response is received by the Axis2 Client API
(ServiceClient). This will eliminate the blocking nature of the Web service
invocation and provide users with the flexibility to use Non Blocking API for
Web service Clients.</p>
<p>To run the sample client ( EchoNonBlockingClient) you can simply use the
"testEchoNonBlockingClient" target of the ant file found at the
"<strong>Axis2_HOME/samples</strong>" 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 take a long time to complete. The
limitation is due to the use of single transport connections to invoke the
Web service and to retrieve the response. In other words, client API provides
a non blocking invocation mechanism for users, but the request and the
response come in a single transport (Two-Way transport) connection (like
HTTP). Long running Web service invocations or Web service invocations using
One-Way transports (like SMTP) cannot be utilized by simply using a non
blocking invocation. </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 &lt;wsa:MessageID&gt; and
&lt;wsa:RelatesTo&gt; headers. Axis2 provides support for addressing  based
correlation mechanism and a complying Client API to invoke Web services with
two transport connections. (Core of Axis2 does not depend on WS-Addressing,
but contains a set of parameters like in addressing that can be populated in
any means. WS-Addressing is one of the uses that may populate them. Even the
transports can populate these. Hence Axis2 has the flexibility to use
different versions of addressing)</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" the addressing module in both client and server sides.</p>
<h5>Engaging Addressing in the 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#incomingsoap">Architecture Guide</a> for
more details on 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
"<strong>/webapps/axis2/WEB-INF/conf</strong>" directory in the servlet
container.
<pre style="margin-bottom: 0.2in"> &lt;module ref="addressing"/&gt;</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 the Client Side</h5>
There are two ways of doing this:<br>
<ol>
<li>One is to get the addressing-&lt;version&gt;.mar from modules folder of
the standard binary distribution. And then making that available in your
classpath.</li>
<li>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.</li>
</ol>
<p>You can use the extracted <a
href="../download/1_1/download.html/#std-bin">standard binary
distribution</a> itself as the repository as it contains the proper structure
of an Axis2 repository (having the services and modules folders inside it).
ConfigurationContext has the runtime context information of the Axis2 system.
<br>
</p>
<p>If you have extracted the standard binary distribution to, say,
$user_home/axis2/dist, then put the following line just before sender = new
ServiceClient();</p>
<pre>ConfigurationContext configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(&lt; Axis2RepositoryLocation &gt;, 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
"<strong>Axis2_HOME/samples/userguide</strong>" 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 "<strong>Axis2_HOME/samples/userguide/src/userguide/clients/</strong>"
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 the response. This is a very
useful mechanism when the service invocation is IN-OUT in nature and the
transports are One-Way (e.g. SMTP). For the sample client we use two HTTP
connections for request and response. Users can test this client using the
"echoBlockingDualClient" target of the ant build file found in the
"<strong>Axis2_HOME/samples/userguide</strong>" directory.</p>
<p>See <a href="http-transport.html" target="_blank">Configuring
Transports</a> for using different transports.</p>
<h3><a
name="Writing_Web_Service_Clients_using_Code_Generation_with_Data_Binding_Support">2.
Writing Web Service Clients using Code Generation with Data Binding
Support</a></h3>
<p>Axis2 provides the data binding support for Web service clients as well.
The user can generate the required stubs from a given WSDL with other
supporting classes. Let's generate stubs for the WSDL used earlier to
generate the skeleton for the "Axis2SampleDocLitService". Simply run the
WSDL2Java tool that can be found in the bin directory of the Axis2
distribution using the following command:</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 (This is 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>The following code fragment shows the necessary code for utilizing the
echoString operation of the Axis2SampleDocLitService that we have already
deployed. The code is very simple to understand and the explanations are in
the form of comments.</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 the 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 &lt; 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>
<h2><a name="Modules"></a>Modules</h2>
<p>Axis2 provides extended support for modules (See <a
href="Axis2ArchitectureGuide.html" target="_blank">Architecture Guide</a> for
more details about modules in Axis2). Let's create a custom module and deploy
it to MyService which we created earlier.</p>
<p>Following steps show the actions that need to be performed to deploy a
custom module for a given Web service:</p>
<ol>
<li><p style="margin-bottom: 0in">Create the Module Implementation</p>
</li>
<li><p style="margin-bottom: 0in">Create the Handlers</p>
</li>
<li><p style="margin-bottom: 0in">Create the module.xml</p>
</li>
<li><p style="margin-bottom: 0in">Modify the "axis2.xml" (if you need
custom phases)</p>
</li>
<li><p style="margin-bottom: 0in">Modify the "services.xml" to engage
modules at the deployment time.</p>
</li>
<li><p style="margin-bottom: 0in">Package in a ".mar" (Module Archive)</p>
</li>
<li><p>Deploy the module in Axis2</p>
</li>
</ol>
<h3><a name="MyService_with_a_Logging_Module">MyService with a Logging
Module</a></h3>
<p>Let's write a simple logging module for our sample located at
<b>"samples\userguide\src"</b> directory of the binary distribution. 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 which needs to be there in the ".mar"
archive. Let's create all these and see how it works.</p>
<p><img src="images/userguide/ModuleView.jpg" name="Graphic5" align="bottom"
border="0"></p>
<h4><a name="Step1_:_LoggingModule_Class">Step1 : LoggingModule Class</a></h4>
<p>LoggingModule is the implementation class of the Axis2 module. Axis2
modules should implement the "<a
href="http://svn.apache.org/viewcvs.cgi/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/modules/Module.java?rev=396785&amp;view=log">org.apache.axis2.modules.Module</a>"
interface with the following methods.</p>
<pre>public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault;//Initialize the module
public void shutdown(AxisConfiguration axisSystem) throws AxisFault;//End of module processing
public void engageNotify(AxisDescription axisDescription) throws AxisFault;</pre>
<p>These methods can be used to control the module initialization and the
termination. With the input parameter AxisConfiguration, the user is provided
with the complete configuration hierarchy. This can be used to fine-tune the
module behavior by the module writers. For the simple logging service we can
keep these methods blank in our implementation class.</p>
<h4><a name="Step2_:_LogHandler">Step2 : LogHandler</a></h4>
<p>A module in Axis2 can contain, one or more handlers that perform various
SOAP header processing at different phases. (See<a
href="Axis2ArchitectureGuide.html#incomingsoap" target="_blank"> Architecture
Guide</a> for more information on phases). To write a handler one should
implement <a
href="http://svn.apache.org/viewcvs.cgi/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/Handler.java?rev=357187&amp;view=log">org.apache.axis2.engine.Handler</a>.
But for convenience, <a
href="http://svn.apache.org/viewcvs.cgi/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/handlers/AbstractHandler.java?rev=396788&amp;view=log">org.apache.axis2.handlers.AbstractHandler</a>
provides an abstract implementation of the Handler interface.</p>
<p>For the logging module we will write a handler 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.</p>
<pre>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 setName(QName name) {
this.name = name;
}
}</pre>
<h4><a name="Step3_:_module_xml">Step3 : module.xml</a></h4>
<p>"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:</p>
<pre>&lt;module name="logging" class="userguide.loggingmodule.LoggingModule "&gt;
&lt;inflow&gt;
&lt;handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase" /&gt;
&lt;/handler&gt;
&lt;/inflow&gt;
&lt;outflow&gt;
&lt;handler name="OutFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/outflow&gt;
&lt;Outfaultflow&gt;
&lt;handler name="FaultOutFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/Outfaultflow&gt;
&lt;INfaultflow&gt;
&lt;handler name="FaultInFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase"/&gt;
&lt;/handler&gt;
&lt;/INfaultflow&gt;
&lt;/module&gt;</pre>
<p>As you can see there are four flows defined in this "module.xml"</p>
<ol>
<li>inflow - Represents the handler chain that will run when a message is
coming in. </li>
<li><p style="margin-bottom: 0in">outflow - Represents the handler chain
that will run when the message is going out. </p>
</li>
<li><p style="margin-bottom: 0in">Outfaultflow - Represents the handler
chain that will run when there is a fault and the fault is going out</p>
</li>
<li><p>INfaultflow - Represents the handler chain that will run when there
is a fault and the fault is coming in </p>
</li>
</ol>
<p>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 class. 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. "&lt;order
phase="loggingPhase" /&gt;" describes the phase in which this handler
runs.</p>
<pre>&lt;handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"&gt;
&lt;order phase="loggingPhase" /&gt;
&lt;/handler&gt;</pre>
<p>To learn more about Phase rules, check out the article <a
href="http://www.developer.com/java/web/article.php/3529321"
target="_blank">Axis2 Execution Framework</a></p>
<h4><a name="Step_4:_Modify_the_&#34;axis2_xml&#34;">Step 4: Modify the
"axis2.xml"</a></h4>
<p>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 the 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 the Axis2 engine. This
is an extract of the phase section of "axis2.xml".</p>
<pre>&lt;!-- ================================================= --&gt;
&lt;!-- Phases --&gt;
&lt;!-- ================================================= --&gt;
&lt;phaseOrder type="inflow"&gt;
&lt;!-- System pre defined phases --&gt;
&lt;phase name="TransportIn"/&gt;
&lt;phase name="PreDispatch"/&gt;
&lt;phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"&gt;
&lt;handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"&gt;
&lt;order phase="Dispatch"/&gt;
&lt;/handler&gt;
&lt;handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher"&gt;
&lt;order phase="PostDispatch"/&gt;
&lt;/handler&gt;
&lt;/phase&gt;
&lt;!-- System pre defined phases --&gt;
&lt;!-- After Postdispatch phase module author or service author can add any phase he wants --&gt;
&lt;phase name="OperationInPhase"/&gt;
&lt;phase name="<span style="color: rgb(36, 193, 19);">loggingPhase</span>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="outflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="OperationOutPhase"/&gt;
&lt;phase name="<span style="color: rgb(36, 193, 19);">loggingPhase</span>"/&gt;
&lt;!--system predefined phases--&gt;
&lt;!--these phases will run irrespective of the service--&gt;
&lt;phase name="PolicyDetermination"/&gt;
&lt;phase name="MessageOut"/&gt;
&lt;/phaseOrder/&gt;
&lt;phaseOrder type="INfaultflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="OperationInFaultPhase"/&gt;
&lt;phase name="<span style="color: rgb(36, 193, 19);">loggingPhase</span>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="Outfaultflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="OperationOutFaultPhase"/&gt;
&lt;phase name="<span style="color: rgb(36, 193, 19);">loggingPhase</span>"/&gt;
&lt;phase name="PolicyDetermination"/&gt;
&lt;phase name="MessageOut"/&gt;
&lt;/phaseOrder&gt;
</pre>
<p>The text in green, the custom phase "loggingPhase" is placed in all the
flows, hence that phase will be called in all the message flows in the
engine. Since our module is associated with this phase, the LogHandler inside
the module will now be executed in this phase.</p>
<h4><a name="Step5_:_Modify_the_&#34;services_xml&#34;">Step5 : Modify the
"services.xml"</a></h4>
<p>Up to this point we have created the required classes and configuration
descriptions for the logging module and by changing the "axis2.xml" we have
created the required phases for the logging module.</p>
<p>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- 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 similar operations.</p>
<p>The code for this service can be found in the
"<strong>Axis2_HOME/samples/userguide/src/userguide/example2</strong>"
directory. The simple changes that we have done to "services.xml' are shown
in green in the following lines of xml.</p>
<pre>&lt;service name="<span style="color: rgb(36, 193, 19);">MyServiceWithModule</span>"&gt;
&lt;description&gt;
This is a sample Web service with a logging module engaged.
&lt;/description&gt;
<span style="color: rgb(36, 193, 19);">&lt;module ref="logging"/&gt;</span>
&lt;parameter name="ServiceClass" locked="xsd:false"&gt;userguide.example2.MyService&lt;/parameter&gt;
&lt;operation name="echo"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;operation name="ping"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;/service&gt;</pre>
<p>In this example we have changed the service name (the implementation class
is very similar to what we have used earlier although it is in a different
package). In addition we have added the line <b>"&lt;module
ref="logging"/&gt;"</b> to "services.xml". This informs the Axis2 engine that
the module "logging" should be engaged for this service. The handler inside
the module will be executed in their respective phases as described by the
"module.xml".</p>
<p><b><a name="Step6_:_Packaging">Step6 : Packaging</a></b></p>
<p>Before deploying the module we need to create the ".mar" file for this
module. This can be done, using the "jar" command and then renaming the
created jar file. Or you can find the "logging.mar" that is already created
for you in the "<strong>Axis2_HOME/samples/userguide</strong>" directory.</p>
<h4><a name="Step7_:_Deploy_the_Module_in_Axis2">Step7 : Deploy the Module in
Axis2</a></h4>
<p>Deploying a module in Axis2 require the user to create a directory with
the name "modules" in the "webapps/axis2/WEB-INF" directory of their servlet
container and then copying the ".mar" file to that directory. So let's first
create the "modules" directory and drop the "logging.mar" in to this
directory.</p>
<p>Although the required changes to the "services.xml" is very little, we
have created a separate service archive (MyServiceWithModule.aar) for users
to deploy and see.</p>
<p>Deploy this service using the same steps that you used to <a
href="#Step4_:Deploy_the_Web_Service">deploy "MyService"</a> and copy the
"logging.mar" file to the "modules" directory.</p>
<p>Then run using the "TestWebServiceWithModuleClient.bat" or
"TestWebServiceWithModuleClient.sh" in the
"<strong>Axis2Home/samples/userguide/src/userguide/clients/bin</strong>"
directory.</p>
<p>Note: To see logs, the user needs to modify the "log4j.properties" to log
INFO. The property file is located in
"<strong>webapps/axis2/WEB-INF/classes</strong>" of your servlet container.
Change the line "log4j.rootCategory= ERROR, LOGFILE" to
"log4j.rootCategory=INFO, ERROR, LOGFILE".</p>
<h2><a name="Other_Samples">Other Samples</a></h2>
<p>To show the power of usage of Axis2, three standard samples are shipped
with the standard binary distribution. These are meant to interact with
outside Web services and prove the capabilities of the Axis2 system.</p>
<p>The included samples are</p>
<ul>
<li><style="margin-bottom: 0in">Google spell checker sample</li>
<li><p style="margin-bottom: 0in">Google search sample</p>
</li>
<li><p style="margin-bottom: 0in">Amazon queuing sample</p>
</li>
</ul>
<p>A simple introduction to each of the above samples are given below. Each
sample contains it's own <strong>help document</strong> that speaks about 
the usage and the advanced operations of that particular sample.</p>
<p>The most obvious place to look for the samples are the <a
href="Axis2 standard binary distribution#std-bin">standard binary
distribution</a>. All these samples are included in the
<strong>samples</strong> directory in the binary distribution. The shell
scripts and the batch files are in fact written to use the binary
distribution's root directory as the home in order to find the libraries.</p>
<p>The alternate method is to build the samples from <a
href="Axis2 standard binary distribution#src">standard source
distribution</a>. Moving to the "<strong>Axis2_HOME/modules/samples</strong>"
of the source distribution and running maven will create the samples in the
"<strong>Axis2_HOME/target/samples</strong>" directory. However, if the
samples need to be started using the shell scripts (or the batch files) then
the Axis2_HOME environment need to be set.( the "guessed" Axis2_HOME would
not be correct in this case)</p>
<h3><a name="Google_Spell_Checker_Sample">Google Spell Checker Sample</a></h3>
<p>This includes a spell checker program that uses the Google spell checking
service. It demonstrates the blocking and non-blocking modes of calling the
service. This sample can be found at the
"<strong>Axis2_HOME/samples/googleSpellcheck</strong>" directory in the Axis2
standard binary distribution and can be easily started using either the batch
file or the shell script.</p>
<h3><a name="Google_Search_Sample">Google Search Sample</a></h3>
<p>This includes a search program that uses the familiar Google search over
the SOAP API. It utilizes the non-blocking mode of the client API. This
sample can be found at "<strong>Axis2_HOME/samples/googleSearch</strong>"
directory of the standard binary distribution and can be easily started using
either the batch file or the shell script.</p>
<h3><a name="Amazon_Queuing_Service">Amazon Queuing Service</a></h3>
<p>Amazon queuing service sample shows how to use the Amazon queuing service.
It has two user interfaces, one to enqueue and the other to dequeue. This
sample is included in "<strong>Axis2_HOME/samples/amazonQS</strong>"
directory of the standard binary distribution with the required batch/shell
scripts to run the sample.</p>
<h2>Advanced Topics</h2>
<ul>
<li><a href="rest-ws.html" target="_blank">RESTful Web Services</a></li>
<li><a href="tcp-transport.html" target="_blank">TCP Transport</a></li>
<li><a href="mail-transport.html" target="_blank">Mail Transport</a></li>
<li><a href="http-transport.html" target="_blank">HTTP Transports</a></li>
<li><a href="jms-transport.html" target="_blank">JMS Transports</a></li>
<li><a href="mtom-guide.html" target="_blank">MTOM with Axis2</a></li>
<li><a href="../modules/wss4j/1_0/security-module.html"
target="_blank">Securing SOAP Messages with Apache Rampart</a></li>
</ul>
</body>
</html>