<!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 & 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 & | |
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 & 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 ->Code generate the | |
Skeleton ->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><service > | |
<description> | |
This is a sample Web Service with two operations, echo and ping. | |
</description> | |
<parameter name="ServiceClass" locked="false">userguide.example1.MyService</parameter> | |
<operation name="echo"> | |
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> | |
</operation> | |
<operation name="ping"> | |
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> | |
</operation> | |
</service></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><serviceGroup> | |
<service name="Service1"> | |
<!-- details for Service1 --> | |
</service> | |
<service name="Service2"> | |
<!-- details for Service2 --> | |
</service> | |
<module ref="ModuleName" /> | |
<parameter name="serviceGroupParam1" locked="false">value 1</parameter> | |
</serviceGroup></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 < 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><!--Auto generated Axis Service XML--> | |
<service name="Axis2SampleDocLitPortTypeSkeletonTest"> | |
<parameter locked="xsd:false" name="ServiceClass">userguide.Axis2SampleDocLitPortTypeSkeleton</parameter> | |
<!--Mounting the method echoStringArray--> | |
<operation name="echoStringArray"> | |
<messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/> | |
</operation> | |
<!--Mounting the method echoStruct--> | |
<operation name="echoStruct"> | |
<messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/> | |
</operation> | |
<!--Mounting the method echoString--> | |
<operation name="echoString"> | |
<messageReceiver class="userguide.Axis2SampleDocLitPortTypeMessageReceiver"/> | |
</operation> | |
</service></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 & 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 | |
<wsa:MessageID> and <wsa:RelatesTo> headers. Axis2 provides | |
support for addressing based correlation mechanism and a complying Client | |
API to invoke Web Services with two transport connections. (Core of Axis2 | |
does not depend on WS-Addressing, but contains a set of parameters like in | |
addressing that can be populated in any means. WS-Addressing is one of the | |
users that may populate them. Even the transports can populate these. Hence | |
Axis2 has the flexibility to use different versions of addressing)</p> | |
<p>Users can select between Blocking or Non-Blocking APIs for the Web Service | |
clients with two transport connections. By simply using a boolean flag, the | |
same API can be used to invoke web services (IN-OUT operations) using two | |
separate transport connections. Let's see how it's done using an example. | |
Following code fragment shows how to invoke the same "echo" operation using | |
Non-Blocking API with two transport connections<strong>. The ultimate | |
asynchrony!!</strong></p> | |
<pre> try { | |
OMElement payload = ClientUtil.getEchoOMElement(); | |
Options options = new Options();<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"> <module ref="addressing"/></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 < 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><module name="logging" class="userguide.loggingmodule.LoggingModule "> | |
<inflow> | |
<handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"> | |
<order phase="loggingPhase" /> | |
</handler> | |
</inflow> | |
<outflow> | |
<handler name="OutFlowLogHandler" class="userguide.loggingmodule.LogHandler"> | |
<order phase="loggingPhase"/> | |
</handler> | |
</outflow> | |
<Outfaultflow> | |
<handler name="FaultOutFlowLogHandler" class="userguide.loggingmodule.LogHandler"> | |
<order phase="loggingPhase"/> | |
</handler> | |
</Outfaultflow> | |
<INfaultflow> | |
<handler name="FaultInFlowLogHandler" class="userguide.loggingmodule.LogHandler"> | |
<order phase="loggingPhase"/> | |
</handler> | |
</INfaultflow> | |
</module></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. "<order | |
phase="loggingPhase" />" describes the phase in which this handler | |
runs.</p> | |
<pre><handler name="InFlowLogHandler" class="userguide.loggingmodule.LogHandler"> | |
<order phase="loggingPhase" /> | |
</handler></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><!-- ================================================= --> | |
<!-- Phases --> | |
<!-- ================================================= --> | |
<phaseOrder type="inflow"> | |
<!-- System pre defined phases --> | |
<phase name="TransportIn"/> | |
<phase name="PreDispatch"/> | |
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> | |
<handler name="AddressingBasedDispatcher" | |
class="org.apache.axis2.engine.AddressingBasedDispatcher"> | |
<order phase="Dispatch"/> | |
</handler> | |
<handler name="RequestURIBasedDispatcher" | |
class="org.apache.axis2.engine.RequestURIBasedDispatcher"> | |
<order phase="Dispatch"/> | |
</handler> | |
<handler name="SOAPActionBasedDispatcher" | |
class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> | |
<order phase="Dispatch"/> | |
</handler> | |
<handler name="SOAPMessageBodyBasedDispatcher" | |
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> | |
<order phase="Dispatch"/> | |
</handler> | |
<handler name="InstanceDispatcher" | |
class="org.apache.axis2.engine.InstanceDispatcher"> | |
<order phase="PostDispatch"/> | |
</handler> | |
</phase> | |
<!-- System pre defined phases --> | |
<!-- After Postdispatch phase module author or or service author can add any phase he want --> | |
<phase name="userphase1"/> | |
<phase name="<font color="#33cc00">loggingPhase</font>"/> | |
</phaseOrder> | |
<phaseOrder type="outflow"> | |
<!-- user can add his own phases to this area --> | |
<phase name="userphase1"/> | |
<phase name="<font color="#33cc00">loggingPhase</font>"/> | |
<!--system predefined phase--> | |
<!--these phase will run irrespective of the service--> | |
<phase name="PolicyDetermination"/> | |
<phase name="MessageOut"/> | |
</phaseOrder/> | |
<phaseOrder type="INfaultflow"> | |
<!-- user can add his own phases to this area --> | |
<phase name="userphase1"/> | |
<phase name="<font color="#33cc00">loggingPhase</font>"/> | |
</phaseOrder> | |
<phaseOrder type="Outfaultflow"> | |
<!-- user can add his own phases to this area --> | |
<phase name="userphase1"/> | |
<phase name="<font color="#33cc00">loggingPhase</font>"/> | |
<phase name="PolicyDetermination"/> | |
<phase name="MessageOut"/> | |
</phaseOrder> | |
</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><service name="<font color="#33cc00">MyServiceWithModule</font>"> | |
<description> | |
This is a sample Web Service with a logging module engaged. | |
</description> | |
<font color="#33cc00"><module ref="logging"/></font> | |
<parameter name="ServiceClass" locked="xsd:false">userguide.example2.MyService</parameter> | |
<operation name="echo"> | |
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> | |
</operation> | |
<operation name="ping"> | |
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> | |
</operation> | |
</service></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>"<module | |
ref="logging"/>"</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> |