blob: 082cb2449de10be97107e896aa4793166146993d [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Axis2 User's Guide</title>
</head>
<body lang="en-US" dir="ltr">
<h1 align="center"><a name="_Toc96697849" id="_Toc96697849"></a>Axis2 User's
Guide</h1>
<p><i>Version 0.94</i></p>
<i>User Feedback: <a
href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a></i>
<h2>Contents</h2>
<ul>
<li><p><a href="#Introduction">Introduction</a></p>
<ul>
<li><a href="#Attention">Attention</a></li>
<li><a href="#What_is_Axis_2_0__">What is Axis2?</a></li>
<li><a href="#Featurelist">Axis2 Complete Features List</a>
<ul>
<li><a href="#experimental">Experimental Features List</a></li>
<li><a href="#majorchanges">Major Changes Since Last
Release</a></li>
</ul>
</li>
<li><a href="#toolsinrelease">Tools included in this Release</a></li>
<li><a href="#WhatsStillToDo">What's still to do?</a></li>
</ul>
</li>
<li><p><a href="#samples">Samples</a></p>
</li>
<li><p><a href="#WS">Web Services Using Axis2</a></p>
<ul>
<li><a href="#WSapi">Writing Web Services using Axis2 APIs</a>
<ul>
<li><a href="#CreateWS">Creating Web Service (MyService)</a></li>
<li><a href="#WriteWS">How to write the Web Service?</a>
<ul>
<li><a href="#step1">Step1 :Write the Implementation
Class</a></li>
<li><a href="#step2">Step2 :Write the services.xml file</a></li>
<li><a href="#step3">Step3 :Create the Web Service
Archive</a></li>
<li><a href="#step4">Step4 :Deploy the Web Service</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a href="#generateskl">Writing Web Services by Code Generating
Skeleton</a></p>
<ul>
<li><a href="#WSDL2JavaTool">WSDL2Java Tool</a></li>
<li><a href="#businesslogic">Implement the Business Logic</a></li>
<li><a href="#echostring">echoString</a></li>
<li><a href="#echostringarray">echoStringArray</a></li>
<li><a href="#echostruct">echoStruct</a></li>
<li><a href="#servicesxml">services.xml</a></li>
<li><a href="#packaging">Packaging</a></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="#primaryAPIs">Writing Web Service Clients using Axis2's
Primary APIs</a>
<ul>
<li><a href="#echoblocking">EchoBlockingClient</a></li>
<li><a href="#ping">PingClient</a></li>
<li><a href="#echononblocking">EchoNonBlockingClient</a></li>
<li><a
href="#echononblockingdual">EchoNonBlockingDualClient</a></li>
<li><a href="#echoblockingdual">EchoBlockingDualClient</a></li>
</ul>
</li>
<li><p><a href="#databinding">Writing Web Service Clients using Code
Generation</a></p>
<ul>
<li><a href="#echovoid">Client for echoVoid Operation</a></li>
<li><a href="#clientechostring">Client for echoString
Operation</a></li>
<li><a href="#clientechostringarray">Cient for
echoStringArray</a></li>
<li><a href="#clientechostruct">Client for echoStruct
Operation</a></li>
</ul>
</li>
</ul>
</li>
<li><p><a href="#Modules">Modules</a></p>
<ul>
<li><a href="#logging">MyService with a Logging Module</a>
<ul>
<li><a href="#step1loggingmodule">Step1 : LoggingModule
Class</a></li>
<li><a href="#step2loggingmodule">Step2 : LogHandler</a></li>
<li><a href="#step3loggingmodule">Step3 : module.xml</a></li>
<li><a href="#step4loggingmodule">Step 4: Modify the
"axis2.xml"</a></li>
<li><a href="#step5loggingmodule">Step5 : Modify the
"services.xml"</a></li>
<li><a href="#step6loggingmodule">Step6 : Packaging</a></li>
<li><a href="#step7loggingmodule">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="#googlespell">Google Spell Checker Sample</a></li>
<li><a href="#googlesearch">Google Search Sample</a></li>
<li><a href="#amazonqueuing">Amazon Queuing Service</a></li>
</ul>
</li>
<li><p><a href="#Advanced_Topics">Advanced Topics</a></p>
<ul>
<li><a href="rest-ws.html">RESTful Web Services</a></li>
<li><a href="tcp-transport.html">TCP transport</a></li>
<li><a href="mail-transport.html">Mail Transport</a></li>
<li><a href="http-transport.html">HTTP Transports</a></li>
<li><a href="mtom-guide.html">MTOM with Axis2</a></li>
<li><a href="security-module.html">Securing SOAP Messages with
WSS4J</a></li>
</ul>
</li>
</ul>
<h2><a name="_Toc96698076"></a><a name="Introduction"></a>Introduction</h2>
<p>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.</p>
<h3><a name="Attention"></a>Attention</h3>
<ul>
<li>
<p style="margin-bottom: 0in">This User's Guide is written based on
<em>Axis2 standard binary distribution</em>. (The standard binary distribution can also be
created from the source distribution using the maven goal <code>$maven
dist-std-bin). </code> Please refer the <a href="installationguide.html#Download">installation guide</a> for further information about the downloadable available in this release. </p>
</li>
<li><p>If you are new to Axis, it's highly recommended that you read <a
href="http://ws.apache.org/axis/java/user-guide.html"
target="_blank">Axis 1.x User's Guide</a> before you go any further in
this guide.</p>
</li>
</ul>
<h3><a name="_Toc96698077"></a><a name="What_is_Axis_2_0__"></a>What is
Axis2?</h3>
<p>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.</p>
<p>After months of continued discussion and coding in this direction, Axis2
now delivers the following key features:</p>
<ul>
<li><p style="margin-bottom: 0in"><strong>Speed</strong> - Axis2 uses its
own object model and StAX (Streaming API for XML) parsing to achieve
significantly greater speed than earlier versions of Apache Axis.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Low memory foot print</strong>-
Axis2 was designed ground-up keeping low memory foot print in mind.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>AXIOM</strong> - Axis2 comes with
its own light-weight object model, AXIOM, for message processing which is
extensible, high performance and developer convenient</p>
</li>
<li><p style="margin-bottom: 0in"><strong><a name="hotdeployment">Hot
Deployment</a></strong> - Axis2 is equipped with the capability of
deploying web service &amp; 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.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Asynchronous Web
Services</strong> - Axis2 now supports asynchronous web services &amp;
asynchronous web services invocation using non-blocking clients and
transports .</p>
</li>
<li><p style="margin-bottom: 0in"><strong>MEP Support</strong> - 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.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Flexibility</strong> - The Axis2
architecture gives the developer complete freedom to insert extensions
into the engine for custom header processing, system management, or
<em>anything else you can imagine</em>.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Stability</strong> - Axis2 defines
a set of published interfaces which change relatively slowly compared to
the rest of Axis.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Component-oriented
Deployment</strong> - You can easily define reusable networks of Handlers
to implement common patterns of processing for your applications, or to
distribute to partners.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Transport Framework</strong> - 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.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>WSDL support</strong> - Axis2
supports the <a href="http://www.w3.org/TR/wsdl" target="_blank">Web
Service Description Language</a>, 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.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Add-ons </strong> Several web
services specifications have been incorporated including <a
href="http://ws.apache.org/wss4j/" target="_blank">WSS4J</a> for
security, <a href="http://ws.apache.org/sandesha/"
target="_blank">Sandesha</a> for reliable messaging, <a
href="http://ws.apache.org/kandula/" target="_blank">Kandula</a> which is
an encapsulation of WS-Coordination, WS-AtomicTransaction and WS-BusinessActivity.</p>
</li>
<li><p style="margin-bottom: 0in"><strong>Composition and Extensibility</strong> -
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 <a href="#hotdeployment">hot deployable</a> as they change
the overall behavior of the system.</p>
</li>
</ul>
<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!</p>
<p>Please send your feedback on Axis2 to "<a
href="mailto:axis-user@ws.apache.org">axis-user@ws.apache.org</a>" and make
sure to prefix the subject of the mail with [Axis2].</p>
<h3>Axis2 Complete Features List<a name="Featurelist"></a></h3>
<ol type="1">
<li> 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. </li>
<li>Support for One-Way Messaging (In-Only) and Request Response Messaging (In-Out) </li>
<li>Module Architecture, mechanism to extend the SOAP Processing Model </li>
<li>Module version support , can have multiple versions of the same module and use them depending on the requirement. </li>
<li>Content hierarchy </li>
<li>Archive based deployment Model and Directory based deployment model </li>
<li>JWS like deployment (making Java class into Web service) </li>
<li>WSDL Code Generation Tool for Stub and skeletons </li>
<li>WS-Addressing, both the submission (2004/08) and final (2005/08) versions </li>
<li>WSS4J module for security </li>
<li>Improved and user friendly Client API </li>
<li>WSDL2Java</li>
<li>REST (REpresentational State Transfer) Support </li>
<li>Transports supports: HTTP, SMTP, TCP, JMS </li>
<li>Raw XML providers </li>
<li>Support for MTOM/ MIME/ SwA </li>
<li>SAAJ implementation </li>
<li>DOOM - New Feature </li>
<li>Pack/Unpack capability for the generated code- New Feature </li>
<li>Axis Data Binding - ADB (Framework and Schema Compiler) </li>
<li>Numerous bug fixes since last release </li>
</ol>
<h4 id="head-5bb5aa099717d1d49642f7ae2d63ce5cf94487ad">Axis2 Experimental Features List<a name="experimental"></a></h4>
<ol type="1">
<li> Sessions scoping for Application, SOAP, Transport and Request levels </li>
<li>Server side Web Service Policy support </li>
<li>?wsdl and ?xsd support </li>
<li>Java2WSDL</li>
<li>Generating ServiceClient for a given WSDL and invoke the corresponding service using generated client. </li>
</ol>
<h4 id="head-7dd8e783bb9e22fb00f88748855bb6e500111e12">Major Changes Since Last Release<a name="majorchanges"></a></h4>
<ol type="1">
<li> Fixing of memory leaks </li>
<li>Client API changes , Introducing ServiceClient instead of MEPClient, InOnlyMEPClient, InOutMEPClient, Call. (Please note that the above classes will be deprecated in this release.) </li>
<li>Module versioning support , can have multiple versions of the same module and use them depending on the requirement. </li>
<li>Code generator improved to process multi-port WSDL's properly </li>
<li>Packing and unpacking options for the code generated classes </li>
</ol>
<h3 id="head-83371cc3d6961295be042f584c7b74d81cca23c4">Tools Included In This Release<a name="toolsinrelease"></a></h3>
<ol type="1">
<li> Axis2 Web Application (Web App) </li>
<li>WSDL2WS- Eclipse plugin/ Command line version/ IntelliJ IDEA plugin </li>
<li>Service Archive Wizard- Eclipse plugin/ IntelliJ IDEA plugin </li>
</ol>
<h3 id="head-599c5a50552f02ebdeb5f58ef8da289234812ca4">What's Still To Do?<a name="WhatsStillToDo"></a></h3>
<p>See list of what we think needs to be done, and consider helping out if you're interested &amp; able! </p>
<ol type="1">
<li> JAX-RPC 1.1 and/or JAX-WS compliance </li>
<li>SOAP Encoding </li>
<li>Binary serialization and de-serialization support </li>
<li>Management Interface for Axis2 </li>
<li>Implementation of other Transports. </li>
<li>Resource framework implementation (WS-RF) and Enterprise web services such as JSR 109 support </li>
<li>Completion of interop tests </li>
</ol>
<h2><a name="samples">Samples</a></h2>
<p>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 <b><font
color="#000000">"samples/userguide/src"</font></b> directory of the binary
distribution. So... let's explore the samples.</p>
<h2><a name="WS">Web Services Using Axis2</a></h2>
<p>Before starting, please check whether you have deployed the "axis2.war" in
your servlet container and it is working properly. (See <a
href="installationguide.html" target="_blank">Installation Guide</a>). User
can select any of the  following two ways of writing web services using
Axis2. </p>
<ol>
<li><a href="#WSapi">Use Axis2's primary
interfaces (APIs) and implement the business logic.</a></li>
<li><p><a href="#generateskl">Start from the WSDL -&gt;Code generate the
Skeleton -&gt;Implement the Business Logic.</a></p>
</li>
</ol>
<h3><a name="WSapi">Writing Web Services Using Axis2's Primary APIs</a></h3>
<h4><a name="CreateWS">Creating Web Service (MyService)</a></h4>
<p>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.</p>
<pre>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.</pre>
<p>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.</p>
<h4><a name="WriteWS">How to write the Web Service?</a></h4>
Writing a new Web Service with Axis2 involve 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>Deploy the Web Service</p>
</li>
</ol>
<h4><a name="step1">Step1 :Write the Implementation Class</a></h4>
<p>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.</p>
<pre>public class MyService{
public void ping(OMElement element){
......
}
public OMElement echo(OMElement element){
......
}
}</pre>
<h4><a name="step2">Step2 :Write the services.xml file</a></h4>
<p>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.</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;/operation&gt;
&lt;operation name="ping"&gt;
&lt;messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;/service&gt;</pre>
<p><em>The above XML tags can be explained as follows:</em></p>
<p>Name of the service will be the name of the archive file , if and only if
the services.xml contains only one service element.</p>
<p>Next comes the description and the service class.</p>
<p>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 <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>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.</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">Step3 :Create the Web Service Archive</a></h4>
<p>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.</p>
<p><img src="images/userguide/ServiceItems.jpg" name="Graphic1"
align="bottom" width="176" height="91" border="0"></p>
<p>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...</p>
<h4><a name="step4">Step4 :Deploy the Web Service</a></h4>
<p>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
"<b>services</b>" directory. Once these steps are completed, start the
servlet container (if you have not already started) and check the link
"Services" on the <a href="http://localhost:8080/axis2/index.jsp"
target="_blank">Home Page of Axis2 Web Application</a>
(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.</p>
<p align="center"><img src="images/userguide/MyServiceDeployed.jpg"
name="Graphic2" align="bottom" width="734" height="766" 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>
<h3><a name="generateskl">Writing Web Services by Code Generating
Skeleton</a></h3>
<p>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 <b>wsdl</b> directory under samples.</p>
<h4><a name="WSDL2JavaTool">WSDL2Java Tool</a></h4>
<p>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.</p>
<pre>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</pre>
<p>We will use the tool with the following parameters and generate the
skeleton and the other required classes.</p>
<p>Windows users can use the following command in the console:</p>
<pre style="margin-bottom: 0.2in">WSDL2Java -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -ss -sd -o ..\samples\src -p org.apache.axis2.userguide</pre>
<p>Linux users should switch the file separator:</p>
<pre style="margin-bottom: 0.2in">WSDL2Java -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -o ../samples/src -p org.apache.axis2.userguide</pre>
<p>This will generate the required classes in the <b>src</b> directory inside
samples, and the schema classes in <strong>schema</strong> 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</p>
<h4><a name="businesslogic">Implement the Business Logic</a></h4>
<p>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:<!--<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  - Operation that echoes a
String value </p>
</li>
<li><p style="margin-bottom: 0in">echoStringArray - Operation that accept
string array as the input and echoes them back</p>
</li>
<li><p>echoStruct - Operation that accept a Struct as the input and echoes
them back.</p>
</li>
</ul>
<!--<h4>echoVoid   </h4>
<p>Locate the following code segment  in the
"Axis2SampleDocLitPortTypeSkeleton.java"  and fill 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 the
"Axis2SampleDocLitPortTypeSkeleton.java"  and fill the business logic as
shown below.</p>
<pre> public org.soapinterop.xsd.EchoStringArrayReturnDocument
echoStringArray(org.soapinterop.xsd.EchoStringArrayParamDocument param2){
//To do fill this with the necessary business logic
return null;
}</pre>
<p>Once filled with the business logic it will be as follows. The code is
simple and the explanations are given as comments.</p>
<pre>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;
}</pre>
<p>Similarly following code fragments shows how you can fill the business
logic for our first web service.</p>
<h4><a name="echostringarray">echoStringArray</a></h4>
<pre>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 &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>
<pre>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;
}</pre>
<h4><a name="servicesxml">services.xml</a></h4>
<p> 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.</p>
<pre>&lt;!--Auto generated Axis Service XML--&gt;
&lt;service name="Axis2SampleDocLitPortTypeSkeletonTest"&gt;
&lt;parameter locked="xsd:false" name="ServiceClass"&gt;userguide.Axis2SampleDocLitPortTypeSkeleton&lt;/parameter&gt;
&lt;!--Mounting the method echoStringArray--&gt;
&lt;operation name="echoStringArray"&gt;
&lt;messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;!--Mounting the method echoStruct--&gt;
&lt;operation name="echoStruct"&gt;
&lt;messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;!--Mounting the method echoString--&gt;
&lt;operation name="echoString"&gt;
&lt;messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/&gt;
&lt;/operation&gt;
&lt;/service&gt;</pre>
<p>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.</p>
<h4><a name="packaging">Packaging</a></h4>
<p>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 <b>schema </b>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.</p>
<p><img src="images/userguide/DirectoryStructure.JPG" align="bottom"
width="164" height="142" 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 type the following command in a command line.</p>
<pre style="margin-bottom: 0.2in">jar -cf Axis2SampleDocLitPortType.aar .</pre>
<p>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 "<b>services</b>"
directory. Once these steps are completed, please start the servlet container
(if you have not already started) and check the link "Services" on the <a
href="http://localhost:8080/axis2/index.jsp" target="_blank">Home Page of
Axis2 Web Application</a> (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.</p>
<p align="center"><img src="images/userguide/ServiceDeployed.JPG"
name="Graphic4" align="bottom" width="734" height="764" 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"></a>Web Service Clients Using
Axis2</h2>
<p>Now let's see how we can write a Web Service Client to use this Web
Service.</p>
<p>Web services can be used to provide wide range of functionality to the
users ranging from simple, less time consuming  operations such as
"getStockQuote"  to time consuming business services. When we utilize (invoke
using client applications) these Web Service we cannot use some simple
generic invocation paradigm that suites all the timing complexities involved
in the service operations. For example, if we use a single transport channel
(such as HTTP) to invoke a Web Service with 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.</p>
<p>Many web service engines provide the users with a Blocking and
Non-Blocking client APIs.</p>
<ul>
<li><p style="margin-bottom: 0in"><b>Blocking API</b> -Once the service
invocation is called, the client application hangs and only gets control
back when the operation completes, after which client receives a response
or a fault. This is the simplest way of invoking Web Services and it also
suites many business situations.</p>
</li>
<li><p><b>Non-Blocking API </b>- This is a callback or polling based API,
hence once a service invocation is called, the client application
immediately gets the control back and the response is retrieved using the
callback object provided. This approach provides the flexibility to the
client application to invoke several Web Services simultaneously without
blocking the operation already invoked.</p>
</li>
</ul>
<p>Both these mechanisms work in the API level. Let's name the  asynchronous
behavior that we can get using the <strong>Non-Blocking API</strong> as
<b>API Level Asynchrony.</b></p>
<p>Both these mechanisms use single transport connection to send the request
and to receive the response. They severely lags the capability of using two
transport connections for the request and the response (either One-Way 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 <strong>two
separate transport connections for request and response</strong>. The
asynchronous behavior that we gain using this solution can be called
<b>Transport Level Asynchrony</b>.</p>
<p>By combining API Level Asynchrony &amp; Transport Level Asynchrony we can
obtain four different invocation patterns for web services as shown in the
following table.</p>
<a name="table1"></a>
<table width="100%" border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td width="33%" height="19"><p><strong>API
(Blocking/Non-Blocking)</strong></p>
</td>
<td width="33%"><p><strong> Dual Transports (Yes/No)</strong></p>
</td>
<td width="33%"><p><strong>Description</strong></p>
</td>
</tr>
<tr>
<td width="33%" height="19"><p>Blocking</p>
</td>
<td width="33%"><p>No</p>
</td>
<td width="33%"><p>Simplest and the familiar invocation pattern</p>
</td>
</tr>
<tr>
<td width="33%" height="19"><p>Non-Blocking</p>
</td>
<td width="33%"><p>No</p>
</td>
<td width="33%"><p>Using callbacks or polling</p>
</td>
</tr>
<tr>
<td width="33%" height="19"><p>Blocking</p>
</td>
<td width="33%"><p>Yes</p>
</td>
<td width="33%"><p>This is useful when the service operation is IN-OUT
in nature but the transport used is One-Way (e.g. SMTP)</p>
</td>
</tr>
<tr>
<td width="33%" height="19"><p>Non-Blocking</p>
</td>
<td width="33%"><p>Yes</p>
</td>
<td width="33%"><p>This is can be used to gain the maximum asynchronous
behavior. No blocking in the API level and also in the transport
level</p>
</td>
</tr>
</tbody>
</table>
<p>Axis2 provides the user with all these possibilities to invoke Web
Services.</p>
<p>Below we describe how to write Web Services Clients using Axis2. This can
be done in two methods:</p>
<ol>
<li><a href="#primaryAPIs">Using the Axis2's primary APIs</a></li>
<li><p><a href="#databinding">Using stubs generated with data binding
support</a>, making the life easy for developers writing Web Service
client applications</p>
</li>
</ol>
<h3><a name="primaryAPIs">Writing Web Service Clients Using Axis2's Primary
APIs</a></h3>
<h4><a name="echoblocking">EchoBlockingClient</a></h4>
<p>Axis2 provides the user with several invocation patterns for Web Services,
ranging from pure blocking single channel invocations to a non-blocking dual
channel invocations. Let's first see how we can write a client to invoke
"echo" operation of "MyService" using the simplest blocking invocation. The
client code you need to write is as follows.</p>
<pre> try {
OMElement payload = ClientUtil.getEchoOMElement();
<font color="#33cc00"> Options options = new Options();
options.setTo(targetEPR);
options.setListenerTransportProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(false);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);</font>
<font color="#33cc00"> OMElement result = sender.sendReceive(payload);</font>
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();
}
}</pre>
<p>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. </p>
<h4><a name="ping">PingClient</a></h4>
<p>In the Web Service "MyService" we had a IN-ONLY operation with the name
"ping" (see <a href="#WS">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);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}</pre>
<p>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".</p>
<p>We have invoked the two operations in our service. Are we done? No! There
are lot more to explore. Let's see some other ways to invoke the same
operations...</p>
<h4><a name="echononblocking">EchoNonBlockingClient</a></h4>
<p>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.</p>
<p>A sample client for this can be found under
"Axis2Home/samples/userguide/src/userguide/clients" with the name
EchoNonBlockingClient. If we consider the changes that user may have to do
with respect to the "EchoBlockingClient" that we have already seen, it will
be as follows:</p>
<pre style="margin-bottom: 0.2in">serviceClient.sendReceiveNonblocking(payload, callback);</pre>
<p>The invocation accepts a callback object as a parameter. Axis2 client API
provides an abstract Callback with the following methods:</p>
<pre>public abstract void onComplete(AsyncResult result);
public abstract void onError(Exception e);
public boolean isComplete() {}</pre>
<p>The user is expected to implement the "onComplete " and "onError "
methods of their extended call back class. Axis2 engine calls the onComplete
method once the Web Service response is received by the Axis2 Client API
(ServiceClient). This will eliminate the blocking nature of the Web Service
invocations and provides the user with the flexibility to use Non Blocking
API for Web Service Clients.</p>
<p>To run the sample client ( EchoNonBlockingClient) you can simply use the
"testEchoNonBlockingClient" target of the ant file found at the
"Axis2Home/samples" directory.</p>
<h4><a name="echononblockingdual">EchoNonBlockingDualClient</a></h4>
<p>The solution provided by the Non-Blocking API has one limitation when it
comes to  Web Service invocations which takes long time to complete. The
limitation is due to the use of single transport connection to invoke the Web
Service and to retrieve the response. In other words, client API provides a
non blocking invocation mechanism for the users, but the request and the
response comes in a single transport (Two-Way transport) connection (like
HTTP). Long running Web Service invocations or Web Service invocations using
One-Way transports (like SMTP) cannot be utilized by simply using a non
blocking invocation. </p>
<p>The trivial solution is to use separate transport connections (either
One-Way or Two-Way) for the request and response. The next problem that needs
to be solved is the correlation (correlating the request and the response).
<a href="http://www.w3.org/Submission/ws-addressing/"
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
users that may populate them. Even the transports can populate these. Hence
Axis2 has the flexibility to use different versions of addressing)</p>
<p>Users can select between Blocking or Non-Blocking APIs for the Web Service
clients with two transport connections. By simply using a boolean flag, the
same API can be used to invoke web services (IN-OUT operations) using two
separate transport connections. Let's see how it's done using an example.
Following code fragment shows how to invoke the same "echo" operation using
Non-Blocking API with two transport connections<strong>. The ultimate
asynchrony!!</strong></p>
<pre> try {
OMElement payload = ClientUtil.getEchoOMElement();
Options options = new Options();<br> options.setTo(targetEPR);<br> options.setListenerTransportProtocol(Constants.TRANSPORT_HTTP);
//The boolean flag informs the axis2 engine to use two separate transport connection
//to retrieve the response.
<br> options.setUseSeparateListener(true);
ServiceClient serviceClinet = new ServiceClinet();
<br> serviceClinet.setOptions(options);</pre>
<pre>
//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);
}
<font color="#33cc00">serviceClinet.finalizeInvoke();</font>
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}</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>serviceClinet.finalizeInvoke()</b>" informs the Axis2 engine to
stop the client side listener started to retrieve the
response.</font></font></p>
<p>Before we run the sample client we have one more step to perform. As
mentioned earlier Axis2 uses addressing based correlation mechanism, hence we
need to "engage" addressing module in the server side as well. According to
the Axis2 architecture, addressing module is deployed in the
"<strong>pre-dispatch</strong>" phase (See <a
href="Axis2ArchitectureGuide.html" target="_blank">Architecture Guide</a> for
more details about phases)  and hence "engaging" means simply adding module
reference in the "axis2.xml" (NOT the "services.xml"). Now add the following
line to the "axis2.xml" that you can find in the "/webapps/axis2/WEB-INF"
directory in the servlet container. </p>
<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>
<p>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.</p>
<h4><a name="echoblockingdual">EchoBlockingDualClient</a></h4>
<p>This is again a Two-Way transport request/response client, but this time,
we use a Blocking API in the client code. Sample code for this can be found
in the "Axis2Home/samples/userguide/src/userguide/clients/" directory and the
explanation is similar to the <a
href="#echononblockingdual">EchoNonBlockingDualClient</a>, except that here
we do not use a callback object to handle response. This is a very useful
mechanism when the service invocation is IN-OUT in nature and the transports
are One-Way (e.g. SMTP). For the sample client we use two HTTP connections
for request and response. User can test this client using the
"echoBlockingDualClient" target of the ant build file found in the
"Axis2Home/samples" directory.</p>
<p>See <a href="http-transport.html" target="_blank">Configuring
Transports</a> for use different transports.</p>
<h3><a name="databinding">Writing Web Service Clients using Code Generation
with Data Binding Support</a></h3>
<p>Axis2 provides the data binding support for Web Service client as well.
The user can generate the required stubs from a given WSDL with the other
supporting classes. Let's generate stubs for the WSDL used earlier to
generate the skeleton for the "Axis2SampleDocLitPortType". Simply run the
WSDL2Java tool that can be found in the bin directory of the Axis2
distribution using the following command:</p>
<pre style="margin-bottom: 0.2in">WSDL2Java -uri ..\samples\wsdl\Axis2SampleDocLit.wsdl -o ..\samples\src -p org.apache.axis2.userguide</pre>
<p>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).</p>
<h4><a name="echovoid">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="clientechostring">Client for echoString Operation</a></h4>
<p>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.</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");
//Create the request document to be sent.
EchoStringParamDocument reqDoc= EchoStringParamDocument.Factory.newInstance();
reqDoc.setEchoStringParam("Axis2 Echo");
//invokes the web service.
EchoStringReturnDocument resDoc=stub.echoString(reqDoc);
System.out.println(resDoc.getEchoStringReturn());
} catch (Exception e) {
e.printStackTrace();
}</pre>
<p>Similarly following code fragments show client side code for
echoStringArray operation and echoStruct operation respectively.</p>
<h4><a name="clientechostringarray">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/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 &lt; resParams.length; i++) {
System.out.println(resParams[i]);
}
} catch (Exception e) {
e.printStackTrace();
}</pre>
<h4><a name="clientechostruct">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/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();
}</pre>
<h2><a name="Modules"></a>Modules</h2>
<p>Axis2 provides an extended support for modules (See <a
href="Axis2ArchitectureGuide.html">Architecture Guide</a> 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:</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="logging">MyService with a Logging Module</a></h3>
<p>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.</p>
<p><img src="images/userguide/ModuleView.jpg" name="Graphic5" align="bottom"
width="185" height="120" border="0"></p>
<h4><a name="step1loggingmodule">Step1 : LoggingModule Class</a></h4>
<p>LoggingModule is the implementation class of the Axis2 module. Axis2
modules should implement the "org.apache.axis2.modules.Module" interface with
the following methods.</p>
<pre>public void init(AxisConfiguration axisSystem) throws AxisFault;//Initialize the module
public void shutdown(AxisConfiguration axisSystem) throws AxisFault;//End of module processing</pre>
<p>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.</p>
<h4><a name="step2loggingmodule">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" target="_blank"> Architecture Guide</a>
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.</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 revoke(MessageContext msgContext) {
log.info(msgContext.getEnvelope().toString());
}
public void setName(QName name) {
this.name = name;
}
}</pre>
<h4><a name="step3loggingmodule">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 it can be seen there are four phases 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. 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 on Phase rules, click on <a href="http://www.developer.com/java/web/article.php/3529321" target="_blank">here</a></p>
<h4><a name="step4loggingmodule">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 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".</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 or service author can add any phase he want --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="outflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="userphase1"/>
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;!--system predefined phase--&gt;
&lt;!--these phase 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="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;/phaseOrder&gt;
&lt;phaseOrder type="Outfaultflow"&gt;
&lt;!-- user can add his own phases to this area --&gt;
&lt;phase name="userphase1"/&gt;
&lt;phase name="<font color="#33cc00">loggingPhase</font>"/&gt;
&lt;phase name="PolicyDetermination"/&gt;
&lt;phase name="MessageOut"/&gt;
&lt;/phaseOrder&gt;
</pre>
<p>Shown 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 now will be executed in this phase.</p>
<h4><a name="step5loggingmodule">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. 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. The code for this service can be found in the
"Axis2Home/samples/userguide/src/userguide/example2" directory. The simple
changes that we have done to "services.xml' are shown in green in the
following lines of xml.</p>
<pre>&lt;service name="<font color="#33cc00">MyServiceWithModule</font>"&gt;
&lt;description&gt;
This is a sample Web Service with a logging module engaged.
&lt;/description&gt;
<font color="#33cc00">&lt;module ref="logging"/&gt;</font>
&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="step6loggingmodule">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 "Axis2Home/samples/userguide" directory.</p>
<h4><a name="step7loggingmodule">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 "LoggingModule.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. Deploy this service using the <a href="#step4">same steps
that you used to deploy "MyService"</a> and copy the "LoggingModule.mar" file
to the "modules" directory. Then run using the
"TestWebServiceWithModuleClient.bat" or "TestWebServiceWithModuleClient.sh"
in the "Axis2Home/samples/userguide/src/userguide/clients/bin" directory.</p>
<p>Note: To see the logs, the user needs to modify the "log4j.properties" to
log INFO. The property file is located in "webapps\axis2\WEB-INF\classes" 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 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 help document 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 binary
distribution. All these samples are included in the samples 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 source. Moving to the
modules/samples and running maven will create the samples in the
target/samples directory. However if the samples need to be started using the
shell scripts (or the batch files) then the AXIS_HOME environment need to be
set.( the "guessed" AXIS_HOME would not be correct in this case)</p>
<h3><a name="googlespell">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 samples\googleSpellcheck directory
and can be easily started using either the batch file or the shell script.</p>
<h3><a name="googlesearch">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 the samples\googleSearch directory and can be easily
started using either the batch file or the shell script.</p>
<h3><a name="amazonqueuing">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 dequeue. This
sample is included in the samples\amazonQS directory and also contains the
batch/shell scripts required to run sample.</p>
<h2><a name="Advanced_Topics"></a>Advanced Topics</h2>
<ul>
<li><style="margin-bottom: 0in"><a href="rest-ws.html"
target="_blank">RESTful Web Services</a></li>
<li><p style="margin-bottom: 0in"><a href="tcp-transport.html"
target="_blank">TCP transport</a></p>
</li>
<li><p style="margin-bottom: 0in"><a href="mail-transport.html"
target="_blank">Mail Transport</a></p>
</li>
<li><p style="margin-bottom: 0in"><a href="http-transport.html"
target="_blank">HTTP Transports</a></p>
</li>
<li><p><a href="mtom-guide.html" target="_blank">MTOM with Axis2</a></p>
</li>
<li><a href="security-module.html" target="_blank">Securing SOAP Messages
with WSS4J</a></li>
</ul>
</body>
</html>