You are on page 1of 200

AXIS 2

Índice de contenido
AXIS 2..................................................................................................................................................1
Introduction..........................................................................................................................................7
Apache Axis2 User's Guide.............................................................................................................8
How To.............................................................................................................................................8
Data Bindings:.............................................................................................................................9
Transports:...................................................................................................................................9
Axis2 Tools:................................................................................................................................9
Apache Axis2 Developers..............................................................................................................10
References......................................................................................................................................11
Apache Axis2 Installation Guide........................................................................................................11
Contents.........................................................................................................................................11
Axis2 Distributions........................................................................................................................11
1. Standard Binary Distribution................................................................................................11
2. WAR (Web Archive) Distribution.........................................................................................12
3. Documents Distribution........................................................................................................12
4. Source Distribution...............................................................................................................12
System Requirements....................................................................................................................12
Install Axis2 as a Standalone Server using Standard Binary Distribution.....................................12
1. Download and Install the Apache Axis2 Binary Distribution...............................................12
2. Starting up Axis2 Standalone Server....................................................................................13
3. Building the Axis2 Web Application (axis2.war) Using Standard Binary Distribution........13
4. Getting Familiar with the Axis2 Convenient Scripts............................................................13
Install Axis2 in a Servlet Container...............................................................................................14
Uploading Services........................................................................................................................19
Advanced.......................................................................................................................................23
Axis2 Source Distribution.........................................................................................................23
Setting Up the Environment and Tools................................................................................23
Building Binaries and the WAR File Using the Source Distribution...................................24
Apache Axis2 Modules.......................................................................................................................24
Application Server Specific Configuration Guide.............................................................................25
WebLogic/ WebSphere..................................................................................................................25
1. Use exploded configuration to deploy Axis2 WAR..............................................................25
2. Lack of namespacing on serialised items..............................................................................26
Axis2 Quick Start Guide....................................................................................................................26
Content...........................................................................................................................................26
A Quick Setup Note:......................................................................................................................27
Introduction....................................................................................................................................27
Getting Ready................................................................................................................................33
Axis2 Services...............................................................................................................................34
Creating Services...........................................................................................................................35
Deploying POJOs......................................................................................................................35
Building the Service using AXIOM..........................................................................................37
Generating the Service using ADB...........................................................................................41
Generating the Service using XMLBeans.................................................................................42
Generating the Service using JiBX...........................................................................................44

1
Creating Clients.............................................................................................................................45
Creating a Client with AXIOM.................................................................................................45
Generating a Client using ADB................................................................................................48
Generating a Client using XMLBeans......................................................................................49
Generating a Client using JiBX................................................................................................51
Summary........................................................................................................................................52
For Further Study...........................................................................................................................52
Apache Axis2 User's Guide................................................................................................................53
Content...........................................................................................................................................53
Introducing Axis2..........................................................................................................................53
What is Axis2?..........................................................................................................................53
What's Under the Hood?...........................................................................................................54
How Axis2 Handles SOAP Messages.......................................................................................54
Axis2 Distributions...................................................................................................................55
The Axis2 Standard Binary Distribution..............................................................................55
axis2.war Distribution Directory Hierarchy.........................................................................56
Axis2 Documentation Distribution Directory Hierarchy.....................................................57
Axis2 and Clients.................................................................................................................58
Installing and Testing Client Code.................................................................................................58
Introduction to Services.................................................................................................................59
Message Exchange Patterns......................................................................................................59
Creating Clients.............................................................................................................................60
Choosing a Client Generation Method......................................................................................60
Generating Clients.....................................................................................................................61
Axis Data Binding (ADB).........................................................................................................61
Building Services...........................................................................................................................62
Getting Comfortable with the Available Options......................................................................62
Creating a Service from Scratch...............................................................................................63
Deploying Plain Old Java Objects (POJOs).............................................................................67
Deploying and Running an Axis2 Service Created from WSDL..............................................68
Code Listing 14 - Using the WSDL2Java Utility to Generate the Service..........................68
Code Listing 15 - Compiling the Service.............................................................................70
The Samples...................................................................................................................................73
Clients (in AXIS2_HOME/samples/userguide/src/clients):......................................................73
Services (in AXIS2_HOME/samples/userguide):.....................................................................73
Sample WSDL files (in AXIS2_HOME/samples):...................................................................73
Other samples............................................................................................................................73
In AXIS2_HOME/samples Directory:.................................................................................73
External:...............................................................................................................................74
For Further Study...........................................................................................................................74
Resources..................................................................................................................................74
Apache Axis2 Advanced User's Guide...............................................................................................75
Introduction....................................................................................................................................75
Getting Started...............................................................................................................................75
Creating a New Web Service....................................................................................................75
Starting with WSDL, Creating and Deploying a Service.........................................................75
Step1: Generate Skeleton Code............................................................................................76
Step 2: Implement Business Logic.......................................................................................76
Step 3: Create Archive File..................................................................................................76
Step 4: Deploy Web Service.................................................................................................77

2
Writing a Web Service Client....................................................................................................77
Generate Stubs..........................................................................................................................77
Do a Blocking Invocation.........................................................................................................78
Do a Non-Blocking Invocation.................................................................................................78
Using Your Own Repository.....................................................................................................79
Configuring Axis2..........................................................................................................................80
Axis2 Repository.......................................................................................................................80
Global Configurations...............................................................................................................80
Add New Services.....................................................................................................................80
Engaging Modules....................................................................................................................80
WS-Addressing Support...........................................................................................................81
Advanced Topics............................................................................................................................81
Transports..................................................................................................................................81
Attachments..............................................................................................................................82
Security.....................................................................................................................................82
REST Web Service....................................................................................................................82
Pluggable Data Binding............................................................................................................82
Axis2 Data Binding(ADB)........................................................................................................82
JiBX..........................................................................................................................................82
Other Topics..............................................................................................................................82
Axis2 Configuration Guide................................................................................................................82
Content...........................................................................................................................................83
Global Configuration.....................................................................................................................83
Parameter..................................................................................................................................83
Transport Receiver..................................................................................................................83
Transport Sender.......................................................................................................................84
Phase Order...............................................................................................................................84
Module References....................................................................................................................86
Listeners (Observers)................................................................................................................86
Service Configuration....................................................................................................................87
Module Configuration....................................................................................................................88
Apache Axis2 Web Administrator's Guide.........................................................................................90
Contents.........................................................................................................................................90
Introduction....................................................................................................................................91
Log on to the Administration Site.............................................................................................91
Administration Options..................................................................................................................92
Tools..........................................................................................................................................93
Upload Services....................................................................................................................93
System components...................................................................................................................94
Available Services................................................................................................................94
Available Service Groups.....................................................................................................95
Available Modules................................................................................................................96
Globally Engaged Modules..................................................................................................96
Available Phases...................................................................................................................96
Executions Chains.....................................................................................................................97
Global Chains.......................................................................................................................97
Operation Specific Chains....................................................................................................98
Engaging Modules..................................................................................................................100
Services...................................................................................................................................100
Deactivate Service..............................................................................................................100

3
Activate Service.................................................................................................................101
Edit Service Parameters......................................................................................................102
Contexts..................................................................................................................................103
View Hierarchy...................................................................................................................103
Apache Axis2 Architecture Guide....................................................................................................103
Contents.......................................................................................................................................103
The Big Picture............................................................................................................................104
Requirement of Axis2..................................................................................................................104
Axis2 Architecture.......................................................................................................................105
Core Modules:.........................................................................................................................106
Other Modules:.......................................................................................................................106
Information Model..................................................................................................................107
XML Processing Model..........................................................................................................108
SOAP Processing Model.........................................................................................................109
Axis2 Default Processing Model........................................................................................109
Processing an Incoming SOAP Message............................................................................110
Processing of the Outgoing Message.................................................................................110
Extending the SOAP Processing Model.............................................................................111
Deployment.............................................................................................................................111
The axis2.xml file...............................................................................................................112
Service Archive..................................................................................................................112
Module Archive..................................................................................................................112
Client API................................................................................................................................112
One Way Messaging Support.............................................................................................113
In-Out (Request Response) Messaging Support.................................................................113
Transports................................................................................................................................113
Code Generation......................................................................................................................114
Data Binding...........................................................................................................................115
Integration with the Code Generation Engine....................................................................115
Serialization and De-Serialization of Data bound classes..................................................116
POJO Web Services using Apache Axis2.........................................................................................116
Content.........................................................................................................................................116
Introduction..................................................................................................................................117
The POJO.....................................................................................................................................117
POJO Web Service Using Apache Axis2 and Tomcat.................................................................118
Defining the Service: services.xml..........................................................................................118
Building the POJO Web Service Using Apache Ant....................................................................119
Testing the POJO Web Service Using RPCServiceClient...........................................................120
Limitations and Strengths of POJO........................................................................................122
Spring-based POJO Web Service.................................................................................................122
Quick Introduction..................................................................................................................122
The Service Definition: services.xml......................................................................................122
Initializing the Spring Application Context: SpringInit..........................................................124
Build and Deploy Using Apache Axis2 and Tomcat...............................................................125
Testing Using an RPCServiceClient.......................................................................................125
Summary......................................................................................................................................125
For Further Study.........................................................................................................................125
Axis2 Integration with the Spring Framework.................................................................................126
Content.........................................................................................................................................126
Introduction..................................................................................................................................126

4
Configuring Axis2 to be Spring Aware........................................................................................126
Programming Model...............................................................................................................126
Simple Spring Config Example..............................................................................................127
With a ServletContext.............................................................................................................127
Without a ServletContext........................................................................................................128
Putting It All Together............................................................................................................129
Spring Inside an AAR.............................................................................................................132
The Spring inside an AAR layout ......................................................................................132
The Spring inside an AAR init class .................................................................................133
Known issues running Spring inside the AAR ..................................................................134
Writing Your Own Axis2 Module....................................................................................................134
Content List..................................................................................................................................134
MyService with a Logging Module.............................................................................................135
Step1 : LoggingModule Class.................................................................................................135
Step2 : LogHandler......................................................................................................................136
Step3 : module.xml.................................................................................................................136
Step 4: Modify the "axis2.xml"...............................................................................................137
Step5 : Modify the "services.xml"..........................................................................................139
Step6 : Packaging....................................................................................................................139
Step7 : Deploy the Module in Axis2.......................................................................................139
ADB Data Binding...........................................................................................................................140
Axis2 Databinding Framework....................................................................................................140
Content....................................................................................................................................140
Introduction.............................................................................................................................140
Architectural Overview...........................................................................................................140
Code and Dependencies..........................................................................................................141
Invoking the ADB Code Generator.........................................................................................141
As a Standalone Schema Compiler....................................................................................141
Through the API.................................................................................................................142
Generation Modes...................................................................................................................142
Deep into Generated Code......................................................................................................143
An Example!.......................................................................................................................144
Known Limitations.................................................................................................................145
Want to Learn More?..............................................................................................................145
Advanced Axis2 Databinding Framework Features....................................................................146
Content....................................................................................................................................146
xsi:type Support......................................................................................................................146
Helper mode............................................................................................................................147
Additional ADB Topics...........................................................................................................147
ADB Integration With Axis2.......................................................................................................147
Content....................................................................................................................................147
Introduction.............................................................................................................................148
Selection of Generation Modes for ADB................................................................................148
Things to Remember...............................................................................................................148
ADB Tweaking Guide..................................................................................................................148
Content....................................................................................................................................148
Introduction.............................................................................................................................149
Know the Configuration..............................................................................................................149
The First Tweak - Generate Plain Java Beans.........................................................................149
A More Advanced Tweak - Generate Code for Another Language........................................149

5
JiBx Data Binding............................................................................................................................150
JiBX Integration With Axis2........................................................................................................150
Content....................................................................................................................................150
Introduction.............................................................................................................................150
Wrapped vs. unwrapped..........................................................................................................151
Starting from Java...................................................................................................................151
Starting from WSDL...............................................................................................................152
WSDL2Java usage..................................................................................................................152
Coming Attractions.................................................................................................................152
References...............................................................................................................................153
JiBX general document/literal.....................................................................................................153
JiBX Unwrapped document/literal..............................................................................................157
Advanced..........................................................................................................................................160
Writing Web Services Using Apache Axis2's Primary APIs........................................................160
How to Write a Web Service?.................................................................................................161
Step1: Write the Implementation Class..............................................................................161
Step2: Write the services.xml file.......................................................................................161
Step3: Create the Web Service Archive..............................................................................163
Step4: Deploy the Web Service..........................................................................................163
Writing Web Service Clients Using Axis2's Primary APIs..........................................................164
Request-Response, Blocking Client........................................................................................166
One Way Client.......................................................................................................................166
Request-Response, Non-Blocking that uses one transport connection...................................167
Request-Response, Non-Blocking that uses two transport connections.................................168
Handling Binary Data with Axis2 (MTOM/SwA)...........................................................................169
Content.........................................................................................................................................169
Introduction..................................................................................................................................170
Where Does MTOM Come In?...............................................................................................170
MTOM with Axis2.......................................................................................................................171
Programming Model...............................................................................................................171
Enabling MTOM Optimization on the Client Side.................................................................172
Enabling MTOM Optimization on the Server Side................................................................172
Accessing Received Binary Data (Sample Code)...................................................................173
Service ...............................................................................................................................173
Client .................................................................................................................................173
MTOM Databinding................................................................................................................173
MTOM Databinding Using ADB.......................................................................................174
SOAP with Attachments (SwA) with Axis2................................................................................177
Receiving SwA Type Attachments..........................................................................................177
Sending SwA Type Attachments.............................................................................................178
MTOM Backward Compatibility with SwA...........................................................................179
Advanced Topics..........................................................................................................................180
File Caching for Attachments.................................................................................................180
Transports.........................................................................................................................................181
HTTP Transport...........................................................................................................................181
Content....................................................................................................................................181
CommonsHTTPTransportSender.......................................................................................181
Timeout Configuration.......................................................................................................182
HTTP Version Configuration..............................................................................................182
Proxy Authentication..........................................................................................................183

6
Basic, Digest and NTLM Authentication...........................................................................183
JMS Transport..............................................................................................................................184
Contents..................................................................................................................................184
Overview.................................................................................................................................184
Configuration..........................................................................................................................185
Writing Services to Use the JMS Transport............................................................................186
Echo - Service implementation and services.xml..............................................................186
Echo2 - Service implementation and services.xml............................................................187
Starting up the Axis2 JMS transport.......................................................................................188
TCP Transport..............................................................................................................................188
Content....................................................................................................................................188
Introduction.............................................................................................................................188
How to Start the TCPServer....................................................................................................188
How to Send SOAP Messages Using TCP Transport.............................................................188
Samples...................................................................................................................................189
Transport Components............................................................................................................189
Mail Transport..............................................................................................................................189
Invoking a Service Using a Mail Transport............................................................................189
Content...............................................................................................................................190
Prologue..............................................................................................................................190
Introduction........................................................................................................................190
1. Using the Simple Mail Server Included in Axis2...........................................................190
2. Using a Generic Mail Server..........................................................................................192
Resources............................................................................................................................192
Mail Transport Configuration......................................................................................................192
Content....................................................................................................................................193
Introduction.............................................................................................................................193
Transport Sender.....................................................................................................................193
Transport Receiver..................................................................................................................194
Using Mail Transport in the Server Side.................................................................................195
Using Mail Transport in the Client Side.................................................................................195
Configure James as SMTP and POP Server............................................................................195
Using the Included Mail Server..............................................................................................196
How to Write Your Own Axis2 Transport....................................................................................196
Prologue..................................................................................................................................196
Introduction.............................................................................................................................197
Transport Receiver..................................................................................................................197
Transport Sender.....................................................................................................................199

Introduction
Apache Axis2, the third generation Web services engine is more efficient, more modular and
more XML-oriented than its predecessor Apache Axis. It is carefully designed to support the
easy addition of plug-in modules that extend its functionality for features such as security and
increased reliability.
Apache Axis2 Version 1.2 comes to you with performance improvements and bug fixes over
the 1.1 release.
This page will take you through the list of documents that we have in store for you.

7
Apache Axis2 User's Guide
You can get started with Axis2 with the assistance of the following documents. They will
guide you through the Axis2 download, installation (both as a standalone Web services engine
and as part of a J2EE compliant servlet container), and instructions on how to write Web
services and Web services client using Apache Axis2.
• Introduction- Gives you an introduction to what Axis2 is, the life cycle of a Web
services message, how Axis2 handles SOAP messages and also includes a basic
description on Axis2 distributions, and how Axis2 behaves as part of a Web application
or as a standalone client that is not part of a J2EE application.
• Download and Installation- Lists the different distribution packages offered by Axis2
and gives in-depth instructions on the installation of the standalone method and as part
of a J2EE servlet container.
• Testing Client Code - The best way to make sure that your system is running Axis2 is
to install and test both a service and a client. This document describes this process in
easy to understand steps.
• Introduction to Services - The term "Web services" can apply to a number of
different ways of sending information back and forth. However, this guide focuses on
the sending and receiving of SOAP messages and Message Exchange Patterns (MEPs).
• Creating Clients from WSDL - When it comes to creating a Web service client, you
can do it manually as described in the next document. However, in most cases, you will
have a Web Service Description Language (WSDL) definition that describes the
messages that clients should send and expect to receive. Axis2 provides several ways to
use this definition to automatically generate a client. This document explains how to
create a client using WSDL definitions.
• Building Services from Scratch - Now that you know how to use Axis2 to generate
clients from WSDL as described in the document before, this document digs a little
deeper, showing you how to create services, and how to create both services and clients
"from scratch", so to speak.
• Samples - The Axis2 Standard Distribution provides a number of samples you can
use as a guide for implementing specific features and capabilities. These services are
listed in this document along with basic introductions for each one.
• For Further Study - This section lists resource documents for further study.
• POJO Web Services using Apache Axis2-This guide will show you how to create
a Plain Old Java Object (POJO) for deploying using Apache Axis2 on Apache
Tomcat. POJOs are fast to build and easy to maintain, which means you'll save a
lot of time building and debugging your code
• Axis2 Quick Start Guide-The purpose of this guide is to get you started on
creating services and clients using Axis2 as quickly as possible. It demonstrates
how to create Web services using a variety of different technologies.
Also see our FAQ page to answer those common questions in mind.

How To
This section deals with more advanced topics including Axis2 support features such as
Transports, Attachments, Pluggable Data Binding, Security, and REST Web services in detail.
• Web Administrator's Guide - Detailed instructions on the administration console of
Axis2 Web application, which provides run-time configuration of Axis2.
• Migrating from Axis 1.x to Axis 2 - Guiding Axis 1.x users in upgrading to Axis2

8
• Application Server Specific Configuration Guide - Provides extra configuration
information required for application servers to run Axis2 to its fullest potential
• AXIOM Tutorial-An introduction to Axis2's Object Model
• REST Support-Introduction on Representational State Transfer
• Axis2 RPC Support - This document talks about the Axis2's Remote Procedure Calls
support in a set of easy to understand implementation steps
• MTOM Guide -Sending Binary Data with SOAP - Explains how to send binary data
using the SOAP Message Transmission Optimization Mechanism
• Axis2 Configuration Guide - Explains the three configurations in Axis2: global,
service, and module
• SOAP Monitor How-to - A guide on the utilities used to monitor the SOAP messages
that invoke Web services, along with the results of those messages
• Web Services Policy Support In Axis2 - Introduction to the role of Web services policy
in Axis2
• Spring Framework - A guide on how to use Axis2 with the Spring Framework
• JSON Support - This document explains how to use JSON support implementation in
Axis2. Includes details on test cases and samples
• Guide to using EJB Provider in Axis2 - This guide explains how to use an EJB provider
in Axis2 using an example.

Data Bindings:
• ADB How-to - A guide on the Axis2 Databinding Framework (ADB)
• Advanced ADB Framework Features - Provides an insight into the newly added
advanced features of ADB
• Tweaking the ADB Code Generator - Explains the available mechanisms to extend
ADB
• ADB Integration with Axis2 - A guide to writing an extension using the integrator in
order to integrate ADB with Axis2
• JiBX Integration With Axis2 - A guide to using JiBX with Axis2 in order to expose
existing Java code as a Web service and to implement a client for an existing Web
service

Transports:
• TCP Transport - A guide to sending and receiving SOAP messages via TCP in Axis2
• Mail Transport - Explains how to invoke a service using a Mail transport
• Mail Transport Configuration - A guide to configuring Axis2 in order to get mail
transport working
• HTTP Transports - A description on HTTP sender and HTTP receiver in Axis2
• JMS Transport - A description on JMS sender and JMS receiver in Axis2
• Write Your Own Axis2 Transport - A quick and easy guide to create your own Axis2
Transport protocol

Axis2 Tools:
• Code Generator Tool Guide for Command Line and Ant Tasks - Lists command line

9
and Ant task references. How to build a file using custom Ant tasks and how to invoke a
Code Generator from Ant
• Code Generator Wizard Guide for Eclipse Plug-in - Explains the usage of the code
generator Eclipse plug-in for WSDL2Java and/or Java2WSDL operations
• Service Archive Generator Wizard Guide for Eclipse Plug-in - Describes the
functionality of the Eclipse plugin service archive generator tool
• Code Generator Wizard Guide for IntelliJ IDEA Plug-in - A guide on the usage of the
IDEA code generation plug-in to create service archives and generate Java class files
from WSDL files
• Maven2 AAR Plug-in Guide - A guide to generate an Axis 2 service file (AAR file)
using the Maven plug-in.
• Maven2 Java2WSDL Plug-in Guide - A guide to using Java2WSDL Maven 2 Plug-in
that takes a Java class as input and generates a WSDL, which describes a Web service
for invoking the class methods
• Maven2 WSDL2Code Plug-in Guide - A guide to using this plugin that takes as input a
WSDL and generates client and server stubs for calling or implementing a Web service
matching the WSDL.

Apache Axis2 Developers


• Advanced User's Guide - A quick start user's guide for more experienced users and
developers on how to install, create Web services and Web service clients using Axis2.
• Introduction - Outlines the overall direction of the user guide, with a high level
introduction on Axis2
• Download and Installation - Lists the different distribution packages offered by
Axis2, and the installations for the standalone and as part of a J2EE servlet
container methods.
• Creating a new Web Service with Code Generation - Axis2 provides two ways
to create new Web Services: using code generation and XML based primary APIs.
This section explains how to start from a WSDL, and create a new Service with
code generation
• Writing Web Services Using Axis2's Primary APIs - Explains how to create new
Web Services using XML based primary APIs
• Writing a Web Service Client with Code Generation - Axis2 also provides a
more complex, yet powerful XML based client API that is intended for advanced
users. However, if you are a new user we recommend using the code generation
approach presented below
• Writing Web Service Clients Using Axis2's Primary APIs - This section presents
complex yet powerful XML based client APIs, which is intended for advanced
users to write Web services clients
• Configuring Axis2 - Axis2 configuration is based on a repository and standard
archive formats. Here you will find details on how to configure Axis2. You will
also find reference documents that lead to greater detail in this area.
• Axis2 Architecture Guide - Introduction to Axis2's modular architecture
• Online Java Docs - Java API documentation
• Reference Library - This document provides additional information to developers on
WS-* specifications, Java language specifications, Subversion (SVN) control etc.

10
References
Gives you a list of published articles, tutorials and Questions-Answers on Apache Axis2.
Check them out for that extra knowledge on the next generation Web services engine Apache
Axis2. Be Informed and up-to-date!

Apache Axis2 Installation Guide


This document provides information on Axis2 distribution packages, system prerequisites
and setting up environment variables and tools followed by detailed instructions on installation
methods.
Send your feedback to: axis-dev@ws.apache.org mailing list. (Subscription details are
available on Axis2 site.) Kindly prefix every email subject with [Axis2].

Contents
• Axis2 Distributions
• System Requirements
• Install Axis2 as a Standalone Server using Standard Binary Distribution
• Install the Apache Axis2 Binary Distribution
• Starting up Axis2 Standalone Server
• Building WAR File Using Standard Binary Distribution
• Getting Familiar with the Axis2 Convenient Scripts
• Install Axis2 in a Servlet Container
• Uploading Services
• Advanced
• Axis2 Source Distribution
• Setting up the Environment and Tools
• Building Axis2 Binaries and the WAR file Using the Source Distribution

Axis2 Distributions
Axis2 is distributed in several convenient distribution packages and can be installed either
as a standalone server or as part of a J2EE compliant servlet container. Axis2 is distributed
under the Apache License, version 2.0. This Installation Guide will mainly focus on running
Apache Axis2 using the Standard Binary Distribution.
Download distribution packages of the Apache Axis2 1.2 version (latest).
Download distribution packages of all versions of Apache Axis2.
The Distribution Packages Provided are as follows:

1. Standard Binary Distribution


This is the complete version of Axis2 and includes samples and convenient scripts as well.
Download Standard Binary Distribution

11
2. WAR (Web Archive) Distribution
This is the Web application of Axis2, which can be deployed in most of the servlet
containers.
Download WAR (Web Archive) Distribution

3. Documents Distribution
This contains all the documentation in one package. The package includes the xdocs and the
Java API docs of this project.
Download Documents Distribution

4. Source Distribution
This contains the sources of Axis2 standard distribution, and is mainly for the benefit of the
advance users. One can generate a binary distribution using the source by typing $maven dist-
bin. You need to set up the Axis2 environment before running this command. Step by step
details on how to create the binary distribution is available in the Advanced section.
Download Source Distribution

System Requirements
1.4 or later (For instructions on setting up the JDK in
Java Development Kit (JDK)
different operating systems, visit http://java.sun.com)
Approximately 11 MB separately for standard binary
Disk
distribution
Tested on Windows XP, Linux, Mac OS X, Fedora core,
Operating system
Ubuntu, Gentoo
Build Tool-Apache Ant
To run samples and to build WAR Version 1.6.5 or higher (download).
files from Axis2 binary distribution.
Build Tool- Apache Maven 1.x 1.0.2 or higher in Maven 1.x series (download). Please
Required only for building Axis2 download Maven 1.x version. Axis2 does not
from Source Distribution support Maven 2.
Make sure that the above prerequisites are available for the Axis2 installation.

Install Axis2 as a Standalone Server using Standard


Binary Distribution
This section provides you with the following information
1. Install Axis2 as a standalone server using the Standard Binary Distribution
2. Start up the Axis2 standalone server
3. Building the axis2.war file (using the Standard Binary Distribution) which is required
to run Axis2 as part of a J2EE compliant servlet container
4. Running Axis2 convenient scripts

1. Download and Install the Apache Axis2 Binary Distribution


Download and install a Java Development Kit (JDK) release (version 1.4 or later). Install the

12
JDK according to the instructions included with the release. Set an environment variable
JAVA_HOME to the pathname of the directory into which you installed the JDK release.
Download and unpack the Axis2 Standard Binary Distribution into a convenient location so
that the distribution resides in its own directory. Set an environment variable AXIS2_HOME to
the pathname of the extracted directory of Axis2 (Eg: /opt/axis2-1.2).

2. Starting up Axis2 Standalone Server


Standalone Axis2 server can be started by executing the following commands:
$AXIS2_HOME\bin\axis2server.bat (Windows)
$AXIS2_HOME/bin/axis2server.sh (Unix)
After startup, the default web services included with Axis2 will be available by visiting
http://localhost:8080/axis2/services/

3. Building the Axis2 Web Application (axis2.war) Using


Standard Binary Distribution
Download and install Apache Ant (version 1.6.5 or later). Install Apache Ant according to
the instructions included with the Ant release.
Locate the Ant build file (build.xml) inside the webapp directory, which resides in your Axis2
home directory (i.e:- $AXIS_HOME/webapp)". Run the Ant build by executing "ant create.war"
inside the $AXIS2_HOME/webapps folder. You can find the generated axis2.war inside the
$AXIS2_HOME/dist directory. All the services and modules that are present in the
AXIS2_HOME/repository will be packed into the created axis2.war together with the Axis2
configuration found at $AXIS2_HOME/conf/axis2.xml.
Read Installing Axis2 in a Servlet Container to find out how to deploy the Axis2 Web
application in a servlet container.

4. Getting Familiar with the Axis2 Convenient Scripts


It is advised to add the $AXIS2_HOME/bin to the PATH, so that you'll be able to run the
following scripts from any where.
Script Name Description
You can use this script to run web service clients written using Axis2. This script
calls the "java" command after adding the classpath for Axis2 dependent
libraries (*.jar files present in your AXIS2_HOME/lib), setting the Axis2
axis2.{bat|
repository location (AXIS2_HOME/repository) and setting the Axis2
sh}
configuration file location(AXIS2_HOME/conf/axis2.xml) for you. With this you
can be relieved from setting all the above Axis2 specific parameters.
Usage : axis2.{sh.bat} [-options] class [args...]
This script will start a standalone Axis2 server using the
AXIS2_HOME/repository as the Axis2 repository and the
AXIS2_HOME/conf/axis2.xml as the Axis2 configuration file. This will start all
the transport listeners listed in the AXIS2_HOME/conf/axis2.xml.
axis2server.{
For example, if you want to deploy a service using a standalone Axis2
sh|bat}
server,then copy your service archive to the AXIS2_HOME/repository/services
directory. Next, go to the "Transport Ins" section of the
AXIS2_HOME/conf/axis2.xml and configure the transport receivers
(simpleHttpServer in port 8080 is listed by default). Then invoke this script.
wsdl2java.{b This script generates Java code according to a given WSDL file to handle Web
at|sh} service invocations (Client side Stubs). This script also has the ability to
generate service skeletons according to the given WSDL.

13
Usage: wsdl2java.{sh|bat} [OPTION]... -uri <Location of WSDL>
e.g., wsdl2java.sh -uri ../wsdl/Axis2Sample.wsdl
A more detailed reference about this script can be found here
This script generates the appropriate WSDL file for a given Java class.
java2wsdl.{b Usage: Java2WSDL.{sh|bat} [OPTION]... -cn <fully qualified class name>
at|sh} e.g., Java2WSDL.sh -cn ../samples/test/searchTool.Search
A more detailed reference about this script can be found here

Install Axis2 in a Servlet Container


Which ever the distribution, installing Axis2 in a J2EE compliant servlet container is as
follows:
1. Build the Axis2 WAR file using the Axis2 Standard Binary Distribution. (Alternatively
you can download the axis2.war file or you can build axis2.war using the Source
Distribution.
2. Drop the WAR file in the webapps folder of the servlet container. Most servlet
containers will automatically install the WAR file. (Some servlet containers may require
a restart in order to capture the new web application. Refer to your servlet container
documentation for more information.)
3. Once the WAR is successfully installed, test it by pointing the web browser to the
http://<host :port>/axis2. It should produce the following page which is the Axis2
Web Application Home Page.

4. Use the link "Validate" to ensure that everything is fine and smooth. If the validation
fails then the WAR has failed to install properly or some essential jars are missing. In
such a situation, refer to the documentation of the particular servlet container to find
the problem. The following page is a successful validation. Note that the statement core
Axis2 libraries are present.

14
15
16
17
18
Note: For any Application server specific installation information please refer to the
Application Server Specific Configuration Guide.

Uploading Services
The Axis2 Web application also provides an interface to upload services. Once a service
is created according to the service specification as described in the Advanced User's
Guide, that .jar file can be uploaded using the upload page.

19
The uploaded .jar files will be stored in the default service directory. For Axis2, this will be
the <webapps>/axis2/WEB-INF/services directory. Once a service is uploaded, it will be
installed instantly.
Since Axis2 supports hot deployment, you can drop the service jar directly through the file
system to the above mentioned services directory. It will also cause the service to be
automatically installed without the container being restarted.
Use the 'Services' link on the Web Application home page to check the successful installation
of a service. The services and the operations of successfully installed services will be displayed
on the available services page.

20
If the service has deployment time errors it will list those services as faulty services. If
you click on the link, you will see the deployment fault error messages.

Deployment time error message

21
22
Axis2 Administration is all about configuring Axis2 at the run time and the configuration
will be transient. More descriptions are available in the Axis2 Web Administration Guide

Advanced

Axis2 Source Distribution


By using the Source Distribution, both binary files (which can be downloaded as the Standard
Binary Distribution) and the axis2.war file (which can be downloaded as the WAR distribution) can
be built using Maven commands.
Required jar files do not come with the distribution and they will also have to be built by running
the maven command. Before we go any further, it is necessary to install Maven

Setting Up the Environment and Tools

Maven
The Axis2 build is based on Maven . Hence the only prerequisite to build Axis2 from the
source distribution is to have Maven installed. Extensive instruction guides are available at the
Maven site. This guide however contains the easiest path for quick environment setting.
Advanced users who wish to know more about Maven can visit this site.
• MS Windows
1. Download and run the Windows installer package for Maven.
2. Set the 'Environment Variables' ( create system variable MAVEN_HOME and edit
path. eg: "C:\Program Files\Apache Software Foundation\maven-1.0.2"; path
%MAVEN_HOME%\bin)
3. Make sure that the system variable JAVA_HOME is set to the location of your JDK,
eg. C:\Program Files\Java\jdk1.5.0_02
4. Run maven --version to verify that it is correctly installed.

23
• Unix based OS (Linux etc)
The tar ball or the zip archive is the best option. Once the archive is downloaded expand it
to a directory of choice and set the environment variable MAVEN_HOME and add
MAVEN_HOME/bin to the path as well. More instructions for installing Maven in Unix based
operating systems.
Once Maven is properly installed, you can start building Axis2.
Maven commands that are frequently used in Axis2 are listed on the FAQs page.

Building Binaries and the WAR File Using the Source Distribution
The Source Distribution is available as a zipped archive. All the necessary build scripts are
included with the source distribution. Once the source archive is expanded into a directory of
choice, moving to the particular directory and running maven command will build the Axis2 jar
file.

Once the command completes, the binaries (jar files in this case) can be found at a newly
created "target" directory.
Note: For the first Maven build (if the maven repository is not built first) it will
take a while since the required jars need to be downloaded. However, this is a once
only process and will not affect any successive builds.
The default maven build will however build only the Axis2 jar file. To obtain a WAR (Web
Archive), maven war command should be issued. This will create a complete WAR with the
name axis2.war inside the target directory.
Once this build step is complete, the binaries are ready to be deployed.

Apache Axis2 Modules


Axis2 architecture is flexible enough to extend its functionalities using modules. This page is
maintained to keep track of the relevant modules that are developed on top of Axis2.
Compatible
Name Description Version Axis2 Downloads
version
Addressing This is an implementation of WS- 1.2 1.2 mar MD5 PGP
Addressing submission version (2004-
08) and WS-Addressing 2005-08

24
versions.
SOAP Monitor utility provides a way for
Web services developers to monitor the
SOAP
SOAP messages being sent/received 1.2 1.2 zip MD5 PGP
Monitor
without requiring any special
configuration or restarting of the server
An implementation of WS-RM
Sandesha2 1.2 1.2 zip MD5 PGP
specification February 2005
The WS-Security and WS-
SecureConversation implementation for
Rampart 1.2 1.2 zip MD5 PGP
axis2. Now with a new configuration
model based on WS-SecurityPolicy

Previous module releases are available here

Application Server Specific Configuration


Guide
This document provides configuration information required for your Application Server to
run Apache Axis2 to its fullest potential.
Send your feedback or questions to: axis-dev@ws.apache.org. ( Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

WebLogic/ WebSphere

1. Use exploded configuration to deploy Axis2 WAR


We recommend using the exploded configuration to deploy Axis2 WAR in WebLogic and
WebSphere application servers to support the hotupdate/ hotdeployment features in Axis2.
However, if you do want to deploy custom WARs, say in a clustering environment, you need to
add two additional files into the WEB-INF named "services.list" and "modules.list" under the
modules and services directory respectively.
• WEB-INF/services/services.list : should list all the services (aar files) that you
want to expose.
• WEB-INF/modules/modules.list : should list all the modules (mar files) that you
want to use.
NOTE: In both cases, please list one entry per line.
WebLogic ships with JARs that conflict with JARs present in Axis2. Therefore use <prefer-
web-inf-classes> to ensure that JARs packaged in Axis2 WAR are picked up from WEB-INF/lib.
You can do this by setting the <prefer-web-inf-classes> element in WEB-INF/weblogic.xml to
true. An example of weblogic.xml is shown below:

<weblogic-web-app>
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
</weblogic-web-app>

If set to true, the <prefer-web-inf-classes> element will force WebLogic's classloader to load

25
classes located in the WEB-INF directory of a Web application in preference to application or
system classes. This is a recommended approach since it only impacts a single Web module.
Please refer to the following documents in WebLogic/ WebSphere for more information:
• WebLogic ServerApplication Classloading- For more information on how WebLogic's
class loader works
• Redeploying a Web Application in Exploded Directory Format
• Deploying the Web application in exploded form

2. Lack of namespacing on serialised items


BEA WebLogic Server 9.0 comes with its own StAX implementation. This results in lack of
namespacing on serialised items. In turn, WeLogic server (WLS) breaks with AXIOM on the
WLS classpath. Hence a filtering classloader is required:
Adding the following to weblogic-application.xml should resolve the issue:

<prefer-application-packages>
<package-name>com.ctc.wstx.*</package-name>
<package-name>javax.xml.*</package-name>
<package-name>org.apache.*</package-name>
</prefer-application-packages>

Note that the classes - Xerces, StAX API, Woodstox need to be on the application classpath

Axis2 Quick Start Guide


The purpose of this guide is to get you started on creating services and clients using Axis2
as quickly as possible. We'll take a simple StockQuote Service and show you some of the
different ways in which you can create and deploy it, as well as take a quick look at one or two
utilities that come with Axis2. We'll then look at creating clients to access those services.

Content
• Introduction
• Getting Ready
• Axis2 services
• Creating services
• Deploying POJOs
• Building the service using AXIOM
• Generating the service using ADB
• Generating the service using XMLBeans
• Generating the service using JiBX
• Generating Clients
• Creating a client using AXIOM
• Generating a client using ADB
• Generating a client using XML Beans

26
• Generating a client using JiBX
• Summary
• For Further Study

A Quick Setup Note:


The code for the document can be found in the extracted Standard Binary Distribution, more
specifically at Axis2_HOME/samples/ inside the directories- quickstart, quickstartadb,
quickstartaxiom, quickstartjibx and quickstartxmlbeans. (Consider getting it now as it will help
you to follow along.) It includes Ant buildfiles (build.xml) that we'll refer to throughout the
examples to make compilation easier.

Introduction
Let's start with the service itself. We'll make it simple so you can see what is going on when
we build and deploy the services. A StockQuoteService example seems to be mandatory in
instances like this one, so let's use the following (see Code Listing 1).
Code Listing 1: The StockQuoteService class

27
28
29
30
31
32
package samples.quickstart.service.pojo;

import java.util.HashMap;

public class StockQuoteService {


private HashMap map = new HashMap();

public double getPrice(String symbol) {


Double price = (Double) map.get(symbol);
if(price != null){
return price.doubleValue();
}
return 42.00;
}

public void update(String symbol, double price) {


map.put(symbol, new Double(price));
}
}

It will be a simple service with two possible calls. One of which is an in/out message, and
the other is an in-only service. Ultimately, we'll package the service and deploy it in four
different ways.
First, let's look at how this simple Java class corresponds to a service.

Getting Ready
Before we build anything using Axis2, we have to take care of a little housekeeping. First
off, you'll need to get your environment ready for working with Axis2. Fortunately, it involves
just a few simple steps:
1. Download and install Java. (Minimum version is JDK1.4)
2. Download Axis2 and extract it to a target directory.
3. Copy the axis2.war file to the webapps directory of your servlet engine.
4. Set the AXIS2_HOME environment variable to point to the target directory in step.
Note that all of the scripts and build files Axis2 generates depend on this value, so don't
skip this step!
In most cases, we're also going to need a WSDL file for our service. Axis2's Java2WSDL can
be used to bootstrap a WSDL. To generate a WSDL file from a Java class, perform the following
steps:
1. Create and compile the Java class.
2. Generate the WSDL using the command:

%AXIS2_HOME%/bin/java2wsdl -cp . -cn


samples.quickstart.service.pojo.StockQuoteService -of
StockQuoteService.wsdl

Once you've generated the WSDL file, you can make the changes you need. For example,
you might add custom faults or change the name of the generated elements. For example, this
StockQuoteService.wsdl is in %AXIS2_HOME%/samples/quickstartadb/resources/META-INF
folder, which we'll be using throughout the rest of this guide, replaces the generic parameters
created by the generation process.

33
Axis2 Services
Before we build anything, it's helpful to understand what the finished product looks like.
The server side of Axis2 can be deployed on any Servlet engine, and has the following
structure. Shown in Code Listing 2.
Code Listing 2: The Directory Structure of axis2.war

axis2-web
META-INF
WEB-INF
classes
conf
axis2.xml
lib
activation.jar
...
xmlSchema.jar
modules
modules.list
addressing.mar
...
soapmonitor.mar
services
services.list
aservice.aar
...
version.aar
web.xml

Starting at the top, axis2-web is a collection of JSPs that make up the Axis2 administration
application, through which you can perform any action such as adding services and engaging
and dis-engaging modules. The WEB-INF directory contains the actual java classes and other
support files to run any services deployed to the services directory.
The main file in all this is axis2.xml, which controls how the application deals with the
received messages, determining whether Axis2 needs to apply any of the modules defined in
the modules directory.
Services can be deployed as *.aar files, as you can see here, but their contents must be
arranged in a specific way. For example, the structure of this service will be as follows:

- StockQuoteService
- META-INF
- services.xml
- lib
- samples
- quickstart
- service
- pojo
- StockQuoteService.class

Here, the name of the service is StockQuoteService, which is specified in the services.xml
file and corresponds to the top-level folder of this service. Compiled Java classes are placed
underneath this in their proper place based on the package name. The lib directory holds any
service-specific JAR files needed for the service to run (none in this case) besides those
already stored with the Axis2 WAR file and the servlet container's common JAR directories.

34
Finally, the META-INF directory contains any additional information about the service that Axis2
needs to execute it properly. The services.xml file defines the service itself and links the Java
class to it (See Code Listing 3).
Code Listing 3: The Service Definition File

<service name="StockQuoteService" scope="application">


<description>
Stock Quote Sample Service
</description>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
samples.quickstart.service.pojo.StockQuoteService
</parameter>
</service>

Here the service is defined, along with the relevant messageReceiver types for the different
message exchange patterns.
The META-INF directory is also the location for any custom WSDL files you intend to include
for this application.
You can deploy a service by simply taking this hierarchy of files and copying it to the
webapps directory of your servlet engine. This is known as the "exploded" format. You can also
compress your documents into an *.aar file, similar to a *.jar file, and place the *.aar file
directly in the servlet engine's webapps directory.
Now that you understand what we're trying to accomplish, we're almost ready to start
building.
First, download and unzip the appropriate version of Axis2 Standard Binary Distribution.
Make sure that you set the value of the AXIS2_HOME variable to match the location into which
you extracted the contents of this release.
Let's look at some different ways to create clients and services.

Creating Services
In this section, we'll look at five ways to create a service based on the StockQuoteService
class: deploying Plain Old Java Objects (POJO), building the service using AXIOM's OMElement,
generating the service using Axis2 Databinding Framework (ADB), generating the service using
XMLBeans, and generating the service using JiBX.

Deploying POJOs
To deploy the service using POJOs (Plain Old Java Objects), execute the following steps.
Note the directory structure contained at <AXIS2_HOME>/samples/quickstart (the
services.xml file is from the first section of this guide):

35
- quickstart
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- src
- samples
- quickstart
- service
- pojo
- StockQuoteService.java

Note that you can generate a WSDL from the quickstart directory by typing:
● ant generate.wsdl
However, creating StockQuoteService.wsdl is optional. It can be the version generated
directly from the Java class, or a customized version of that file, and that services.xml is the
same file referenced earlier in this document.
Now build the project by typing ant generate.service in the quickstart directory, which
creates the following directory structure:

- quickstart/build/classes
- META-INF
- services.xml
- samples
- quickstart
- service
- pojo
- StockQuoteService.class

If you want to deploy the service in an exploded directory format, rename the classes
directory to StockQuoteService, and copy it to the webapps/axis2/WEB-INF/services directory
in your servlet engine. Otherwise, copy the build/StockQuoteService.aar file to the
webapps/axis2/WEB-INF/services directory in your servlet engine. Then check to make sure
that the service has been properly deployed by viewing the list of services at:
● http://localhost:8080/axis2/services/listServices
You can also checkout the WSDL at:
● http://localhost:8080/axis2/services/StockQuoteService?wsdl
And the schema at:
● http://localhost:8080/axis2/services/StockQuoteService?xsd
Once the URLs are working, quickly test the service. Try pointing your browser to the
following URL:
● http://localhost:8080/axis2/services/StockQuoteService/getPrice?symbol=IBM
You will get the following response:

<ns:getPriceResponse
xmlns:ns="http://pojo.service.quickstart.samples/xsd"><ns:return>42</ns:
return></ns:getPriceResponse>

If you invoke the update method as,


● http://localhost:8080/axis2/services/StockQuoteService/update?symbol=IBM&p

36
rice=100
and then execute the first getPrice URL, you will see that the price has got updated.

Building the Service using AXIOM


To build a service "from scratch" using AXIOM, execute the following steps.
Note the directory structure contained at /samples/quickstartaxiom:

- quickstartaxiom
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- StockQuoteService.wsdl
- src
- samples
- quickstart
- service
- axiom
- StockQuoteService.java
- clients
- AXIOMClient.java

Since AXIOM is a little different, you're going to need a different services.xml file from the
one used for POJO. Define it, as shown in Code Listing 4.
Code Listing 4: The Service Definition File.

<service name="StockQuoteService" scope="application">


<description>
Stock Quote Service
</description>
<operation name="getPrice">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="update">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
<parameter
name="ServiceClass">samples.quickstart.service.axiom.StockQuoteService</
parameter>
</service>

Note that it's almost the same, except that the operations are explicitly defined in the
service.xml file, and the MessageReceivers are now RawXML.
Now, the above referenced StockQuoteService.java class, a plain Java class that uses
classes from the Axis2 libraries, is defined as shown in Code Listing 5.
Code Listing 5: The StockQuoteService Class using AXIOM

37
38
39
package samples.quickstart.service.axiom;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

import java.util.HashMap;
public class StockQuoteService {
private HashMap map = new HashMap();

public OMElement getPrice(OMElement element) throws


XMLStreamException {
element.build();
element.detach();

OMElement symbolElement = element.getFirstElement();


String symbol = symbolElement.getText();

String returnText = "42";


Double price = (Double) map.get(symbol);
if(price != null){
returnText = "" + price.doubleValue();
}
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs =
fac.createOMNamespace("http://axiom.service.quickstart.sampl
es/xsd", "tns");
OMElement method = fac.createOMElement("getPriceResponse",
omNs);
OMElement value = fac.createOMElement("price", omNs);
value.addChild(fac.createOMText(value, returnText));
method.addChild(value);
return method;
}

public void update(OMElement element) throws XMLStreamException {


element.build();
element.detach();

OMElement symbolElement = element.getFirstElement();


String symbol = symbolElement.getText();

OMElement priceElement =
(OMElement)symbolElement.getNextOMSibling();
String price = priceElement.getText();

map.put(symbol, new Double(price));


}
}

Axis2 uses AXIOM, or the AXIs Object Model, a DOM (Document Object Model)-like
structure that is based on the StAX API (Streaming API for XML). Methods that act as services
must take as their argument an OMElement, which represents an XML element that happens,
in this case, to be the payload of the incoming SOAP message. Here, you're extracting the
contents of the first child of the payload element, adding text to it, and using it as content for
the return OMElement. Unless this is an "in only" service, these methods must return an
OMElement, because that becomes the payload of the return SOAP message.

40
Now build the project by typing ant generate.service in the
Axis2_HOME/samples/quickstartaxiom directory.
Place the StockQuoteService.aar file in the webapps/axis2/WEB-INF/services directory of
the servlet engine, and check to make sure that the service has been properly deployed by
viewing the list of services at,
● http://localhost:8080/axis2/services/listServices
You can also check the custom WSDL at,
● http://localhost:8080/axis2/services/StockQuoteService?wsdl
and the schema at,
● http://localhost:8080/axis2/services/StockQuoteService?xsd

Generating the Service using ADB


To generate and deploy the service using the Axis2 Databinding Framework (ADB), execute
the following steps.
Generate the skeleton using the WSDL2Java utility by typing the following in the
Axis2_HOME/samples/quickstartadb directory:
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.service.adb -d adb -s -ss -sd -ssi -o build/service
Else, simply type ant generate.service in the Axis2_HOME/samples/quickstartadb directory.
The option -d adb specifies Axis Data Binding (ADB). The -s switch specifies synchronous or
blocking calls only. The -ss switch creates the server side code (skeleton and related files). The
-sd switch creates a service descriptor (services.xml file). The -ssi switch creates an interface
for the service skeleton. The service files should now be located at build/service.
If you generated the code by using WSDL2Java directly, next you have to modify the
generated skeleton to implement the service (if you used "ant generate.service", a completed
skeleton will be copied over the generated one automatically).
Open the build/service/src/samples/quickstart/adb/service/StockQuoteServiceSkeleton.java
file and modify it to add the functionality of your service to the generated methods; shown in
Code Listing 6.
Code Listing 6: Defining the Service Skeleton File

41
package samples.quickstart.service.adb;

import samples.quickstart.service.adb.xsd.GetPriceResponse;
import samples.quickstart.service.adb.xsd.Update;
import samples.quickstart.service.adb.xsd.GetPrice;

import java.util.HashMap;

public class StockQuoteServiceSkeleton {

private static HashMap map;

static{ map = new HashMap(); }

public void update(Update param0) {


map.put(param0.getSymbol(), new Double(param0.getPrice()));
}

public GetPriceResponse getPrice(GetPrice param1) {


Double price = (Double) map.get(param1.getSymbol());
double ret = 42;
if(price != null){
ret = price.doubleValue();
}
GetPriceResponse res =
new GetPriceResponse();
res.set_return(ret);
return res;
}
}

Now you can build the project by typing the following command in the build/service
directory:
● ant jar.server
If all goes well, you should see the BUILD SUCCESSFUL message in your window, and the
StockQuoteService.aar file in the build/service/build/lib directory. Copy this file to the
webapps/axis2/WEB-INF/services directory of the servlet engine.
You can check to make sure that the service has been properly deployed by viewing the list
of services at,
● http://localhost:8080/axis2/services/listServices
You can also check the custom WSDL at,
● http://localhost:8080/axis2/services/StockQuoteService?wsdl
and the schema at,
● http://localhost:8080/axis2/services/StockQuoteService?xsd

Generating the Service using XMLBeans


To generate a service using XMLBeans, execute the following steps.
Generate the skeleton using the WSDL2Java utility by typing the following in the
Axis2_HOME/samples/quickstartxmlbeans directory.
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.service.xmlbeans -d xmlbeans -s -ss -sd -ssi -o build/service

42
Else simply type ant generate.service in the Axis2_HOME/samples/quickstartxmlbeans
directory.
The option -d xmlbeans specifies XML Beans data binding. The -s switch specifies
synchronous or blocking calls only. The -ss switch creates the server side code (skeleton and
related files). The -sd switch creates a service descriptor (services.xml file). The -ssi switch
creates an interface for the service skeleton. The service files should now be located at
build/service.
If you generated the code by using WSDL2Java directly, next you have to modify the
generated skeleton to implement the service (if you used "ant generate.service", a completed
skeleton will be copied over the generated one automatically).
Next open the
build/service/src/samples/quickstart/service/xmlbeans/StockQuoteServiceSkeleton.java file
and modify it to add the functionality of your service to the generated methods (see Code
Listing 7).
Code Listing 7: Defining the Service Skeleton

package samples.quickstart.service.xmlbeans;

import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;
import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;
import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;

import java.util.HashMap;

public class StockQuoteServiceSkeleton implements


StockQuoteServiceSkeletonInterface {

private static HashMap map;

static{ map = new HashMap(); }

public void update(UpdateDocument param0) {


map.put(param0.getUpdate().getSymbol(), new
Double(param0.getUpdate().getPrice()));
}

public GetPriceResponseDocument getPrice(GetPriceDocument param1) {


Double price = (Double) map.get(param1.getGetPrice().getSymbol());
double ret = 42;
if(price != null){
ret = price.doubleValue();
}
System.err.println();
GetPriceResponseDocument resDoc =
GetPriceResponseDocument.Factory.newInstance();
GetPriceResponseDocument.GetPriceResponse res =
resDoc.addNewGetPriceResponse();
res.setReturn(ret);
return resDoc;
}
}

Build the project by typing the following command in the build/service directory, which
contains the build.xml file:
● ant jar.server

43
If all goes well, you should see the BUILD SUCCESSFUL message in your window, and the
StockQuoteService.aar file in the newly created build/service/build/lib directory. Copy this file
to the webapps/axis2/WEB-INF/services directory of the servlet engine.
You can check to make sure that the service has been properly deployed by viewing the list
of services at,
● http://localhost:8080/axis2/services/listServices
You can also check the custom WSDL at,
● http://localhost:8080/axis2/services/StockQuoteService?wsdl
and the schema at,
● http://localhost:8080/axis2/services/StockQuoteService?xsd

Generating the Service using JiBX


To generate and deploy the service using JiBX data binding, execute the following steps.
Generate the skeleton using the WSDL2Java utility by typing the following at a console in
the Axis2_HOME/samples/quickstartjibx directory:
%AXIS2_HOME%/bin/wsdl2java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.service.jibx -d jibx -s -ss -sd -ssi -uw -o build/service
Else, simply type "ant generate.service" in the Axis2_HOME/samples/quickstartjibx
directory.
The option -d jibx specifies JiBX data binding. The -s switch specifies synchronous or
blocking calls only. The -ss switch creates the server side code (skeleton and related files). The
-sd switch creates a service descriptor (services.xml file). The -ssi switch creates an interface
for the service skeleton. The -uw switch unwraps the parameters passed to and from the
service operations in order to create a more natural programming interface.
After running WSDL2Java, the service files should be located at build/service. If you
generated the code by using WSDL2Java directly, you need to modify the generated skeleton
to implement the service (if you used "ant generate.service" a completed skeleton will be
copied over the generated one automatically). Open the
build/service/src/samples/quickstart/service/jibx/StockQuoteServiceSkeleton.java file and
modify it to add the functionality of your service to the generated methods, as shown in Code
Listing 8.
Code Listing 8: Defining the Service Skeleton File

44
package samples.quickstart.service.jibx;

import java.util.HashMap;

public class StockQuoteServiceSkeleton implements


StockQuoteServiceSkeletonInterface {
private HashMap map = new HashMap();

public void update(String symbol, Double price) {


map.put(symbol, price);
}

public Double getPrice(String symbol) {


Double ret = (Double) map.get(symbol);
if (ret == null) {
ret = new Double(42.0);
}
return ret;
}
}

Now you can build the project by typing the following command in the build/service
directory:
● ant jar.server
If all goes well, you should see the BUILD SUCCESSFUL message in your window, and the
StockQuoteService.aar file in the build/service/build/lib directory. Copy this file to the
webapps/axis2/WEB-INF/services directory of the servlet engine.
You can check to make sure that the service has been properly deployed by viewing the list
of services at,
● http://localhost:8080/axis2/services/listServices
You can also check the custom WSDL at,
● http://localhost:8080/axis2/services/StockQuoteService?wsdl
and the schema at,
● http://localhost:8080/axis2/services/StockQuoteService?xsd
For more information on using JiBX with Axis2, see the JiBX code generation integration
details. You can also check the JiBX Axis2 Wiki page for updated information about using JiBX
with Axis2.

Creating Clients
In this section, we'll look at four ways to create clients based on the StockQuoteService
class: building an AXIOM based client, generating a client using Axis2 Databinding Framework
(ADB), generating a client using XMLBeans, and generating a client using JiBX.

Creating a Client with AXIOM


To build a client using AXIOM, execute the following steps.
Also, note the directory structure shown in the Creating a service with AXIOM section,
duplicated below for completeness.

45
- quickstartaxiom
- README.txt
- build.xml
- resources
- META-INF
- services.xml
- StockQuoteService.wsdl
- src
- samples
- quickstart
- service
- axiom
- StockQuoteService.java
- clients
- AXIOMClient.java

The above referenced AXIOMClient.java class is defined as follows, shown in Code Listing 9.
Code Listing 9: The AXIOMClient class using AXIOM

package samples.quickstart.clients;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class AXIOMClient {

private static EndpointReference targetEPR =


new
EndpointReference("http://localhost:8080/axis2/services/StockQuoteServic
e");

public static OMElement getPricePayload(String symbol) {


OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs =
fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd",
"tns");

OMElement method = fac.createOMElement("getPrice", omNs);


OMElement value = fac.createOMElement("symbol", omNs);
value.addChild(fac.createOMText(value, symbol));
method.addChild(value);
return method;
}

46
public static OMElement updatePayload(String symbol, double price) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs =
fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd",
"tns");

OMElement method = fac.createOMElement("update", omNs);

OMElement value1 = fac.createOMElement("symbol", omNs);


value1.addChild(fac.createOMText(value1, symbol));
method.addChild(value1);

OMElement value2 = fac.createOMElement("price", omNs);


value2.addChild(fac.createOMText(value2,
Double.toString(price)));
method.addChild(value2);
return method;
}

public static void main(String[] args) {


try {
OMElement getPricePayload = getPricePayload("WSO");
OMElement updatePayload = updatePayload("WSO", 123.42);
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

ServiceClient sender = new ServiceClient();


sender.setOptions(options);

sender.fireAndForget(updatePayload);
System.err.println("done");
OMElement result = sender.sendReceive(getPricePayload);

String response = result.getFirstElement().getText();


System.err.println("Current price of WSO: " + response);

} catch (Exception e) {
e.printStackTrace();
}
}

Axis2 uses AXIOM, or the AXIs Object Model, a DOM (Document Object Model)-like
structure that is based on the StAX API (Streaming API for XML). Here you setup the payload
for the update and getPrice methods of the service. The payloads are created similar to how
you created the getPriceResponse payload for the AXIOM service. Then you setup the Options
class, and create a ServiceClient that you'll use to communicate with the service. First you call
the update method, which is a fireAndForget method that returns nothing. Lastly, you call the
getPrice method, and retrieve the current price from the service and display it.
Now you can build and run the AXIOM client by typing ant run.client in the
Axis2_HOME/samples/quickstartaxiom directory.
You should get the following as output:
done
Current price of WSO: 123.42

47
Generating a Client using ADB
To build a client using Axis Data Binding (ADB), execute the following steps.
Generate the client databings by typing the following in the
Axis2_HOME/samples/quickstartadb directory:
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.clients -d adb -s -o build/client
Else, simply type ant generate.client in the Axis2_HOME/samples/quickstartadb directory.
Next take a look at quickstartadb/src/samples/quickstart/clients/ADBClient.java, and see
how it's defined in Code Listing 10.
Code Listing 10: The ADBClient Class

package samples.quickstart.clients;
import samples.quickstart.service.adb.StockQuoteServiceStub;

public class ADBClient{


public static void main(java.lang.String args[]){
try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService
");

getPrice(stub);
update(stub);

} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

/* fire and forget */


public static void update(StockQuoteServiceStub stub){
try{
StockQuoteServiceStub.Update req = new
StockQuoteServiceStub.Update();
req.setSymbol ("ABC");
req.setPrice (42.35);

stub.update(req);
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

48
/* two way call/receive */
public static void getPrice(StockQuoteServiceStub stub){
try{
StockQuoteServiceStub.GetPrice req = new
StockQuoteServiceStub.GetPrice();

req.setSymbol("ABC");

StockQuoteServiceStub.GetPriceResponse res =
stub.getPrice(req);

System.err.println(res.get_return());
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

This class creates a client stub using the Axis Data Bindings you created. Then it calls the
getPrice and update operations on the Web service. The getPrice method operation creates the
GetPrice payload and sets the symbol to ABC. It then sends the request and displays the
current price. The update method creates an Update payload, setting the symbol to ABC and
the price to 42.35.
Now build and run the client by typing ant run.client in the
Axis2_HOME/samples/quickstartadb directory.
You should get the following as output:
42
done

Generating a Client using XMLBeans


To build a client using the XML Beans data bindings, execute the following steps.
Generate the databings by typing the following in the xmlbeansClient directory.
%AXIS2_HOME%/bin/WSDL2Java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.service.xmlbeans -d xmlbeans -s -o build/client
Else, simply type ant generate.client in the Axis2_HOME/samples/quickstartxmlbeans
directory.
Note that this creates a client stub code and no server side code.
Next take a look at
quickstartxmlbeans/src/samples/quickstart/clients/XMLBEANSClient.java, and see how it's
defined in Code Listing 11.
Code Listing 11: The XMLBEANSClient class

49
package samples.quickstart.clients;

import samples.quickstart.service.xmlbeans.StockQuoteServiceStub;
import samples.quickstart.service.xmlbeans.xsd.GetPriceDocument;
import samples.quickstart.service.xmlbeans.xsd.GetPriceResponseDocument;
import samples.quickstart.service.xmlbeans.xsd.UpdateDocument;

public class XMLBEANSClient{

public static void main(java.lang.String args[]){


try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService
");

getPrice(stub);
update(stub);

} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

/* fire and forget */


public static void update(StockQuoteServiceStub stub){
try{
UpdateDocument reqDoc =
UpdateDocument.Factory.newInstance();
UpdateDocument.Update req = reqDoc.addNewUpdate();
req.setSymbol ("ABC");
req.setPrice (42.32);

stub.update(reqDoc);
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

/* two way call/receive */


public static void getPrice(StockQuoteServiceStub stub){
try{
GetPriceDocument reqDoc =
GetPriceDocument.Factory.newInstance();
GetPriceDocument.GetPrice req = reqDoc.addNewGetPrice();
req.setSymbol("ABC");

GetPriceResponseDocument res =
stub.getPrice(reqDoc);

System.err.println(res.getGetPriceResponse().getReturn());
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
}

50
This class creates a client stub using the XML Beans data bindings you created. Then it calls
the getPrice and the update operations on the Web service. The getPrice method operation
creates the GetPriceDocument, its inner GetPrice classes and sets the symbol to ABC. It then
sends the request and retrieves a GetPriceResponseDocument and displays the current price.
The update method creates an UpdateDocument, updates and sets the symbol to ABC and
price to 42.32, displaying 'done' when complete.
Now build and run the the project by typing ant run.client in the
Axis2_HOME/samples/quickstartxmlbeans directory.
You should get the following as output:
42
done

Generating a Client using JiBX


To build a client using JiBX, execute the following steps.
Generate the client stub by typing the following at a console in the
Axis2_HOME/samples/quickstartjibx directory.
%AXIS2_HOME%/bin/wsdl2java -uri resources/META-INF/StockQuoteService.wsdl -p
samples.quickstart.clients -d jibx -s -uw -o build/client
Else, simply type "ant generate.client".
Next take a look at quickstartjibx/src/samples/quickstart/clients/JiBXClient.java, shown
below in Code Listing 12.
Code Listing 12: The JiBXClient class

package samples.quickstart.clients;

import samples.quickstart.service.jibx.StockQuoteServiceStub;

public class JiBXClient{


public static void main(java.lang.String args[]){
try{
StockQuoteServiceStub stub =
new StockQuoteServiceStub
("http://localhost:8080/axis2/services/StockQuoteService
");

getPrice(stub);
update(stub);

} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

51
/* fire and forget */
public static void update(StockQuoteServiceStub stub){
try{
stub.update("ABC", new Double(42.35));
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

/* two way call/receive */


public static void getPrice(StockQuoteServiceStub stub){
try{
System.err.println(stub.getPrice("ABC"));
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}

This class uses the created JiBX client stub to access the getPrice and the update operations
on the Web service. The getPrice method sends a request for the stock "ABC" and displays the
current price. The update method setsnex the price for stock "ABC" to 42.35.
Now build and run the client by typing "ant run.client" at a console in the
Axis2_HOME/samples/quickstartjibx directory.
You should get the following as output:
42
done
For more information on using JiBX with Axis2, see the JiBX code generation integration
details.

Summary
Axis2 is a slick and robust way to get web services up and running in no time. This guide
presented five methods of creating a service deployable on Axis2, and four methods of creating
a client to communicate with the services. You now have the flexibility to create Web services
using a variety of different technologies.

For Further Study


Apache Axis2:
● http://ws.apache.org/axis2/
Axis2 Architecture:
● http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html
Introduction to Apache Axis2:
● http://www.redhat.com/magazine/021jul06/features/apache_axis2/
Working With Apache Axis2:
● http://www.wso2.net/articles/axis2/java/2006/09/13/working-with-axis2

52
Apache Axis2 User's Guide
This guide provides a starting place for users who are new to Apache Axis2. It also covers
some advanced topics, such as how to use Axis2 to create and deploy Web services as well as
how to use WSDL to generate both clients and services.
For experienced users of Apache Axis2, we recommend the Advanced User's Guide.

Content
• Introducing Axis2
• What is Axis2?
• What's under the hood?
• How Axis2 handles SOAP messages
• Axis2 Distributions
• The Axis2 Standard Binary Distribution
• Axis2.war Directory Hierarchy
• Axis2 Documents Distribution
• Axis2 and Clients
• Installing and Testing Client Code
• Introduction to Services
• Message Exchange Patterns
• Creating Clients
• Choosing a Client Generation Method
• Generating Clients
• Axis Data Binding (ADB)
• Building Services
• Getting Comfortable with Available Options
• Creating a Service from Scratch
• Deploying Plain Old Java Objects
• Deploying and Running an Axis2 Service Created from WSDL
• Samples
• For Further Study

Introducing Axis2
This section introduces Axis2 and its structure, including an explanation of various
directories/files included in the latest Axis2 download.

What is Axis2?
The Apache Axis2 project is a Java-based implementation of both the client and server sides
of the Web services equation. Designed to take advantage of the lessons learned from Apache
Axis 1.0, Apache Axis2 provides a complete object model and a modular architecture that
makes it easy to add functionality and support for new Web services-related specifications and

53
recommendations.
Axis2 enables you to easily perform the following tasks:
• Send SOAP messages
• Receive and process SOAP messages
• Create a Web service out of a plain Java class
• Create implementation classes for both the server and client using WSDL
• Easily retrieve the WSDL for a service
• Send and receive SOAP messages with attachments
• Create or utilize a REST-based Web service
• Create or utilize services that take advantage of the WS-Security, WS-
ReliableMessaging, WS-Addressing, WS-Coordination, and WS-Atomic Transaction
recommendations
• Use Axis2's modular structure to easily add support for new recommendations as
they emerge
Many more features exist as well, but this user guide concentrates on showing you how to
accomplish the first five tasks on this list.

What's Under the Hood?


To understand Axis2 and what it does, you must have a good idea of the life cycle of a Web
services message. Typically, it looks something like this:

The sending application creates the original SOAP message, an XML message that consists
of headers and a body. (For more information on SOAP, see "Introduction to Services".) If the
system requires the use of WS* recommendations such as WS-Addressing or WS-Security, the
message may undergo additional processing before it leaves the sender. Once the message is
ready, it is sent via a particular transport such as HTTP, JMS, and so on.
The message works its way over to the receiver, which takes in the message via the
transport listener. (In other words, if the application doesn't have an HTTP listener running, it's
not going to receive any HTTP messages.) Again, if the message is part of a system that
requires the use of WS-Security or other recommendations, it may need additional processing
for the purpose of checking credentials or decrypting sensitive information. Finally, a
dispatcher determines the specific application (or other component, such as a Java method) for
which the message was intended, and sends it to that component. That component is part of
an overall application designed to work with the data being sent back and forth.

How Axis2 Handles SOAP Messages


Axis2 can handle processing for both the sender and the receiver in a transaction. From the
Axis2 perspective, the structure looks like this:

54
On each end, you have an application designed to deal with the (sent or received)
messages. In the middle, you have Axis2, or rather, you can have Axis2. The value of Web
services is that the sender and receiver (each of which can be either the server or the client)
don't even have to be on the same platform, much less running the same application.
Assuming that Axis2 is running on both sides, the process looks like this:
• The sender creates the SOAP message.
• Axis "handlers" perform any necessary actions on that message such as encryption
of WS-Security related messages.
• The transport sender sends the message.
• On the receiving end, the transport listener detects the message.
• The transport listener passes the message on to any handlers on the receiving side.
• Once the message has been processed in the "pre-dispatch" phase, it is handed off
to the dispatchers, which pass it on to the appropriate application.
In Axis2, these actions are broken down into "phases", with several pre-defined phases,
such as the "pre-dispatch", "dispatch," and "message processing", being built into Axis2. Each
phase is a collection of "handlers". Axis2 enables you to control what handlers go into which
phases, and the order in which the handlers are executed within the phases. You can also add
your own phases and handlers.
Handlers come from "modules" that can be plugged into a running Axis2 system. These
modules, such as Rampart, which provides an implementation of WS-Security, and Sandesha,
which provides an implementation of WS-ReliableMessaging, are the main extensibility
mechanisms in Axis2.

Axis2 Distributions
Axis2 is released in several distributions. Which one you need depends on what you'll be
doing with it.

The Axis2 Standard Binary Distribution


If you're developing services and applications, you'll need the Axis2 Standard Binary
Distribution. The distribution includes all the necessary *.jar files, as well as a variety of scripts
that ease development. It has the following structure.
Code Listing 1: Axis2 Standard Binary Distribution

55
bin
axis2.bat
axis2.sh
axis2server.bat
axis2server.sh
java2wsdl.bat
java2wsdl.sh
wsdl2java.bat
wsdl2java.sh
setenv.sh
lib
activation-1.1.jar
...
XmlSchema.jar
repository
modules
modules.list
addressing-1.1.mar
..
services
services.list
version.aar
..
samples
...
webapp
...
conf
axis2.xml

LICENSE.txt
README.txt
NOTICE.txt
INSTALL.txt
release-notes.html

The bin directory includes a number of useful scripts. They include axis2.bat (or axis2.sh),
which enables you to easily execute a Java command without having to manually add all the
Axis2 jar files to the classpath, java2wsdl.bat (and .sh) and wsdl2java.bat (and .sh), which
enable you to easily generate Java code from a WSDL file and vice versa, and axis2server.bat
(and sh), a simple Web server that enables you to build Axis2's capability to send and receive
messages into your own application.
As expected, the lib directory includes all the necessary .jar files. Services and modules are
added to the repository directory. Axis2 comes with a standard module implementing WS-
Addressing, and you can add any other necessary module such as Rampart to the
repository/modules directory.
conf directory includes the axis2.xml which is the global deployment descriptor.
Finally, the samples directory includes all the sample code distributed with Axis2. See the
list of samples and their descriptions.

axis2.war Distribution Directory Hierarchy


axis2.war is available in WAR (Web Archive) Distribution. The server side of Axis2 ships as a
J2EE application, and has the following structure shown in Code Listing 2.
Code Listing 2: Server Side of Axis2

56
axis2-web
META-INF
WEB-INF
classes
conf
axis2.xml
lib
activation.jar
...
xmlSchema.jar
modules
modules.list
addressing.mar
...
soapmonitor.mar
services
services.list
aservice.aar
...
version.aar
web.xml

Starting at the top, axis2-web is a collection of JSPs that make up the Axis2 administration
application, through which you can perform any needed actions such as adding services and
engaging and dis-engaging modules. The WEB-INF directory represents the actual Axis2
application, including all the *.jar files, any included modules, and even the deployed services
themselves.
The classes directory holds any class or property files that are needed by Axis2 itself, such
as log4j.properties. Any actual services to be handled by the system reside in the services
directory in the form of an axis archive, or *.aar file. This file contains any classes related to
the service, as well as the services.xml file, which controls any additional requirements, such
as the definition of message senders and message receivers.
The main file in all this is axis2.xml, which controls how the application deals with received
messages. It defines message receivers and transport receivers, as well as defining transport
senders and determining which modules are active. It also defines the order of phases, and the
handlers to be executed within each phase.
You can control all of this information through the use of the Web application, but if you
restart the Axis2 application, these changes are lost and the server goes back to the definitions
in the axis2.xml file.
Axis2 also provides a third distribution, the source distribution, which enables you to
generate this .war file yourself.

Axis2 Documentation Distribution Directory Hierarchy


The Documents distribution includes all Axis2 documentation including the xdcos and
javadocs. It has the following structure:
Code Listing 3: Axis2 Documents Distribution

57
docs
javadocs
xdocs

LICENSE.txt
README.txt
release-notes.html

The javadocs directory includes all the standard API documentation for the Axis2 API, with
other documentation (like this document) in the xdocs directory.

Axis2 and Clients


Now that explains how Axis2 behaves as part of a Web application. What about a standalone
client that is not part of a J2EE application? In that case, a sender can use the Axis2 default
properties, in other words, no special handlers, and so on. But you also have the option to tell
the client to load its own copy of the axis2.xml file and behave accordingly.

Installing and Testing Client Code


The best way to make sure that your system is running Apache Axis2 is to install and test
both a service and a client. The process involves the following steps:
The Short Story:
1. Install Apache Axis2 in a suitable container, such as Apache Tomcat, by copying the
axis2.war file to the webapps directory.
2. Install the service into the Axis2 application by copying the *.aar file into the Axis2
services directory.
3. Install the client on the system on which you want to run it, and make sure all the
Axis2 libraries are on the CLASSPATH.
4. Run the client.
The Long Story:
Start by installing a suitable container, such as Apache Tomcat. Any J2EE server will do. To
install Apache Axis2 on the server, download the Axis2 WAR distribution from
http://ws.apache.org/axis2/download.cgi and place the axis2.war file in the server's webapps
directory. The server will then expand the distribution into its proper structure, as seen in the
earlier section.
Apache Axis2 services come bundled as *.aar files, which contain all the pieces necessary to
define the service, such as the necessary classes and libraries and the services.xml file that
defines the service's behavior. You can install the service using the Web administration
application, but to make things simple for now, copy the *.aar file into the Axis2 services
directory. For example, to install the MyService service distributed as one of the Axis2
samples, copy the file <AXIS2_HOME>/samples/userguide/build/MyService.aar file, which is
built using the ant command, from <AXIS2_HOME>/samples/userguide, to the directory
<J2EE_HOME>/webapps/axis2/WEB-INF/services.
Your client can come in any number of forms, from a collection of files to a single *.jar file.
The important thing is to ensure that all the appropriate classes are on the classpath. In
addition to the classes that pertain to the actual client, you must also add the Axis2 .jar files
into the CLASSPATH. Normally you will do this by downloading and unpacking the Axis2
Standard Distribution and adding the *.jar files in the lib directory to your CLASSPATH, or you
also have the option of running your client using the axis2.bat (or axis2.sh) script, which takes
care of it for you. For example, you can run a client with the command:

58
axis2 org.apache.axis2.axis2userguide.Client.

Introduction to Services
The term "Web services" can apply to a number of different ways of sending information
back and forth. However, this guide focuses on the sending and receiving of SOAP messages.
SOAP messages are XML documents that consist of an "envelope" containing a "payload" (see
Code Listing 4).
Code Listing 4: Example SOAP Message

<?xml version='1.0' ?>


<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/03/addressing">
<env:Header>

<wsa:MessageID>
http://ws.apache.org/9C21DE32-DB42-1228-C42E-66CB101421AD
</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://example.com/projects/clientApp</wsa:Address>
</wsa:ReplyTo>

<wsa:To>http://example.com/axis2/publishingService</wsa:To>

<wsa:Action>http://example.com/axis2/addDocument</wsa:Action>

</env:Header>
<env:Body>

<addDocument>
<docTitle>What I Did On My Summer Vacation</doctitle>
<docSubtitle>Children's Essays from Accross the World</docSubtitle>
<docLocation>contentRepos/summerVac.doc</docLocation>
</addDocument>

</env:Body>
</env:Envelope>

This XML document consists of the outer element or the SOAP Envelope, and its contents.
The SOAP Envelope is in the SOAP namespace, http://www.w3.org/2003/05/soap-envelope,
prefixed as env: and contains up to two children. This envelope is a standard format that
pertains to every single SOAP message sent and received by any SOAP Web service.
The contents of the Envelope consists of two parts; the first being the SOAP headers-the
contents of the env:Header element. These headers, such as the WS-Addressing elements
shown here, provide additional information about the message and how it should be handled.
A SOAP message may carry headers relating to several aspects of the message, or it may
carry no headers at all. These headers are typically processed by the message handlers.
The second and arguably the most important part of the message is the payload, which
consists of the contents of the env:Body element. This is the actual message intended for the
receiver, and it is the information that the main application will ultimately process.

Message Exchange Patterns


Although all SOAP messages carry the same structure, the ways in which they are used can
be combined into a number of different "message exchange patterns", or MEPs. The two major

59
message exchange patterns are:
• In-Out: in this MEP, the client sends a SOAP message to the server, which processes
the message and sends a response back. This is probably the most commonly used
MEP, and is useful for tasks such as searching for information or submitting information
in situations in where acknowledgment is important.
• In-Only: In this MEP, the client sends a message to the server without expecting a
response. You may use this MEP for activities such as pinging a server to wake it up,
reporting logging information for which you do not need an acknowledgment and so on.
Within these two MEPs, you also have several variables to consider:
• Blocking versus non-blocking: When the client sends a message, the application may
wait to receive a response before moving on, or it may simply send a message and
move on by specifying a callback action to be completed when the response is received.
• Number of parameters: Ultimately, a message sent from a client to server is intended
to execute a particular action. That action may not require any parameters, or it may
require one or more parameters. These parameters must be encoded as part of the
payload of the message.
Taking all these options into consideration, you can create virtually any MEP. For example,
you can create an Out-Only system by reversing roles for the In-Only MEP. Apache Axis2 also
includes support for less prominent MEPs, such as Robust-In-Only.

Creating Clients
When it comes to creating a Web service client, you can do it manually (see Building
Services), but in most cases you have a Web Service Description Language (WSDL) definition
that describes the messages clients should send and expect to receive. Axis2 provides several
ways to use this definition to automatically generate a client.

Choosing a Client Generation Method


Axis2 gives you several options when it comes to mapping WSDL to objects when
generating clients. Three of these options are Axis2 DataBinding Framework, XMLBeans, and
JiBX databinding. All of these methods involve using databinding to create Java objects out of
the XML structures used by the service, and each has its pros and cons. You can also generate
XML in-out stubs that are not based on databinding.
Axis2 Databinding Framework (ADB): ADB is probably the simplest method of generating an
Axis2 client. In most cases, all of the pertinent classes are created as inner classes of a main
stub class. ADB is very easy to use, but it does have limitations. It is not meant to be a full
schema binding application, and has difficulty with structures such as XML Schema element
extensions and restrictions.
XMLBeans: Unlike ADB, XMLBeans is a fully functional schema compiler, so it doesn't carry
the same limitations as ADB. It is, however, a bit more complicated to use than ADB. It
generates a huge number of files, and the programming model, while being certainly usable, is
not as straightforward as ADB.
JiBX: JiBX is a complete databinding framework that actually provides not only WSDL-to-
Java conversion, as covered in this document, but also Java-to-XML conversion. In some ways,
JiBX provides the best of both worlds. JiBX is extremely flexible, enabling you to choose the
classes that represent your entities, but it can be complicated to set up. On the other hand,
once it is set up, actually using the generated code is as easy as using ADB.
In the end, for simple structures, ADB will likely be enough for you. If, on the other hand
you need more power or flexibility, whether you choose XMLBeans or JiBX depends on how
much power or flexibility you need and your tolerance for complexity.

60
Generating Clients
The process for generating and using a client varies slightly depending on the method of
generation you choose. In all three cases in this document, clients are generated from the
same WSDL file (see Code Listing 5).
Note that the document defines four operations, DoInOnly, NoParameters,
TwoWayOneParameterEcho, and MultipleParametersAddItem. Each of the clients will include
methods for calling each of these operations.
(You can get more information on WSDL at http://www.w3.org/2002/ws/desc/ .)

Axis Data Binding (ADB)


To create a client using ADB, execute the following steps:
The short story:
1. href="http://ws.apache.org/axis2/download/1_2/download.cgi#std-bin" Download
and unpack the Apache Axis2 Standard Distribution, if you have not done it already.
2. Create the client stub with the following command:
%AXIS2_HOME%\bin\WSDL2Java -uri Axis2UserGuide.wsdl -p
org.apache.axis2.axis2userguide -d adb -s
3. Create the client (for example, Client.java), a Java application that uses the
generated stub, and save it in the org/apache/axis2/axis2userguide directory.
4. Build the client by typing: ant jar.client.
5. Assuming you have a corresponding service, run the client by adding the generated
Axis2UserGuideService-test-client.jar file located in build/lib to the classpath and type:
java org.apache.axis2.axis2userguide.Client
The long story:
If you have not done it already, download and unpack the Apache Axis2 Standard
Distribution. The Axis2 WAR Distribution does not include the necessary utilities for generating
code, such as WSDL2Java.
In the ADB method of generating clients, all the functionalities of the services are contained
in a single class called a stub. The stub contains inner classes corresponding to all the
necessary objects defined in the WSDL file, such as, in the case of this WSDL,
DoInOnlyRequestMessage. Once you have the stub, you will be able to create a client by
simply referring to these classes and their methods. To generate the client, issue the following
command in Code Listing 6.
Code Listing 6 - Generating the Client
%AXIS2_HOME%\bin\WSDL2Java -uri Axis2UserGuide.wsdl -p
org.apache.axis2.axis2userguide -d adb -s
This command analyzes the WSDL file and creates the stub in the package
org.apache.axis2.axis2userguide. The options specify that you want the ADB data binding
method (-d), and synchronous or blocking, methods (-s). In other words, when the client
makes an In-Out call to the service, it will wait for a response before continuing.
Once you run this command, you will see two new items in the directory. The first is the
build.xml file, which contains the instructions for Ant to compile the generated classes. The
second is the src directory, which contains the actual Axis2UserGuideServiceStub.java file. If
you open this file, you will see a collection of inner classes for each of the items in the WSDL
file. You'll also see a number of calls to the Axis2 client API, including those that use AXIOM to
build and analyze the incoming and outgoing messages.
Now you need a client to make use of this code. To create a client, create a new class and

61
save it as Client.java in the org/apache/axis2/axis2userguide directory. It should contain the
following code in Code Listing 7.
Note that using the service is simply a matter of creating and populating the appropriate
type of request using the names defined in the WSDL file, and then using the stub to actually
send the request to the appropriate method. For example, to call the DoInOnly operation, you
create a DoInOnlyRequest, use its setMessageString() method to set the contents of its
messageString element, and pass it as an argument to stub.DoInOnly().
To build the client, type: ant jar.client
This action creates two new directories, build and test. The test directory will be empty, but
the build directory contains two versions of the client. The first version, in the lib directory, is a
.jar file that contains the client class and the stub. The second, in the classes directory, is just
raw classes.
Make sure all the jar files in the Axis2 lib directory are in the classpath.
If you have a service corresponding to this client you can run the client by adding the jar file
to your classpath and typing: java org.apache.axis2.axis2userguide.Client
(If you don't have such a service,, refer to the Building services document.)
You should see the response in the console window of your servlet container. It should look
something like this:

ADB is not your only option for generating Web service clients. Other options include
XmlBeans, JiBX, JAXME and JAXBRI.

Building Services
Now that you know how to use Axis2 to generate clients from WSDL, this section digs a little
deeper showing you how to create services, and also how to create services and clients "from
scratch", so to speak.

Getting Comfortable with the Available Options


Axis2 provides a number of ways to create a service, such as:
• Create a service and build it from scratch. In this case, you build your service class
to specifically access AXIOM OMElement objects, then create the services.xml file and

62
package it for deployment.
• Deploy Plain Old Java Objects (POJOs) as a service.
• Generate the service from WSDL. Just as you can generate clients with WSDL, you
can also generate the skeleton of a service.
Let's look at these three options.

Creating a Service from Scratch


Creating a service from scratch is not the most convenient way to do it, but it does give you
the most control. The process involves several steps.
The short story:
1. Create the service class with each operation that is represented by a method that
takes an org.apache.axiom.om.OMElement object as its argument. (An OMElement is
how the AXIs2 Object Model (AXIOM) represents an XML element.)
2. Create the service descriptor, services.xml, which defines the class to be used by the
service and the appropriate message receivers.
3. Create the .aar file, with the classes in their proper locations based on the package
and the services.xml file in the META-INF directory.
4. Deploy the .aar file by using the Web Administration application or by copying it to
the Axis2 services directory.
The long story:
Start by creating the service class, a plain Java class that uses classes from the Axis2
libraries (see Code Listing 8).
Code Listing 8-Creating the Service Class

63
package org.apache.axis2.axis2userguide;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

public class SampleService {

public OMElement sayHello(OMElement element)


throws XMLStreamException {
element.build();
element.detach();

String rootName = element.getLocalName();


System.out.println("Reading "+rootName+" element");

OMElement childElement = element.getFirstElement();


String personToGreet = childElement.getText();

OMFactory fac = OMAbstractFactory.getOMFactory();


OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("sayHelloResponse",
omNs);
OMElement value = fac.createOMElement("greeting", omNs);
value.addChild(fac.createOMText(value, "Hello,
"+personToGreet));
method.addChild(value);

return method;
}

private void ping(){ }


}

Make sure to include Axis2 libraries in your class path when compiling the source.
Axis2 uses AXIOM, or the AXIs Object Model, a DOM (Document Object Model) -like
structure that is based on the StAX API ( Streaming API for XML). Methods that act as services
must take an OMElement as their argument, which represents the payload of the incoming
SOAP message. (An OMElement is just AXIOM's way of representing an XML element, like a
DOM Element object.) In this case, you're extracting the contents of the first child of the
payload element, adding text to it, and using it as content for the return OMElement. Unless
this is an "in only" service, these methods must return an OMElement, because that becomes
the payload of the return SOAP message.
To turn this class into a service, create the service description file, services.xml, as in Code
Listing 9.
Code Listing 9 - Create the Service Description

64
<service name="UserGuideSampleService">
<description>
This is a sample service created in the Axis2 User's Guide
</description>

<parameter name="ServiceClass"
locked="false">org.apache.axis2.axis2userguide.SampleService
</parameter>

<operation name="sayHello">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="ping">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
</service>

This document defines the service, called by the Web Administration Application, and the
class used to serve requests. For each operation, it defines the appropriate message receiver
class.
Create a new directory, META-INF, in the main directory for the class. (In this case, that's
the same directory that contains the org directory) and place the services.xml file in it.
Create the .aar file by typing: jar cvf SampleService.aar ./*
Deploy the SampleService.aar file by using the Web Administration application or by copying
it to the Axis2 services directory.
Now you can create a client class that accesses the service directly (see Code Listing 10).
Code Listing 10 - Create a Client Class that Accesses the Service Directly

65
package org.apache.axis2.axis2userguide;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;

public class SampleClient {

private static EndpointReference targetEPR =


new EndpointReference(
"http://localhost:8080/axis2/services/UserGuideSampleServ
ice");

public static OMElement greetUserPayload(String personToGreet) {


OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("sayHello", omNs);
OMElement value = fac.createOMElement("personToGreet",
omNs);
value.addChild(fac.createOMText(value, personToGreet));
method.addChild(value);
return method;
}

public static void main(String[] args) {


try {
OMElement payload =
SampleClient.greetUserPayload("John");
Options options = new Options();
options.setTo(targetEPR);

options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

ServiceClient sender = new ServiceClient();


sender.setOptions(options);
OMElement result = sender.sendReceive(payload);

String response = result.getFirstElement().getText();


System.out.println(response);

} catch (Exception e) { //(XMLStreamException e) {


System.out.println(e.toString());
}
}
}

This class uses the same technique of sending and receiving OMElements, but it's also
important to note the use of the Options class. This class enables you to determine properties
such as the transport used for the return message (the transport used for the outgoing
message can be inferred from the URL of the destination) and the SOAP version to use. In
addition to providing setter and getter methods of specific properties that affect how the client
interacts with the service, the Options class enables you to create inheritance relationships

66
between Options objects. So if a property is not found in the current Options object used, the
client can check the parent Options object of the current Options object.
Compile and run the above SampleClient.java. Make sure to have all axis2 libraries in your
class path. If all has gone well, 'Hello, John' will be shown as the output in the console.

Deploying Plain Old Java Objects (POJOs)


One very easy way to create a Web service is simply to deploy the Java objects that
represent the service. Start with the class, shown in Code Listing 11.
Code Listing 11 - Creating the Class SampleService

package org.apache.axis2.axis2userguide;

public class SampleService {


public void doInOnly(){
return;
}
public String noParameters(){
return "Hello";
}
public String twoWayOneParameterEcho(String toEcho){
return toEcho;
}
public boolean multipleParametersAdd(float price, int itemId,
String description, String itemName){
//Code to handle the logic
return true;
}
}

Next, you'll need to tell Axis2 what class corresponds with what Web service calls. Do this
by creating a file called services.xml and adding the following shown in Code Listing 12.
Code Listing 12 - Creating services.xml

<service name="SampleService" scope="application">


<description>
Sample Service
</description>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
org.apache.axis2.axis2userguide.SampleService
</parameter>
</service>

This file makes the InOnly and InOut MEPs available to the service and tells Axis2 which
class to call; operations must match method names. In other words, Axis2 automatically sends
a call to the multipleParametersAdd operation to the
org.apache.axis2.axis2userguide.SampleService.multipleParametersAdd() method.

67
Now it's time to create the distribution. Arrange your files in the following directory
structure (see Code Listing 13).
Code Listing 13- Create the Directory Structure for the Distribution

- SampleService
- META-INF
- services.xml
- org
- apache
- axis2
- axis2userguide
- SampleService.class

Finally, deploy the service by copying the SampleService directory to the


webapps/axis2/WEB-INF/services directory on the servlet engine. You can check to make sure
that it's been properly deployed by checking http://<host>:<port>/axis2/services/listServices.

Deploying and Running an Axis2 Service Created from WSDL


If you have a WSDL file, you can easily create and deploy a service based on that
description. For example, to create a service based on the same WSDL file used in the clients
section of this document, you will follow the steps below.
The short story:
1. Download the Axis2 standard distribution, if you have not done so already.
2. Generate the skeleton using the WSDL2Java utility, as in:
java org.apache.axis2.wsdl.WSDL2Java -uri
file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p
org.apache.axis2.axis2userguide -d adb -s -wv 1.1 -ss -sd -ssi
3. Open the *Skeleton.java file and add the functionality of your service to the
generated methods.
4. Build a service using Ant by typing ant jar.server
5. Deploy the service by copying the build/lib/*.aar file to
<J2EE_HOME>/webapps/axis2/WEB-INF/services
6. Check http://<server>:<port>/axis2/services/listServices to make sure the service
has been properly deployed.
The long story:
As with generating clients, you will need the Axis2 Standard Distribution, because the Axis2
WAR Distribution does not include the WSDL2Java utility. Once you've got it downloaded and
unpacked, make sure that you set the AXIS2_HOME variable to point to the location in which
you've unpacked it.
Now you are ready to generate the actual service. To keep things neat, create a new
directory and change to it. The WSDL file is the same one referenced in Generating Clients and
includes four operations: NoParameters, TwoWayOneParameterEcho,
MultipleParametersAddItem, and DoInOnly. To generate the service, use the WSDL2Java utility,
as in Code Listing 14.

Code Listing 14 - Using the WSDL2Java Utility to Generate the


Service
Code Listing 14.1:

68
java org.apache.axis2.wsdl.WSDL2Java -uri
file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p
org.apache.axis2.axis2userguide -d adb -s -wv 1.2 -ss -sd
Note: Make sure all the .jar files in the Axis2 lib directory is set to the CLASSPATH before
you run the above code.
This statement tells the utility you want to create a service out of the operations in the file
Axis2UserGuide.wsdl, and that the Java classes generated should be in the
org.apache.axis2.axis2userguide package (-p). (You can view the appropriate directories
created.) It also indicates that you want to use the Axis2 DataBinding Framework, or ADB (-d),
to generate only synchronous or blocking code (-s), and to generate server-side code (-ss) as
opposed to a client, including the services.xml service descriptor file (-sd). It also specifies
version 1.2 for the WSDL file (-wv).
Code Listing 14.2:
You can also use the following script files to achieve the same. In this case you do not have
the set the CLASSPATH manually.
For Linux:
$AXIS2_HOME/bin/wsdl2java.sh -uri
file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl
-p org.apache.axis2.axis2userguide -o target_directory_name -d adb -s -wv 1.2
-ss -sd
For MS Windows:
%AXIS2_HOME%\bin\wsdl2java.bat -uri
file:\\\C:\apps\axis2\samples\zSample\Axis2UserGuide.wsdl
-p org.apache.axis2.axis2userguide -o target_directory_name -d adb -s -wv 1.2
-ss -sd
In both instances, at this point, you should see four new items in your chosen directory: the
build.xml file, which includes instructions for Ant, the src directory, which includes all the
generated classes and stubs, the resources directory, which includes a regenerated version of
the WSDL, and the services.xml file, which ultimately controls the service's behavior.
You can compile the service at this point, but it doesn't actually do anything yet. You can
solve that problem by opening the
src\org\apache\axis2\axis2userguide\Axis2UserGuideServiceSkeleton.java file and either
editing the code in bold -- make sure you manage parameter numbers -- or replacing all the
code with the following in Code Listing 15.

69
Code Listing 15 - Compiling the Service
/**
* Axis2UserGuideServiceSkeleton.java
* This file was auto-generated from WSDL
* by the Apache Axis2 version: SNAPSHOT Oct 15, 2006 (11:23:18
GMT+00:00)
*/
package org.apache.axis2.axis2userguide;
/**
* Axis2UserGuideServiceSkeleton java skeleton for the axisService
*/
public class Axis2UserGuideServiceSkeleton {

/**
* Auto generated method signature

* @param param7

*/
public org.apache.axis2.axis2userguide.NoParametersResponse
NoParameters
(org.apache.axis2.axis2userguide.NoParametersRequest param7)

{
System.out.println(param7);

NoParametersResponse res =
new NoParametersResponse();

return res;
}

/**
* Auto generated method signature

* @param param9

*/
public
org.apache.axis2.axis2userguide.TwoWayOneParameterEchoResponse
TwoWayOneParameterEcho
(
org.apache.axis2.axis2userguide.TwoWayOneParameterEchoRequest
param9
)

{
System.out.println(param9.getEchoString());

TwoWayOneParameterEchoResponse res =
new TwoWayOneParameterEchoResponse();

res.setEchoString(param9.getEchoString());

return res;
}

70
/**
* Auto generated method signature

* @param param11

*/
public void DoInOnly
(
org.apache.axis2.axis2userguide.DoInOnlyRequest param11
)

{
System.out.println(param11.getMessageString());
}

/**
* Auto generated method signature

* @param param12

*/
public
org.apache.axis2.axis2userguide.MultipleParametersAddItemResponse
MultipleParametersAddItem
(

org.apache.axis2.axis2userguide.MultipleParametersAddItemRequest
param12
)

{
System.out.println(param12.getPrice());
System.out.println(param12.getItemId());
System.out.println(param12.getDescription());
System.out.println(param12.getItemName());

MultipleParametersAddItemResponse res =
new MultipleParametersAddItemResponse();

res.setSuccessfulAdd(true);
res.setItemId(param12.getItemId());

return res;
}

As with generating clients, all these classes, such as MultipleParametersAddItemRequest


and TwoWayOneParameterEchoResponse, are generated by the utility, and can be found in the
same directory as the skeleton file. They include methods such as setSuccessfulAdd(), which
sets the value of the content of an element in the response, and getItemName(), which
retrieves the content of elements in the request.
Save the file and compile it by typing: ant jar.server
If all goes well, you should see the BUILD SUCCESSFUL message in your window, and the
Axis2UserGuideService.aar file in the newly created build/lib directory.

71
Now you need to deploy the service to the server. To do that, copy the
Axis2UserGuideService.aar file to the WEB-INF/services directory of the application server.
(You also have the option to use the administration tools. See the Web Administrator's Guide
for more information.)
To verify that the service has been properly deployed, check the list of services at
http://<host>:<port>/axis2/services/listServices.

Now you should be able to access the service using any of the clients built in the Generating
Clients document.

72
The Samples
The Apache Axis2 Standard Distribution provides a number of samples you can use as a
guide for implementing specific features and capabilities. These services are listed in this
section.

Clients (in AXIS2_HOME/samples/userguide/src/clients):


EchoBlockingClient.java: A basic example of the send/receive MEP.
EchoBlockingDualClient.java: Specifies that the return message should be sent over a
different channel than the request message.
EchoBlockingWsaBasedClient.java: Provides an example of using the capabilities of WS-
Addressing action mapping.
EchoNonBlockingClient.java: Demonstrates an asynchronous request using Callbacks.
EchoNonBlockingDualClient.java: Similar to the above, but uses a separate listener for
the response.
ClientForWebServiceWithModule.java: Simply makes a call to a service with engaged
modules.
ClientSideModuleEngagement.java: Demonstrates the use of modules on the client side,
in addition to the server side.
MailClient.java: Demonstrates the use of the Robust In-Only MEP.
PingClient.java: A simple "fire and forget" client.
RESTClient.java: Demonstrates the ability to request a REST response rather than a SOAP
response. Also demonstrates setting arbitrary properties on the Options object.
TCPClient.java: Provides an example of using the TCP transport rather than HTTP.

Services (in AXIS2_HOME/samples/userguide):


groovyService.aar: Demonstrates how to use Groovy classes in the processing of SOAP
messages.
MyService.aar: Provides simple "echo" and "ping" operations.
MyServiceWithModule.aar: Same as above, but demonstrates how to engage a module.
WsaMappingService.aar: Demonstrates the mapping of WS-Addressing actions.

Sample WSDL files (in AXIS2_HOME/samples):


Axis2SampleDocLit.wsdl: Demonstrates the use of the Document/Literal WSDL pattern,
rather than RPC.
perf.wsdl: Demonstrates the use of array values as input values.

Other samples

In AXIS2_HOME/samples Directory:
faulthandling: Demonstrates the use of SOAP faults and their definitions in WSDL enabling
exception processing in the client.
googleSpellcheck: Demonstrates both synchronous and non-synchronous use of the

73
Google Web Service in a GUI.
mtom: Demonstrates the use of MTOM and SOAP with Attachments to send binary files to a
service.
saopwithattachments: Demonstrates the capabilities and power of SOAP with Attachment
support and the Attachment API of Axis2.
pojo: Example of a POJO (Plain Old Java Object) Web service. It shows how to expose the
methods of a Java class as a Web service using Apache Aixs2.
servicelifecycle: Demonstrates the usage of a service life cycle and a bit of session
management. The main idea is to show where and how to use the service life cycle interface
and session related methods.
databinding: Demonstrates how to use WSDL2Java generated code with Castor.
version: A very simple service that simply outputs the Apache Axis2 version.
yahoorestearch: A complete example of the use of a REST service rather than a SOAP
service.

External:
FlickrClient : Demonstrates code generation capabilities for WSDL 2.0. The
FlickrService.wsdl describes services offered by flickr in terms of WSDL 2.0. It also
demonstrates how a restful service can be described using the HTTPBinding of wsdl 2.0.
Extract the WSO2 WSAS for Java nightly build distribution and you will find the sample at
WSAS_HOME/samples/FlickrClient or checkout sample from SVN:
http://wso2.org/repos/wso2/trunk/wsas/java/modules/samples/FlickrClient

For Further Study

Resources
Axis2 Architecture:
● http://ws.apache.org/axis2/1_2/Axis2ArchitectureGuide.html
XML processing with AXIOM:
● http://ws.apache.org/commons/axiom/OMTutorial.html
RESTful Web Services:
● http://ws.apache.org/axis2/1_2/rest-ws.html
TCP Transport:
● http://ws.apache.org/axis2/1_2/tcp-transport.html
Mail Transport:
● http://ws.apache.org/axis2/1_2/mail-transport.html
HTTP Transports:
● http://ws.apache.org/axis2/1_2/http-transport.html
MTOM with Axis2:
● http://ws.apache.org/axis2/1_2/mtom-guide.html
Securing SOAP Messages with Apache Rampart:
● http://ws.apache.org/axis2/modules/rampart/1_2/security-module.html

74
SOAPMonitor:
● http://ws.apache.org/axis2/1_2/soapmonitor-module.html
Apache Axis2 Advance User's Guide:
● http://ws.apache.org/axis2/1_2/adv-userguide.html

Apache Axis2 Advanced User's Guide


This guide will help you get started with Axis2, the next generation of Apache Axis! It gives
a detail description on how to write Web services and Web service clients using Axis2, how to
write custom modules, and how to use them with a Web service. Advanced Topics and Samples
that are shipped with the binary distribution of Axis2, are also discussed.

Introduction
This user guide is written based on Axis2 Standard Binary Distribution. The Standard Binary
Distribution can be directly downloaded or built using the Source Distribution. If you choose
the latter, then the Installation Guide will instruct you on how to build Axis2 Standard Binary
Distribution using the source.
Please note that Axis2 is an open-source effort. If you feel the code could use some new
features or fixes, please get involved and lend us a hand! The Axis developer community
welcomes your participation.
Let us know what you think! Send your feedback to "axis-user@ws.apache.org".
(Subscription details are available on the Axis2 site.) Kindly prefix the subject of the mail with
[Axis2].

Getting Started
The first two sections of the user guide explain how to write and deploy a new Web Service
using Axis2, and how to write a Web Service client using Axis2. The next section - Configuring
Axis2 - provides an introduction to important configuration options in Axis2. The final section -
Advanced Topics - provides references to other features
In this (first) section, we will learn how to write and deploy Web services using Axis2. All the
samples mentioned in this guide are located in the "samples/userguide/src" directory of
Axis2 standard binary distribution.
Please deploy axis2.war in your servlet container and ensure that it works fine. The
Installation Guide gives you step-by-step instructions on just how to build axis2.war and
deploy it in your servlet container.

Creating a New Web Service


If you are interested in how to write a Web Service client using Axis2, it is decribed under
Writing a Web Service Client. Axis2 provides two ways to create new Web Services, using code
generation and using XML based primary APIs. The following section explains how to start
from a WSDL, and create a new service with code generation. For the XML based primary API,
please refer to the section Writing Web Services Using Axis2's Primary APIs for more
information. However, if you are a new user, it is better to follow the code generation approach
first (given below)

Starting with WSDL, Creating and Deploying a Service


We start with a WSDL, however if you do not have a WSDL and need to create a WSDL from

75
a java class, please use the Java2WSDL tool and create a WSDL. As you might already know, a
WSDL description of a service provides a precise definition of a Web Service. Axis2 can process
the WSDL and generate java code that does most of the work for you. At the server side, we
call them Skeletons, and at the client side, Stubs.
This method of writing a Web service with Axis2 involves four steps:
1. Generate the skeleton code.
2. Add business logic.
3. Create a *.aar archive (Axis Archive) for the Web service.
4. Deploy the Web service.

Step1: Generate Skeleton Code


To generate the skeleton and required classes, you can use the WSDL2Java tool provided in
Axis2. This tool is located in the bin directory of the distribution and can be executed using the
provided scripts (.bat or .sh). The tool's parameter list can be found in the Axis2 Reference
Document.
The parameters for the wsdl2java tool in our example are as follows. Please note that we
use xmlbeans as the data binding framework, and generated code will be sent to the samples
directory. Other data binding tools you can use are adb (Axis data binding) and jaxme (JaxMe
data binding)
wsdl2java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -d xmlbeans
-o ../samples -p org.apache.axis2.userguide
This will generate the required classes in the "sample/src" directory, and the schema
classes in the "samples/resources/schemaorg_apache_xmlbeans" directory. Note that
these are not source files and should be available in the class path in order to compile the
generated classes.

Step 2: Implement Business Logic


Now you should fill the business logic in the skeleton class. You can find the skeleton class
-Axis2SampleDocLitServiceSkeleton.java- among the generated classes in the
"samples/src/org/apache/axis2/userguide directory. Let's fill the echoString(..)
method in the skeleton as shown below. Our sample WSDL-Axis2SampleDocLit.wsdl in
"samples/wsdl" directory has three operations: echoString, echoStringArray, echoStruct. To
see how the others will look when they are filled up, see Code Listing For
Axis2SampleDocLitService Service

public org.apache.axis2.userguide.xsd.EchoStringReturnDocument
echoString(org.apache.axis2.userguide.xsd.EchoStringParamDocument
param4) throws Exception {
//Use the factory to create the output document.
org.apache.axis2.userguide.xsd.EchoStringReturnDocument retDoc =
org.apache.axis2.userguide.xsd.EchoStringReturnDocument.Facto
ry.newInstance();
//send the string back.
retDoc.setEchoStringReturn(param4.getEchoStringParam());
return retDoc;

Step 3: Create Archive File


An Axis2 service must be bundled as a service archive. The next step is to package the

76
classes in an .aar (axis2 archive) and deploy it in Axis2. There is an ant file generated with the
code; it will generate the Axis2 service archive for you. However, if you do not want to use ant,
you can create an archive with the following steps :
1. Compile the generated code.
2. Copy "resources/schemaorg_apache_xmlbeans" xmlbeans classes to your class
folder.
3. Among the generated files, there will be a services.xml file, which is the deployment
descriptor for Axis2 service.[learn more about it]. Copy the resources/service.xml to
META-INF/services.xml
(To write your own service.xml file, see the sub section in Writing Web Services Using
Axis2's Primary APIs )
4. Create the archive using content of the class folder. Change the directory to the class
folder and run jar -cf <service-name>.aar to create the archive.
Once the archive is created, the content of the JAR should look like this.

Step 4: Deploy Web Service


The service can be deployed by simply dropping the ".aar" file into the "services" directory
in "/webapps/axis2/WEB-INF" of your servlet container. We recommend using Apache Tomcat
as the servlet container. Please Note that the services directory is available only after
axis2.war is exploded by Tomcat. However, the easiest way to do it is to start Tomcat
after axis2.war is copied to the webapps directory (if you have not already started).
Check the "Services" link on the Home page of Axis2 Web Application
(http://localhost:8080/axis2) and see whether the Axis2SampleDocLitService is displayed
under the deployed services.
We recommend using the exploded configuration to deploy Axis2 WAR in WebLogic and
WebSphere application servers to support the hotupdate/ hotdeployment features in Axis2.
See Application Server Specific Configuration Guide for details.
Note: Axis2 provides an easy way to deploy Web Services using the "Upload Service" tool in
the Axis2 Web Application's Administration module. (See the Web Administration Guide for
more information)

Writing a Web Service Client


Axis2 also provides a more complex, yet powerful XML based client API which is intended for
advanced users. Read Writing Web Service Clients Using Axis2's Primary APIs to learn more
about it. However, if you are a new user, we recommend using the code generation approach
presented below.

Generate Stubs
Let's see how we could generate java code (Stub) to handle the client side Web Service
invocation for you. This can be done by running the WSDL2Java tool using the following

77
arguments
wsdl2java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -d xmlbeans
-o ../samples/src -p org.apache.axis2.userguide
This will generate client side stubs and xmlbeans types for your types. The Stub class that
you need to use will be of the form <service-name>Stub. In our example, it will be called
"Axis2SampleDocLitServiceStub.java"
Axis2 clients can invoke Web Services both in a blocking and non-blocking manner. In a
blocking invocation, the client waits till the service performs its task without proceeding to the
next step. Normally, the client waits till the response to the particular request arrives. In a
non-blocking invocation, the client proceeds to the next step immediately, and the responses
(if any) are handled using a Callback mechanism. Please note that some explanations use the
terms Synchronous and Asynchronous to describe the similar invocation strategies.

Do a Blocking Invocation
The following code fragment shows the necessary code calling echoString operation of the
Axis2SampleDocLitService that we have already deployed. The code is extremely simple to
understand and the explanations are in the form of comments.

try {
org.apache.axis2.userguide.Axis2SampleDocLitServiceStub stub
= new org.apache.axis2.userguide.Axis2SampleDocLitServiceStub(null,
"http://localhost:8080/axis2/services/Axis2SampleDocLitService");
//Create the request document to be sent.
org.apache.axis2.userguide.xsd.EchoStringParamDocument reqDoc =
org.apache.axis2.userguide.xsd.EchoStringParamDocument.Factory.newIn
stance();
reqDoc.setEchoStringParam("Axis2 Echo");
//invokes the Web service.
org.apache.axis2.userguide.xsd.EchoStringReturnDocument resDoc =
stub.echoString(reqDoc);
System.out.println(resDoc.getEchoStringReturn());
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}

First argument of Axis2SampleDocLitPortTypeStub should be the Axis2 repository for the


client. Here we use null to make the stub use default configurations. However, you can make
Axis2 use your own repository by providing it here. You can find more information about this
from the Axis2 Configuration section. You can find code to invoke other operations from Code
Listing For Axis2SampleDocLitService Service

Do a Non-Blocking Invocation
The stubs also include a method that allows you to do a non-blocking innovation. For each
method in the Service, there will be a method start<method-name>. These methods accept
a callback object, which would be called when the response is received. Sample code that does
an asynchronous interaction is given below.

78
try {
org.apache.axis2.userguide.Axis2SampleDocLitServiceStub stub
= new
org.apache.axis2.userguide.Axis2SampleDocLitServiceStub(null,
"http://localhost:8080/axis2/services/Axis2SampleDocLitServ
ice");
//implementing the callback online
org.apache.axis2.userguide.Axis2SampleDocLitServiceCallbackH
andler callback =
new
org.apache.axis2.userguide.Axis2SampleDocLitServiceCallbackHandler() {
public void receiveResultechoString(
org.apache.axis2.userguide.xsd.EchoStringReturnDoc
ument resDoc) {
System.out.println(resDoc.getEchoStringReturn());
}
};
org.apache.axis2.userguide.xsd.EchoStringParamDocument reqDoc =
org.apache.axis2.userguide.xsd.EchoStringParamDocument.Factory
.newInstance();
reqDoc.setEchoStringParam("Axis2 Echo");
stub.startechoString(reqDoc, callback);
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}

Even though the above code does a non-blocking invocation at the client API, the transport
connection may still operate in a blocking fashion. For example, a single HTTP connection can
be used to create a Web Service request and to get the response when a blocking invocation
happens at the transport level. To perform a "true" non-blocking invocation in which two
separate transport connections are used for the request and the response, please add the
following code segment after creating the stub. It will force Axis2 to use two transport
connections for the request and the response while the client uses a Callback to process the
response.
stub._getServiceClient().engageModule(new QName("addressing"));
stub._getServiceClient().getOptions().setUseSeparateListener(true);
Once those options are set, Axis2 client does the following:
1. Starts a new Transport Listener(Server) at the client side.
2. Sets the address of the Transport Listener, as the ReplyTo WS-Addressing Header of
the request message
3. According to the WS-Addressing rules, the Server will process the request message
and send the response back to the ReplyTo address.
4. Client accepts the response, processes it and invokes the callback with the response
parameters.

Using Your Own Repository


You could use your own repository with Axis2 Client, code below shows how to do this.

79
String axis2Repo = ...
String axis2xml = ...
ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(axi
s2Repo, axis2xml);
Service1Stub stub1 = new Service1Stub(configContext,...);
//invoke Service1
Service2Stub stub2 = new Service2Stub(configContext,...);
//invoke Service2

Note by creating the ConfigurationContext outside and passing it to the stubs, you could
make number of stubs to use same repository, thus saving the configuration loading overhead
from each request.

Configuring Axis2

Axis2 Repository
Axis2 configuration is based on a repository and standard archive format. A repository is a
directory in the file system, and it should have the following:
1. axis2.xml, the Axis2 global deployment descriptor in conf/axis2.xml file
2. services directory, which will have the service archives
3. modules directory (optional), which will have the module archives
Both services and modules will be identified and deployed once their archives are copied to
the corresponding directories. At the server side, users should specify the repository folder at
the time of starting the Axis2 Server (e.g. HTTP or TCP). In Tomcat, webapps/axis2/WEB-INF
folder acts as the repository. At the client side, binary distribution can itself be a repository.
You can copy the conf directory which includes the axis2.xml file from the exploded axis2.war
and edit it to change the global configurations repository.

Global Configurations
The Global configuration can be changed by editing the axis2.xml file, refer to the Axis2
Configuration Guide for more information.

Add New Services


New services can be written either using WSDL based code generation as we did, or from
scratch as explained in Writing Web Services Using Axis2's Primary APIs. Read Creating a
Service from Scratch for more information. Also refer to Axis2 Configuration Guide for a
reference on services.xml file.

Engaging Modules
Each module(.mar file) provides extensions to Axis2. A module can be deployed by copying
it to the modules directory in the repository. Then it becomes available and can be engaged at
a global, service or operation scope. Once engaged, it becomes active (adds handlers to the
execution flow) at the respective scope. Please refer to Axis2 architecture guide for detailed
explanation. The following table explains the semantics of scope, and how to engage modules
in those scopes.

80
Scope Semantics How to Engage
By adding a <module ref="addressing"/> to the Axis2 xml
Add handlers in the
file or calling
module to all the
Global services. Addressing
stub._getServiceClient().engageModule(moduleName)
Handler can be only
engaged as global
at client side
Add handlers in the
By adding a <module ref="addressing"/> to a service.xml
Service module to a specific
service file in a service archive
Add handlers in the
By adding a <module ref="addressing"/> inside an
Operation module to a specific
operation operation tag of a service.xml file in a service archive
* If a handler is added to a service or an operation, it will be invoked for every request
received by that service or operation
Axis2 provides a number of built in Modules (such as addressing,Security, WS-Reliable
Messaging), and they can be engaged as shown above. Please refer to each module on how to
use and configure them. You can also create your own modules with Axis2. Also refer to Axis2
Configuration Guide for a reference on the module.xml file.

WS-Addressing Support
WS-Addressing support for Axis2 is implemented by the addressing module. To enable
addressing, you need to engage the addressing module in both server and client sides.
1. To enable addressing at the server side, you need to copy the addressing.mar file to
the modules directory of the server's axis2 repository. To engage the module, add a
<module ref="addressing"/> to axis2.xml. The Addressing module can be engaged
only at global level.
2. To enable addressing at the client side, you should add it to the repository and
provide the repository as an argument to the ServiceClient or generated stub or have it
in your classpath.
3. To engage the addressing module, you should either add <module
ref="addressing"/> to the axis2.xml file at the client side or call
stub._getServiceClient().engageModule(moduleName)

Advanced Topics

Transports
By default, Axis2 is configured to use HTTP as the transport. However, Axis2 supports HTTP,
SMTP, TCP and JMS transports. You can also write your own transports, and deploy them by
adding new transportReceiver or transportSender tags to axis2.xml. To learn how to configure
and use different transports, please refer to the following documents.
1. TCP Transport
2. Mail Transport
3. HTTP Transports
4. JMS Transports

81
Attachments
Axis2 provides attachment support using MTOM. Please refer to MTOM with Axis2 for more
information.

Security
Axis2 provides Security support using Apache Rampart. Please refer to Securing SOAP
Messages with Apache Rampart for more information.

REST Web Service


Please refer to RESTful Web Services for more information.

Pluggable Data Binding


Axis2 ships with Axis Data Binding(ADB) as the default data binding framework. However,
data binding frameworks are pluggable to Axis2, and therefore you can use other data binding
frameworks with Axis2. Please refer to the following documents for more information.

Axis2 Data Binding(ADB)


1. Axis2 Databinding Framework
2. ADB Integration With Axis2
3. Advanced Axis2 Databinding Framework Features
4. ADB Tweaking Guide

JiBX
JiBX Integration With Axis2

Other Topics
1. Axis2 Integration With The Spring Framework
2. Web Services Policy Support In Axis2
3. Axis2 Configuration Guide
4. Axis2 RPC Support
5. Migrating from Apache Axis 1.x to Axis 2
6. Writing your Own Axis2 Module
7. Using the SOAP Monitor
8. Writing Web Services Using Axis2's Primary APIs
9. Writing Web Service Clients Using Axis2's Primary APIs
10.Application Server Specific Configuration Guide

Axis2 Configuration Guide


In Axis2, there are three kinds of configuration files to configure the system. The first one is
to configure the whole system (global configuration), the second one is to configure a service

82
(service configuration), and the third one is to configure a module (module configuration). This
document explains the above configurations in detail.

Content
• Global Configuration (axis2.xml)
• Service Configuration (services.xml)
• Module Configuration (module.xml)

Global Configuration
• Writing axis2.xml
All the configurations that require starting Axis2 are obtained from axis2.xml. The way to
specify them is extremely simple and easy. The document is all about the proper way of
specifying the configurations in axis2.xml. There are six top level elements that can be seen in
the configuration file and can be listed as follows:
• Parameter
• Transport Receiver
• Transport Sender
• Phase Order
• Module References
• Listeners (Observers)

Parameter
In Axis2, a parameter is nothing but a name value pair. Each and every top level parameter
available in the axis2.xml (direct sub elements of the root element) will be transformed into
properties in AxisConfiguration. Therefore, the top level parameters in the configuration
document can be accessed via AxisConfiguration in the running system. The correct way of
defining a parameter is shown below:

<parameter name="name of the parameter" >parameter value </parameter>

Transport Receiver
Depending on the underlying transport on which Axis2 is going to run, you need to have
different transport receivers. The way you add them to the system is as follows:

<transportReceiver name="http"
class="org.apache.axis2.transport.http.SimpleHTTPServer">
<parameter name="port" >6060</parameter>
</transportReceiver>

The above elements show the way of defining transport receivers in axis2.xml. Here the
name attribute of the 'transportReceiver' element is the name of the transport receiver. It can
be HTTP, TCP, SMTP, CommonsHTTP etc,. When the system starts up or when you set the
transport at the client side, you can use these transport names to load the appropriate
transport. Class attribute is to specify actual java classes that implement required interfaces
for the transport. Any transport can have zero or more parameters, and if there are any, those

83
parameters can be accessed via the corresponding transport receiver.

Transport Sender
Just as the transport receivers, you can register transport senders in the system, and later
at run time, the senders can be used to send the messages. For example, consider Axis2
running under Apache Tomcat. Then Axis2 can use TCP transport senders to send messages
rather than HTTP. The method of specifying transport senders is as follows:

<transportSender name="http"
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL"
locked="xsd:false">HTTP/1.0</parameter>
</transportSender>

name: Name of the transport (you can have HTTP and HHTP1 as the transport name)
class: Implementation class of the corresponding transport. Just as the transport receivers,
transport senders can have zero or more parameters, and if there are any, then it can be
accessed via the corresponding transport sender.

Phase Order
Specifying the order of phases in the execution chain has to be done using the phase order
element. It will look as follows:

<phaseOrder type="InFlow">
<phase name="TransportIn"/>
.
</phaseOrder>

The most interesting thing is that you can add handlers here as well. If you want to add a
handler that should go into that phase, you can directly do that by adding a handler element
into it. In addition to that, there is no hard coding work for the handler chain anywhere in
Axis2 (at any Axis*). So all those configurations are also done in the phase order element. The
complete configurations will look as follows:

84
<phaseOrder type="InFlow">
<!-- <order
Globalphase="Dispatch"/>
phases -->
<phase
</handler>
name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="Transport"/>
</handler>
<order phase="Dispatch"/>
</handler>
</phase>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<!-- Global phases -->
<!-- After
<order
the Dispatch
phase="Transport"/>
phase module author or service author can
add any phase
</handler>
he wants -->
<phase
</phase>
name="OperationInPhase"/>
</phaseOrder>
<phase name="Security"/>
<phaseOrder
<phasetype="OutFlow">
name="PreDispatch"/>
<!--
<phaseuser
name="Dispatch"
can add his own phases to this area -->
class="org.apache.axis2.engine.DispatchPhase">
<phase name="OperationOutPhase"/>
<!--<handler
Global phases
name="AddressingBasedDispatcher"
-->
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<!-- these phases will run irrespective of the service -->
<phase name="MessageOut"/>
<order phase="Dispatch"/>
<phase
</handler>
name="PolicyDetermination"/>
</phaseOrder>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<phaseOrder type="InFaultFlow">
<phase name="PreDispatch"/>
<phase name="Dispatch"
class="org.apache.axis2.engine.DispatchPhase">
<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="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<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="Dispatch"/>
</handler>
</phase>
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
</phaseOrder>
<phaseOrder type="OutFaultFlow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutFaultPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>

85
type: the attribute represents the type of the flow. It can only be one of the following:
• InFlow
• OutFlow
• InFaultFlow
• OutFaultFlow
In addition to that, the only child element that is allowed inside "phaseOrder" is the "phase"
element which represents the available phases in the execution chain. The method of
specifying phases inside "phaseOrder" is as follows:
<phase name="Transport"/>
name: Name of the phase.
There are a number of things that one has to keep in mind when changing a phaseOrder:
For the phaseOrder types "InFlow" and "InFaultFlow"
• All the phases that are above the "Dispatch" phase, including the "Dispatch" phase,
are known as "Global phases" . You can add any number of new phases here and they
will be considered global.
• In these two phaseOrder types, the phases added after the "Dispatch" phase are
known as "Operation phases".
For the phaseOrder types "OutFlow" and "OutFaultFlow"
• All the phases that are below the "MessageOut" phase, including the "MessageOut"
phase, are known as "Global phases". You can add new phases according to your
requirement.
• The phases added before the "MessageOut" phase are known as "Operation phases".
Note : If you look closely at the default axis2.xml, you will be able to clearly identify it.

Module References
If you want to engage a module, system wide, you can do it by adding a top level module
element in axis2.xml. It should look as follows:
<module ref="addressing"/>
ref: the module name which is going to be engaged, system wide.

Listeners (Observers)
In Axis2, AxisConfiguration is observable so that you can register observers into that. They
will be automatically informed whenever a change occurs in AxisConfiguration. In the current
implementation, the observers are informed of the following events:
• Deploying a Service
• Removing a service
• Activate/Inactivate Service
• Module deploy
• Module remove
Registering Observers is very useful for additional features such as RSS feed generation,
which will provide service information to subscribers. The correct way of registering observers
should as follows:

86
<listener class="org.apache.axis2.ObserverIMPL">
<parameter name="RSS_URL" >http://127.0.0.1/rss</parameter>
</listener>

class: Represents an Implementation class of observer, and it should be noted that the
Implementation class should implement AxisObserver interface, and the class has to be
available in the classpath.

Service Configuration
• Writing services.xml
The description of services are specified using services.xml. Each service archive file needs
to have a services.xml in order to be a valid service and it should be available in the META-INF
directory of the archive file. A very simple services.xml is shown below:

<service name="name of the service" scope="name of the scope"


class="full qualifide name the service lifecycle class"
targetNamespace="target namespase for the service">
<description> The description of the service </description>

<transports>
<transport>HTTP</transport>
</transports>
<schema schemaNamespace="schema namespace"/>

<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>

<parameter name="ServiceClass"
locked="xsd:false">org.apache.axis2.sample.echo.EchoImpl</parameter>

<operation name="echoString" mep="operation MEP">


<actionMapping>Mapping to action</actionMapping>
<module ref=" a module name "/>
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

name: The service name will be the name of the archive file if the .aar file contains only
one service, or else the name of the service will be the name given by the name attribute.
scope: (Optional Attribute) The time period during which runtime information of the
deployed services will be available. Scope is of several types- "Application", "SOAPSession",
"TransportSession", "Request". The default value (if you don't enter any value) will be
"Request"
class: (Optional attribute) The full qualified name of the service lifecycle implementation
class. ServiceLifeCycle class is usefull when you want to do some tasks when the system starts
and when it shutdowns.
targetNamespace: (Optional Attribute) Target name space of the service. This value will
be used when generating the WSDL. If you do not specify this value, the value will be
calculated from the package name of the service impl class.

87
description: (Optional) If you want to display any description about the service via Axis2
web-admin module, then the description can be specified here.
transports : (Optional) The transports to which the service is going to be exposed. If the
transport element is not present, then the service will be exposed in all the transports available
in the system. The transport child element specifies the transport prefix (the name of the
transport specified in axis2.xml).
parameters: A services.xml can have any number of top level parameters and all the
specified parameters will be transformed into service properties in the corresponding
AxisService. There is a compulsory parameter in services.xml called ServiceClass that specifies
the Java class, which performs the above transformation. This class is loaded by the
MessageReceiver.
operations : If the service impl class is Java, then all the public methods in that service will
be exposed. If the user wants to override it, he has to add the "operation" tag and override it.
In a non-Java scenario or if you do not have a service class, then all the operations the user
wants to expose by the service has to be indicated in the services.xml. It is specified as
follows:

<operation name="echoString">
<module ref=" a module name "/>
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>

The only compulsory attribute here is "name", which represents the operation name that is
going to be exposed. Any operation can contain module references as well as any number of
parameters. The most interesting thing is that you can register custom message receivers per
operation. Then the registered message receiver will be the message receiver for the
corresponding operation. If you do not specify the message receiver, then the default message
receiver will perform the operation.

Module Configuration
• Writing module.xml
The description of the module is specified using the module.xml. Each module archive file
needs to have a module.xml in order to be a valid module, and it should be available in the
META-INF directory of the archive file.
A very simple module.xml is shown below:

88
<module class="org.apache.module.Module1Impl">
<InFlow>
.
.
</InFlow>
<OutFlow>
.
.
</OutFlow>
<OutFaultFlow>
.
.
</OutFaultFlow>
<InFaultFlow>
.
.
</InFaultFlow>
<operation name="creatSeq" mep="MEP_URI_IN_OUT">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
<parameter name="para1" locked="xsd:true">10</parameter>
</operation>
</module>

class: (Optional attribute) Indicates the module implementation class. A module may or
may not contain a module implementation class since the module can also be a collection of
handlers. If a module contains an implementation class that implements the
org.apache.axis2.modules.Module interface at deployment, its init(); method will be called.
parameter: A module can contain any number of parameters and all the listed parameters
in the module.xml will be transformed into the corresponding AxisModule of the module.
flow: Defining of handlers in a module has to be done inside flows. There are four types of
flows as listed below.
You can add any number of handlers into a flow, and those handlers will be available in the
corresponding chains at runtime, when they are engaged.
• InFlow
• OutFlow
• InFaultFlow
• OutFaultFlow
operations: If a module wants to add an operation when it is engaged into a service, it can
be done by adding an operation tag in module.xml. The method of specifying the operation is
the same as operation in services.xml.
handler: The Handler element consists of compulsory and optional attributes. The method
of defining a handler will look as follows:

<handler name="handler1" class="handlerClass ">


<order phase="userphase1" />
</handler>

Compulsory Attributes:
name: Name of the handler.

89
class: Handler implementation class.
phase: Name of the phase that the handler should remain, in the execution chain.

Optional Attributes :
phaseLast: Indicates that the handler is the last handler of the phase.
phaseFirst: Indicate that the handler is the first handler of the phase.
before : Indicates that the current handler should be invoked before the handler specified
by the before handler.
after: Indicates that the current handler should be invoked after the handler specified by
the after handler.

Apache Axis2 Web Administrator's Guide


This document gives you detailed information on the administration console of the Apache
Axis2 Web application. Apache Axis2 Administration is all about configuring Apache Axis2 at
run time, where the configuration is transient.
Send your feedback to: axis-dev@ws.apache.org. (Subscription details are available on the
Axis2 site.) Kindly prefix every email subject with [Axis2].

Contents
• Introduction
• Login into Administration Site
• Administration Options
• Tools
• Upload Service
• System components
• Available services
• Available service groups
• Available modules
• Globally engaged modules
• Available phases
• Execution chains
• Global chains
• Operation specific chains
• Engage module
• Services
• Deactivate Service
• Activate Service
• Edit service parameters
• Contexts
• View Hierarchy

90
Introduction
The Apache Axis2 Web application has three main sections: 'Services' lists all the available
services deployed in this server, 'Validate' checks the system to see whether all the required
libraries are in place and views the system information, and 'Administration' is the Axis2 Web
Administration module which is the console for administering the Apache Axis2 installation.
The Axis2 Web Administration module provides a way to configure Axis2 dynamically. It's
important to note that this dynamic configuration will NOT be persistent, i.e., if the servlet
container is restarted, then all the dynamic configuration changes will be lost.

Log on to the Administration Site


Once Apache Axis2 is successfully installed, the Web application can be accessed (see
Installation Guide for instructions). From the Axis2 Web Application Home page you can go to
the Administration page by clicking the 'Administration' link. The Login page shown below will
appear requesting the user name and password. The default user name is 'admin' (without
quotes) and default password is 'axis2' (without quotes).

You can change the user name and password values by changing the following two
parameters in the axis2.xml as required.

<parameter name=”userName” locked=”false”>admin</parameter>


<parameter name=”password” locked=”false”>axis2</parameter>

If the log on is successful, you will see the screen below. This is where you can view the
configuration and the status of the running system and dynamically configure it.

91
Administration Options
Tools
• Upload Service
System components
• Available services
• Available service groups
• Available modules
• Globally engaged modules
• Available phases
Execution chains
• Global chains
• Operation specific chains
Engage module
• For all Services
• For a Service Group
• For a Service
• For an Operation
Services

92
• Deactivate service
• Activate service
• Edit service parameters
Contexts
• View Hierarchy
Apache Axis2 Web Application Home Page

Tools

Upload Services
You can upload packaged Apache Axis2 service archive files using this page. This can be
done in two simple steps:
• Browse to the location and select the axisService archive file you wish to upload
• Then click Upload

93
System components

Available Services
The functionality of the 'Available Services' option is almost the same as the functionality of
the 'Services' option on the Axis2 Web Application Home page, where it displays a list of
deployed services and their operations. As an additional feature, the 'Available Services' page
lists details of modules that are engaged to the deployed services and their operations on a
global, service or on an operation level.
Using the 'Disengage' link, you can disengage the corresponding module as long as the
module is not globally engaged (i.e., engaged to all the services and operations).
Click on a specific service and it will give you the WSDL file of that particular service.
Faulty services of this system will also be listed on this page. Click on a faulty service to
view a page that lists the exception stack trace of the exception, which caused the service to
be faulty.

94
Available Service Groups
Service group is a logical collection of related services, and the 'Available Service Groups'
link will list all the available service groups in the system.

95
Available Modules
To view the available modules in the 'modules' directory of the repository, click 'Available
Modules'. This will show you all the available modules in the system. Those modules can be
engaged dynamically.

Globally Engaged Modules


Click the 'Globally Engaged Modules' to view the globally engaged modules, if any. If a
module is engaged globally, then the handlers that belong to that module will be executed
irrespective of the service.

Available Phases
The 'Available Phases' link will display all the available phases. In Axis2, there are two levels
of phases:
• System predefined phases (not allowed to be changed)
• User defined phases
The main difference between these two levels is that system predefined phases will be
invoked irrespective of the services, while the user defined phases will be invoked when the
dispatcher finds the operation. Note that it is essential for module developers and service
writers to have a good understanding of phases and phase ordering.

96
Executions Chains

Global Chains
The 'Global Chains' link will display all the Global Execution Chains. The most interesting
feature of the Axis2 Web Administration Module is that it provides a very basic method of
viewing the global phase list and handlers inside the phases depending on both the phase and
handler orders. This kind of information is extremely useful in debugging the system, as there
is no other way to list out handlers in the global chains. If you engage a new module, the new
handlers will be added to the global chains and will be displayed on this page.

97
Operation Specific Chains
The 'Operation Specific Chains' link can be used to view the handlers corresponding to a
given service in the same order as it is in the real execution chain.

98
Select the service of whose service handlers you wish to view from the list, and click 'View'
to view the handlers. The page below shows the service handlers of the service version

99
Engaging Modules
The 'Engaging Modules' link allows you to engage modules either globally (to all services),
to a service group, to a service, or to an operation depending on the module implementation.
If the module was designed to engage the handlers globally, then the handlers in the module
can be included in any phase in the system. It can be either a system predefined phase or a
user defined phase.
On the other hand, if the module was implemented in such a way that it is going to be
deployed to a service or to an operation, then the module cannot be included in any of the
System Predefined Phases. Thus it can only be included in User Defined Phases.
Immediately after engaging the module, you can see the status of the engagement
indicating whether it is engaged properly or not.

Services

Deactivate Service
The 'Deactivate Service' link under the 'Services' list will lead to the page below. The
Deactivate service functionality provides a way to remove unnecessary services from the
running system, but the removal is transient--which means that if you restart the system, the
service will be active.
To deactivate a service, select a service from the list, select the 'Deactivate service' check
box, and then click 'Deactivate'.. The 'Clear' button will clear the 'Deactivate service' check
box.

100
Activate Service
The 'Activate Service' link under the 'Services' list will lead to the page below. The Activate
service functionality provides a way to activate services while the system is running, but the
activation is transient-- which means that if you restart the system, the service will be inactive.
To activate a service, select a service from the list, select the 'Activate Service' check box,
then click 'Activate'. The 'Clear' button will clear the 'Activate service' check box.

101
Edit Service Parameters
This functionality provides a way to change the parameters in a service or its operations.
These changes will be transient too, which means if you restart the system, the changes will
not be reflected.
The 'Edit Parameters' link under the 'Services' list (on the navigation bar) will link to the
page where you can select the services of which you want to edit the parameters. Once the
service is selected, click 'Edit Parameters'.. This will open the page shown below.

102
Contexts

View Hierarchy
By listing the current context hierarchy, the 'View Hierarchy' link provides a means to look
at the system state at run time. This will list out all the available service group contexts,
service contexts, operation contexts, etc.

Apache Axis2 Architecture Guide


This document gives an introduction to Axis2's modular architecture with explanations on
every module.
Send your feedback to: axis-dev@ws.apache.org. (Subscription details are available on the
Axis2 site.) Kindly prefix subject with [Axis2].

Contents
• The Big Picture
• Requirement of Axis2
• Axis2 Architecture
• Core Modules
• Other Modules

103
• Information Model
• XML Processing Model
• SOAP Processing Model
• Axis2 Default Processing Model
• Processing an Incoming SOAP Message
• Processing of the Outgoing Message
• Extending the SOAP Processing Model
• Extending the SOAP Processing Model with Handlers
• Extending the SOAP Processing Model with Modules
• Deployment
• The axis2.xml file
• Service Archive
• Module Archive
• Client API
• One Way Messaging Support
• Request Response Messaging Support
• Transports
• Code Generation
• Data Binding
• Integration with Code Generation Engine
• Serialization and De-Serialization

The Big Picture


A new architecture for Axis was introduced during the August 2004 Summit in Colombo, Sri
Lanka. This new architecture on which Axis2 is based is more flexible, efficient, and
configurable in comparison to Axis1.x architecture. Some well established concepts from Axis
1.x, like handlers etc., have been preserved in this new architecture.
Any architecture is a result of what that architecture should yield. The success of an
architecture should be evaluated based on the requirements expected to be met by that
architecture. Let us start our journey into Axis2 by looking at the requirements.

Requirement of Axis2
In SOAP terminology, a participant who is taking part in a Web service interaction is known
as a SOAP Node. Delivery of a single SOAP Message is defined based on two participants,
SOAP Sender and SOAP Receiver. Each SOAP message is sent by a SOAP Sender and received
by a SOAP Receiver. A single SOAP delivery is the most basic unit that builds the Web service
interaction.
Each SOAP Node may be written in specific programming language, may it be Java, C++,
.NET or Perl, but the Web services allow them to interoperate. This is possible because on the
wire each Web service interaction is done via SOAP, which is common to every SOAP Node.

104
Web service middleware handles the complexity in SOAP messaging and lets the users work
with the programming language they are accustomed to. Axis2 allows Java users to invoke
Web services using Java representations, and handles the SOAP messaging behind the curtain.
Axis2 handles SOAP processing along with numerous other tasks. This makes life of a Web
service developer a whole lot easier. Following are the identified requirements:
1. Provide a framework to process the SOAP messages. The framework should be
extensible and the users should be able to extend the SOAP processing per service or
per operation basis. Furthermore, it should be able to model different Message
Exchange Patterns (MEPs) using the processing framework.
2. Ability to deploy a Web service (with or without WSDL)
3. Provide a Client API that can be used to invoke Web services. This API should support
both the Synchronous and Asynchronous programming models.
4. Ability to configure Axis2 and its components through deployment.
5. Ability to send and receive SOAP messages with different transports.
Apart from the above functionalities, performance in terms of memory and speed is a major
consideration for Axis2. Axis2 Core Architecture is built on three specifications- WSDL, SOAP
and WS-Addressing. Other specifications like JAX-RPC, SAAJ and WS-Policy are layered on top
of the Core Architecture.

Axis2 Architecture
Axis2 architecture lays out some principals to preserve the uniformity. They are as follows:
• Axis2 architecture separates the logic and the states. Code that does the processing
does not have a state inside Axis2. This allows code to be executed freely by parallel
threads.
• All the information is kept in one information model, allowing the system to be
suspended and resumed.
Axis2 architecture is modular. Therefore, Axis2 Framework is built up of core modules that
collectively make up the core architecture of Axis2. Non-core/other modules are layered on top
of this core modules/architecture.

105
Core Modules:
• Information Model - Axis2 defines a model to handle information and all states are
kept in this model. The model consists of a hierarchy of information. The system
manages the life cycle of the objects in this hierarchy.
• XML processing Model - Handling the SOAP Message is the most important and most
complex task. The efficiency of this is the single most important factor that decides the
performance. It makes sense to delegate this task to a separate sub-project under the
Web services project, allowing that sub-project (AXIOM or AXis Object Model) to provide
a simple API for SOAP and XML info-set. It will hide the complexities of the efficient XML
processing within the implementation.
• SOAP Processing Model - This controls the execution of the processing. The model
defines different phases the execution would walk through, and the user can extend the
Processing Model at specific places.
• Deployment Model - The Axis2 deployment model allows the user to deploy services,
configure the transports, and extend the SOAP Processing model per system, service, or
operation basis.
• Client API - This provides a convenient API for users to communicate with Web
services using Axis2. There are a set of classes to interact with IN-OUT and IN-Only
style Message Exchange Patterns (MEPs), where they can be used to construct any
other MEP. (Please note that even if the client API has in-built support for the above
named MEPs, it does not by any means limit Axis2's flexibility to support custom MEPs.)
• Transports - Axis2 defines a transport framework that enables the user to use
multiple different transports. The transports fit into specific places in the SOAP
processing model. The implementation provides a few common transports and the user
can write or plug-in new ones if and when it is needed.

Other Modules:
• Code Generation - Axis2 provides a code generation tool that generates server side
and client side code along with descriptors and a test case. The generated code would
simplify the service deployment and the service invocation. This would increase the
usability of Axis2.
• Data Binding - The basic client API of Axis2 lets the users process SOAP at the
infoset level, where as data binding extends it to make it more convenient to the users
by encapsulating the infoset layer and providing a programming language specific
interface.

106
Information Model
Information Model has two main hierarchies-Contexts and Descriptions. This model is
described in UML notations below.

( A ----<> B says, B has 1 or more objects of A. A------>B says, the given relationship
holds between A and B.)
The two hierarchies are connected as shown in the above figure. The Description hierarchy
represents the static data. This data may be loaded from a configuration file that exists
throughout the lifetime of Axis2. For example, deployed Web services, operations, etc. On the
other hand, the context hierarchy holds more dynamic information about the things that have
more than one instance (e.g.Message Context).
These two hierarchies create a model that provides the ability to search for key value pairs.
When the values are searched at a given level, they are searched while moving up the
hierarchy until a match is found. In the resulting model, the lower levels override the values in
the upper levels. For example, when a value is looked up in the Message Context and is not
found, it would be looked up in the Operation Context, etc, up the hierarchy. The Search is first
done up the hierarchy, and if the starting point is a Context then it searches in the Description

107
hierarchy as well.
This allows the user to declare and override values, with the result being a very flexible
configuration model. The flexibility could be the Achilles heel for the system as the search is
expensive, specially for something that does not exist. Yet in the final analysis, developers
believe that the flexibility would serve better in this instant.
Context Description Configuration Description
Holds the Axis2's run time Holds all global
Configuration status. A deep copy of this Axis configurations. Transports,
Context would essentially make a Configuration global modules, parameters,
copy of Axis2. and services etc.

Holds information about a


particular usage of the
respective service group. The
life of a Service Group
Context starts when a user
Holds deployment time
Service Group starts interacting with a
AxisServiceGroup information about a particular
Context service that belong to this
service group.
service group. This can be
used to share information
between services (within the
same service group) in a
single interaction.

This context is available


throughout the usage of the
respective service. This can
be used to share information
Service Holds the Operations and the
between several MEPs of the AxisService
Context service level configurations
same service, within a single
interaction. The life cycle
depends on the scope of the
service.

Holds the information about


Operation the current MEP instance, Holds the operation level
AxisOperation
Context maintain the messages in the configurations
current MEP etc.

Holds all the information Holds message level static


Message
about the Message currently AxisMessage information like the schema
Context
being executed. of the particular message.

XML Processing Model


As we mentioned above, the XML processing model of Axis2 has become a separate sub-
project, called Apache Axiom, in the Apache Web services project. Please refer to the OM
Tutorial for more information.

108
SOAP Processing Model

The architecture identified two basic actions a SOAP processor should perform, sending and
receiving SOAP messages. The architecture provides two Pipes ('Flows'), to perform these two
basic actions. The Axis Engine or the driver of Axis2 defines two methods send() and receive()
to implement these two Pipes. The two pipes are named In Pipe and Out Pipe, and the
complex Message Exchange Patterns (MEPs) are constructed by combining these two pipes.
Extensibility of the SOAP processing model is provided through handlers. When a SOAP
message is being processed, the handlers that are registered will be executed. The handlers
can be registered in global, service, or operation scopes and the final handler chain is
calculated combining the handlers from all the scopes.
The handlers act as interceptors and they process parts of the SOAP message and provide
add-on services. Usually handlers work on the SOAP headers, yet they may access or change
the SOAP body as well.
When a SOAP message is being sent through the Client API, an Out Pipe would begin, the
Out Pipe invokes the handlers and end with a Transport Sender that sends the SOAP message
to the target endpoint. The SOAP message is received by a Transport Receiver at the target
endpoint, which reads the SOAP message and starts the In Pipe. The In Pipe consists of
handlers and ends with the Message Receiver, which consumes the SOAP message.
The processing explained above happens for each and every SOAP message that is
exchanged. After processing one message, Axis2 may decide to create other SOAP messages,
in which case more complex message patterns emerge. However, Axis2 always views the SOAP
message in terms of processing a single message. The combination of the messages are
layered on top of that basic framework.
The two pipes does not differentiate between the Server and the Client. The SOAP
Processing Model handles the complexity and provides two abstract pipes to the user. The
different areas or the stages of the pipes are given names, and according to Axis2 slang, they
are named 'phases'. A Handler always runs inside a phase, and the phase provides a
mechanism to specify the ordering of handlers. Both Pipes have built-in phases, and both
define the areas for 'User Phases' which can be defined by the user.

Axis2 Default Processing Model


Axis2 has some inbuilt handlers that run in inbuilt phases and they create the default
configuration for Axis2. We will be looking more in to how to extend the default processing
Model in the next section.

109
There are three special handlers defined in Axis2.
1. Dispatchers - Finds the service and the operation the SOAP message is directed to.
Dispatchers always run on the In-Pipe and inside the Dispatch phase. The in-built
dispatchers dispatch to a particular operation depending on various conditions like WS-
Addressing information, URI information, SOAP action information, etc. ( See more
information on Dispatching)
• Message Receiver - Consumes the SOAP message and hands it over to the
application. The message receiver is the last handler of the in-pipe
• Transport Sender - Sends the SOAP message to the SOAP endpoint the message is
destined to. Always runs as the last handler in the out-pipe

Processing an Incoming SOAP Message


An incoming SOAP message is always received by a Transport Receiver waiting for the SOAP
messages. Once the SOAP message arrives, the transport Headers are parsed and a Message
Context is created from the incoming SOAP message. This message context encapsulates all
the information, including the SOAP message itself, transport headers, etc., inside it. Then the
In Pipe is executed with the Message Context.
Let us see what happens at each phase of the execution. This process can happen in the
server or in the client.
1. Transport Phase - The handlers are in the phase that processes transport specific
information such as validating incoming messages by looking at various transport
headers, adding data into message context, etc.
2. Pre-Dispatch Phase- The main functionality of the handlers in this phase is to
populate message context to do the dispatching. For example, processing of addressing
headers of the SOAP message, if any, happens in this phase. Addressing handlers
extract information and put them in to the message context.
3. Dispatch Phase - The Dispatchers run in this phase and try to find the correct
service and operation this particular message is destined for.
The post condition of the dispatch phase (any phase can contain a post condition)
checks whether a service and an operation were found by the dispatchers. If not, the
execution will halt and give a "service not found' error.
4. User Defined Phases - Users can engage their custom handlers here.
5. Message Validation Phase - Once the user level execution has taken place, this
phase validates whether SOAP Message Processing has taken place correctly.
6. Message Processing Phase - The Business logic of the SOAP message is executed
here. A Message Receiver is registered with each Operation. This message receiver
(associated to the particular operation) will be executed as the last handler of this
phase.
There may be other handlers in any of these phases. Users may use custom handlers to
override the mechanics in each of these phases.

Processing of the Outgoing Message


TheOut Pipe is simpler because the service and the operation to dispatch are known by the
time the pipe is executed. The Out Pipe may be initiated by the
Message Receiver or the Client API implementation. Phases of the Out Pipe are described
below:
1. Message Initialize Phase - First phase of the Out Pipe. Serves as the placeholder
for the custom handlers.

110
2. User Phases - Executes handlers in user-defined phases.
3. Transports Phase - Executes any transport handlers taken from the associated
transport configuration. The last handler would be a transport sender which will send
the SOAP message to the target endpoint.

Extending the SOAP Processing Model


Above, we discussed the default processing model of Axis2. Now let us discuss the
extension mechanism for the SOAP processing model. After all, the whole effort of making this
SOAP engine/processing model was focused on making it extendable.
The idea behind introducing step-wise processing of the SOAP message in terms of handlers
and phases is to allow easier modification of the processing order. The notion of phases makes
it easier to place handlers in between other handlers. This enables modification of the default
processing behavior. The SOAP Processing Model can be extended with handlers or modules.

Extending the SOAP Processing Model with Handlers


The handlers in a module can specify the phase they need to be placed in. Furthermore,
they can specify their location inside a phase by providing phase rules. Phase rules will place a
handler,
1. as the first handler in a phase,
2. as the last handler in a phase,
3. before a given handler,
4. or after a given handler.

Extending the SOAP Processing Model with Modules


Axis2 defines an entity called a 'module' that can introduce handlers and Web service
operations. A Module in terms of Axis2 usually acts as a convenient packaging that includes:
• A set of handlers and
• An associated descriptor which includes the phase rules
Modules have the concept of being 'available' and 'engaged'. 'Availability' means the module
is present in the system, but has not been activated, i.e., the handlers included inside the
module have not been used in the processing mechanism. When a module is 'engaged' it
becomes active and the handlers get placed in the proper phases. The handlers will act in the
same way as explained in the previous section. Usually a module will be used to implement a
WS-* functionality such as WS-Addressing.
Apart from the extension mechanism based on the handlers, the WS-* specifications may
suggest a requirement for adding new operations. For example, once a user adds Reliable
Messaging capability to a service, the "Create Sequence" operation needs to be available to the
service endpoint. This can be implemented by letting the modules define the operations. Once
the module is engaged to a service, the necessary operations will be added to that service.
A service, operation, or the system may engage a module. Once the module is engaged, the
handlers and the operations defined in the module are added to the entity that engaged them.
Modules cannot be added (no hot deployment) while the Axis2 engine is running, but they
will be available once the system is restarted.

Deployment
The Deployment Model provides a concrete mechanism to configure Axis2. This model has

111
three entities that provide the configuration.

The axis2.xml file


This file holds the global configuration for the client and server, and provides the following
information:
1. The global parameters
2. Registered transport-in and transport-outs
3. User-defined phase names
4. Modules that are engaged globally (to all services)
5. Globally defined Message Receivers

Service Archive
The Service archive must have a META-INF/services.xml file and may contain the dependent
classes. The services.xml file has the following information.
1. Service level parameters
2. Modules that are engaged at service level
3. Service Specific Message Receivers
4. Operations inside the service

Module Archive
Module archive must have a META-INF/module.xml file and dependent classes. The
module.xml file has Module parameters and the Operations defined in the module.
When the system starts up, Axis2 prompts the deployment model to create an Axis
Configuration. The deployment model first finds the axis2.xml file and builds the global
configuration. Then it checks for the module archives and then for the service archives. After
that, the corresponding services and modules are added to the Axis Configuration. The system
will build contexts on top of the Axis Configuration. After this, Axis2 is ready to send or receive
SOAP messages. Hot deployment is only allowed for services.

Client API
There are three parameters that decide the nature of the Web service interaction.
1. Message Exchange Pattern (MEP)
2. The behavior of the transport, whether it's One-Way or Two-Way
3. Synchronous/ Asynchronous behavior of the Client API
Variations of the three parameters can result in an indefinite number of scenarios. Even
though Axis2 is built on a core that supports any messaging interaction, the developers were
compelled to provide in-built support for only two most widely used Message Exchange
Patterns (MEPs).
The two supported MEPs are One-Way and the In-Out (Request-Response) scenarios in the
Client API. The implementation is based on a class called ServiceClient and there are
extensions for each MEP that Axis2 Client API supports.

112
One Way Messaging Support
The One-Way support is provided by the fireAndForget method of ServiceClient. For one
way invocations, one can use HTTP , SMTP and TCP transports. In the case of the HTTP
transport, the return channel is not used, and the HTTP 202 OK is returned in the return
channel.

In-Out (Request Response) Messaging Support


The In-Out support is provided by the sendReceive() method in ServiceClient. This
provides a simpler interface for the user. The Client API has four ways to configure a given
message exchange
1. Blocking or Non-Blocking nature - this can be decided by using sendReceive() or
sendReceiveNonBlocking() methods
2. Sender transport - transport that sends the SOAP message
3. Listener transport - transport that receives the response
4. Use Separate Channel - determines whether the response is sent over a separate
transport connection or not. This can be false only when the sender and listener
transport is same and is a Two-Way transport.
Depending on the values of the above four parameters, Axis2 behaves differently.

Transports
Axis2 has two basic constructs for transports, namely: Transport Senders and Transport
Receivers. These are accessed via the AxisConfiguration.
The incoming transport is the transport via which the AxisEngine receives the message. The
outgoing transport is decided based on the addressing information (wsa:ReplyTo and
wsa:FaultTo). If addressing information is not available and if the server is trying to respond,
then the out going transport will be the outputstream of the incoming transport (if it is two-
way transport).
At the client side, the user is free to specify the transport to be used.
Transport Senders and Transport Receivers contain the following information.
1. Transport Sender for Out Configuration
2. Transport Listener for In Configuration
3. Parameters of the transport
Each and every transport out configuration defines a transport sender. The transport sender
sends the SOAP message depending on its configuration.
The transport receiver waits for the SOAP messages, and for each SOAP message that
arrives, it uses the In Pipe to process the SOAP message.
Axis2 presently supports the following transports:
1. HTTP - In HTTP transport, the transport listener is a servlet or
org.apache.axis2.transport.http.SimpleHTTPServer provided by Axis2. The transport
sender uses commons-httpclient to connect and send the SOAP message.
2. TCP - This is the simplest transport, but needs the WS - Addressing support to be
functional.
3. SMTP - This works off a single email account. Transport receiver is a thread that
checks for emails in fixed time intervals.

113
4. JMS

Code Generation
Although the basic objective of the code generation tools has not changed, the code
generation module of Axis2 has taken a different approach to generate code. Primarily, the
change is in the use of templates, namely XSL templates, which gives the code generator the
flexibility to generate code in multiple languages.
The basic approach is to set the code generator to generate an XML, and parse it with a
template to generate the code file. The following figure describes how this shows up in the
architecture of the tool.

The fact here is that it is the same information that is extracted from the WSDL no matter
what code is generated. First, an AxisService is populated from a WSDL. Then the code
generator extracts information from the AxisService and creates an XML, which is language
independent. This emitted XML is then parsed with the relevant XSL to generate code for the
relevant language. No matter what the output language is, the process is the same except for
the template that is being used.

114
Data Binding

Integration with the Code Generation Engine


Databinding for Axis2 is implemented in an interesting manner. Databinding has not been
included in the core deliberately, and hence the code generation allows different data binding
frameworks to be plugged in. This is done through an extension mechanism where the
codegen engine first calls the extensions and then executes the core emitter. The extensions
populate a map of QNames vs. class names that is passed to the code generator on which the
emitter operates on.
The following diagram shows the structure:

The following databinding extensions are available:


1. ADB - ADB (Axis Data Binding ) is a simple framework that allows simple schemas to
be compiled. It is lightweight and simple, works off StAX and fairly performant.
However, it does not support the complete set of schema constructs and is likely to
complain for certain schemas!
2. XMLBeans - XMLbeans claims that it supports the complete schema specification,
and it is preferred if full schema support is needed!
3. JAX-Me - JaxMe support has been added in a similar manner to XMLbeans and

115
serves as another option for the user
4. JibX - This is the most recent addition to the family of databinding extensions, and it
is also another option the users have for data binding.

Serialization and De-Serialization of Data bound classes


AXIOM is based on a StAX API (Streaming API for XML). Xml-beans supports StAX API. Data
binding in Axis2 is achieved through interfacing the AXIOM with the Xml-beans using the StAX
API, which is supported by both parties. At the time of code generation, there will be utility
methods generated inside the stub (or the message receiver) that can de-serialize from AXIOM
to data bound object and serialize from data bound object to AXIOM. For example, if the WSDL
has an operation called "echoString", once the code is generated, the following methods will be
generated inside the relevant classes.

public static
org.apache.axiom.om.OMElement
toOM(org.soapinterop.xsd.EchoStringParamDocument
param)// This method will handle the serialization.

public static org.apache.xmlbeans.XmlObject


fromOM(org.apache.axis2.om.OMElement param, java.lang.Class type) //This
method will handle the de-serialization.

POJO Web Services using Apache Axis2


Want a quick way to get a Web service up and running in no time? Then you should consider
creating a Plain Old Java Object (POJO) that you can deploy using Apache Axis2 on Apache
Tomcat. POJOs are fast to build and easy to maintain, which means you'll save a lot of time
building and debugging your code. This document shows you how to take a simple POJO, and
deploy it on Apache Tomcat as a Web service in the exploded directory format. You'll also learn
how to take a POJO based on the Spring Framework, and deploy that as an AAR packaged Web
service on Tomcat.

Content
• Introduction
• The POJO
• POJO Web service using Apache Axis2 and Tomcat
• Defining the Service: services.xml
• Building the POJO Web Service Using Ant
• Testing the POJO Web Service Using RPCServiceClient
• Limitations and Strengths of POJO
• Spring-based POJO Web Service
• Quick Introduction
• The Service Definition: services.xml
• Initializing the Spring application context: SpringInit
• Testing Using an RPCServiceClient
• Summary

116
• For Further Study

Introduction
The task of building a Web service can sometimes be overwhelming, but not with POJOs!
The old-school Plain Old Java Object is a simple and quick way to get most, if not all, of your
currently existing Java classes up on the Web as readily accessible Web services. This
document describes how to build a POJO-style Web service with Apache Axis2 and Tomcat. It is
organized as follows:
• The POJO: This is the Java class that you'll use throughout this document
• POJO deployment
• Test the POJO Web service using an RPC based client
• Limitations of straight POJO
• Spring-based POJO Web service and deployment
The code for the document can be found at Axis2_HOME/samples/pojoguide and
Axis2_HOME/samples/pojoguidespring once you extract the Axis2 Standard Distribution. (It is
better to get it now as it will help you to follow along.) Let's get started.

The POJO
The POJO you'll be using throughout this document is a Weather service POJO that consists
of two classes: WeatherService and Weather. Weather contains the Weather data:
Temperature, forecast, rain (will it rain?), and howMuchRain (See Code Listing 1).
Code Listing 1: The Weather POJO

package sample.pojo.data;

public class Weather{


float temperature;
String forecast;
boolean rain;
float howMuchRain;

public void setTemperature(float temp){


temperature = temp;
}

public float getTemperature(){


return temperature;
}

public void setForecast(String fore){


forecast = fore;
}

public String getForecast(){


return forecast;
}

public void setRain(boolean r){


rain = r;
}

117
public boolean getRain(){
return rain;
}

public void setHowMuchRain(float howMuch){


howMuchRain = howMuch;
}

public float getHowMuchRain(){


return howMuchRain;
}
}

And here's the WeatherService class, shown in Code Listing 2.


Code Listing 2: The WeatherService class

package sample.pojo.service;

import sample.pojo.data.Weather;

public class WeatherService{


Weather weather;

public void setWeather(Weather weather){


this.weather = weather;
}

public Weather getWeather(){


return this.weather;
}
}

Note that it's all just straight POJOs with field items and getter and setter methods for
each field. Next, you'll take a look at what you need to do to make it ready for deployment on
Apache Axis2 and Tomcat.

POJO Web Service Using Apache Axis2 and Tomcat


Got the POJOs? Great. This section will show you how to package them in the exploded
directory format for easy deployment. First you'll look at the services.xml file that defines the
Web service, and then you'll build the files using Apache Ant, and deploy the Web service on
Tomcat.

Defining the Service: services.xml


Before Axis2 can understand what is going on, you have to tell it to use the services.xml
file. Let's get right into it (see Code Listing 3).
Code Listing 3: The service definition file: services.xml

118
<service name="WeatherService" scope="application">
<description> Weather POJO Service </description>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
sample.pojo.service.WeatherService
</parameter>
</service>

The name of the service is specified as WeatherService and the scope of the service is
application. As you can see in the WeatherService POJO, there are two methods: IN-ONLY
method and IN-OUT method. Hence the messageReceiver elements are ordered within the
messageReceivers tag. Lastly, the ServiceClass parameter specifies the class of the Web
service, which is sample.pojo.service.WeatherService. When operations of your Web service
get called, the methods of the WeatherService class will be called. Next let usl take a look at
an easy method of building your application using Ant.

Building the POJO Web Service Using Apache Ant


Ant is a slick build tool. It helps reduce the time to build the applications, and several of the
Axis2 command-line tools create the build.xml files for you. (We will not be going into too
much detail on the build.xml file that you'll be using.)
Here are the main Ant tasks you'll be using:
• generate.service -- This Ant task builds the service relevant source, and copies the
files to build/WeatherService
• rpc.client -- This task builds the client relevant files, builds a JAR at build/lib/rpc-
client.jar, and then runs the client
Before you can build the source, you'll need to download the Axis2 1.2-bin and 1.2-war
distributions from here. Then modify the following line inside the build.xml file (in the
Axis2_HOME/samples/pojoguide directory in the extracted Axis2 1.2 Standard Binary (bin)
Distribution) :
● <property name="axis2.home" value="c:\apps\axis2" />
This modification contains the path to the root of the unzipped Axis2 1.2-bin download. With
that explanation, you'll now build the source by typing the following: ant
The following directory format should now exist at build/WeatherService:

- WeatherService
- META-INF
- services.xml
- sample
- pojo
- data
- Weather.class
- service
- WeatherService.class

119
Simple isn't it? An excellent way to dive into Web services development.
Now get a Tomcat distribution (I used v5.5), and start it up by running bin/startup.bat or
bin/startup.sh. Once it's running, deploy the Axis2 1.2-war by copying the axis2.war file to
Tomcat's webapps directory. Tomcat will proceed by deploying axis2 and un-archiving it into
the webapps directory. Now copy the WeatherService directory that was created at the time of
building our project to: <tomcat-home>/webapps/axis2/WEB-INF/services.
The service should deploy quickly. You willl test the Web service using the RPCServiceClient
in the next section.

Testing the POJO Web Service Using


RPCServiceClient
OK, so the Web service should be running on Tomcat. Now you'll build a simple
RPCServiceClient and test the POJO Web service. You'll first start out with the class constructs,
creating the RPCServiceClient and initializing the values of the Weather class within the Web
service (See Code Listing 4).
Code Listing 4: Setting the weather

package sample.pojo.rpcclient;

import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;

import sample.pojo.data.Weather;

public class WeatherRPCClient {

public static void main(String[] args1) throws AxisFault {

RPCServiceClient serviceClient = new RPCServiceClient();

Options options = serviceClient.getOptions();

EndpointReference targetEPR = new EndpointReference(


"http://localhost:8080/axis2/services/WeatherService");
options.setTo(targetEPR);

// Setting the weather


QName opSetWeather = new QName("http://service.pojo.sample/xsd",
"setWeather");

Weather w = new Weather();


w.setTemperature((float)39.3);
w.setForecast("Cloudy with showers");
w.setRain(true);
w.setHowMuchRain((float)4.5);
Object[] opSetWeatherArgs = new Object[] { w };

serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs);
...

120
The most interesting code to note is in bold font. Notice the targetEPR variable you create,
setting the endpoint reference to http://localhost:8080/axis2/services/WeatherService. This is
where you deployed it on Axis2. You can also verify this by asking Axis2 to list its services by
going to the following URL: http://localhost:8080/axis2/services/listServices.
Next the opSetWeather variable gets setup, pointing to the setWeather operation. Then the
Weather data is created and initialized. Lastly, you invoke the Web service, which initializes the
weather data (you'll verify this soon). Next you get back the weather data (see Code Listing
5).
Code Listing 5: Getting the weather data

...
serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs);

// Getting the weather


QName opGetWeather =
new QName("http://service.pojo.sample/xsd", "getWeather");

Object[] opGetWeatherArgs = new Object[] { };


Class[] returnTypes = new Class[] { Weather.class };

Object[] response = serviceClient.invokeBlocking(opGetWeather,


opGetWeatherArgs, returnTypes);

Weather result = (Weather) response[0];

if (result == null) {
System.out.println("Weather didn't initialize!");
return;
}
...

First you set the operation in opGetWeather to getWeather. Then you create an empty
argument list. Note that this time you expect something back from the Web service, and so
you create a list of return types. Then you invoke the Web service using a blocking call and
wait for the weather data to be returned to you, and you place it in the result variable. Lastly,
you make sure it isn't null and that it was successfully initialized by the previous call to
setWeather. Now display the data to verify it. (see Code Listing 6).
Code Listing 6: Displaying the data

...
return;
}

// Displaying the result


System.out.println("Temperature : " +
result.getTemperature());
System.out.println("Forecast : " +
result.getForecast());
System.out.println("Rain : " +
result.getRain());
System.out.println("How much rain (in inches) : " +
result.getHowMuchRain());

}
}

121
You should receive the data shown in Code Listing 7.
Code Listing 7: Output from running the client

rpc.client.run:
[java] Temperature : 39.3
[java] Forecast : Cloudy with showers
[java] Rain : true
[java] How much rain (in inches) : 4.5

Excellent! You have a working POJO Web service! Next you'll quickly morph this one into a
Spring based POJO.

Limitations and Strengths of POJO


We've covered the strengths of using POJO based Web services, but what about any
limitations? One main limitation of POJO based Web services is the lack of initialization support
(meaning that you have to go into your Web service and initialize the values before the Web
service is completely useful). However, you'll soon see how to overcome that limitation with a
Spring based POJO, which is covered next.

Spring-based POJO Web Service


Spring is a hot framework for J2EE and makes bean usage a breeze. You'll use it in this
section to create a Spring based POJO Web service. For this section, you'll need the spring.jar
from the latest 1.x Spring download.

Quick Introduction
If you take a look at the source code of this document in
Axis2_HOME/samples/pojoguidespring (to see how the Spring based POJO Web service is
coded), you can see that the Weather class didn't change at all and the WeatherService class
only got its name changed to WeatherSpringService.
You'll also notice an applicationContext.xml file, which we'll cover later. It is used to setup
the beans used in our Web service.
Now you might wonder what the SpringInit.java class is for. This service is necessary to
initialize the Spring Framework's application context.
The client is pretty much the same, except you won't use it to initialize the Weather data in
the Web service, since Spring does that for you using Inversion of Control (IoC), which is
covered next.

The Service Definition: services.xml


Since the core POJOs didn't change, you move straight to the services.xml file. It's a bit
longer this time because it instantiates two services in one file (see Code Listing 7).
Code Listing 7: Defining the services: services.xml

<serviceGroup>
<service name="SpringInit"
class="sample.spring.service.SpringInit">
<description> This web service initializes Spring. </description>

122
<parameter name="ServiceClass">
sample.spring.service.SpringInit
</parameter>
<parameter name="ServiceTCCL">composite</parameter>
<parameter name="load-on-startup">true</parameter>
<operation name="springInit">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>
<service name="WeatherSpringService">
<description>
Weather Spring POJO Axis2 AAR deployment
</description>
<parameter name="ServiceClass">
sample.spring.service.WeatherSpringService
</parameter>
<parameter name="ServiceObjectSupplier">
org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObject
Supplier
</parameter>
<parameter name="SpringBeanName">
weatherSpringService
</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
</service>
</serviceGroup>

You'll see a few familiar items in the above listing, and several changes. Once again, the
items in bold are most important. The ServiceTCCL property under the SpringInit service
makes sure that the Spring class loader is used for the Web service, allowing it to properly
instantiate the Spring application context. The load-on-startup variable is a must-have so that
the service loads up immediately on startup, creating the Spring application context. The
WeatherSpringService stays similar to the WeatherService previously with a couple of
additions: The ServiceObjectSupplier provides the service with the Spring application context,
making it "Spring Aware."
Lastly, the SpringBeanName points to the name of the bean associated with this Web
service, which is defined in the applicationContext.xml file (essentially the
WeatherSpringService). We'll cover the applicationContext.xml file next. The application
context, applicationContext.xml file tells the Spring Framework what beans are defined. For
this example, you'll define three of them (see Code Listing 8).
Code Listing 8: Defining the application context: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="applicationContext" class=
"org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder"
/>

123
<bean id="weatherSpringService"
class="sample.spring.service.WeatherSpringService">
<property name="weather" ref="weatherBean"/>
</bean>

<bean id="weatherBean" class="sample.spring.bean.Weather">


<property name="temperature" value="89.9"/>
<property name="forecast" value="Sunny"/>
<property name="rain" value="false"/>
<property name="howMuchRain" value="0.2"/>
</bean>
</beans>

The first one is Axis2's hook into Spring's application context (needed since AAR deployment
is quite different from regular WAR deployment). Next, you define the bean to which the
services.xml file points, which is the weatherSpringService bean that points to the
WeatherSpringService class. It has one field property that gets initialized by the Spring
Framework - weather. This will be set to the weatherBean. The weatherBean is an instantiation
of the Weather class that holds information on the weather. Spring will initialize it to the values
shown above, and set the Weather object in the WeatherSpringService class to the
weatherBean instantiation. Thus, when you deploy the Web service, you won't have to
instantiate the values because they'll already be set.
Next up is the SpringInit class.

Initializing the Spring Application Context: SpringInit


Without the Spring application context being initialized quickly, you'll run into problems. The
SpringInit class initializes the Spring application context on startup because it is a
ServiceLifeCycle class whose startUp method gets called upon loading the class (and because
its load-on-startup property is set in the services.xml file). The only code worth mentioning in
this class is shown in Code Listing 9.
Code Listing 9: SpringInit's startUp method

public void startUp(ConfigurationContext ignore,


AxisService service) {
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new
ClassPathXmlApplicationContext(new String[]
{"applicationContext.xml"},
false);
appCtx.setClassLoader(classLoader);
appCtx.refresh();
if (logger.isDebugEnabled()) {
logger.debug("\n\nstartUp() set spring classloader " +
"via axisService.getClassLoader() ... ");
}
}

Note that this method retrieves the Spring class loader, and creates an application context
with applicationContext.xml as the parameters. This new application context then gets the
Spring class loader as its class loader. The Spring Framework is now up and ready for our
WeatherSpringService.

124
Build and Deploy Using Apache Axis2 and Tomcat
Your POJO is now ready for primetime within the Spring Framework. Before you build, you'll
first need to make sure the axis2-spring-1.2.jar and spring.jar files are in the project's
Axis2_HOME/lib directory.
Note: The service will not deploy if you add the above .jar files to the service archive due to
class loding issues.
Now build the source and create an AAR file by typing: ant
It'll be created at target/WeatherSpringService.aar. Copy it to <tomcat-
home>/webapps/axis2/WEB-INF/services, and Axis2 should deploy it quickly.
Next, test the Web service to see whether Spring will really initialize the weather data for
you.

Testing Using an RPCServiceClient


It's as simple as it was for the other Web service, except this time type: ant rpc.client
Feel free to browse the code for this client in src/client/WeatherSpringRPCClient.java.
Essentially, this client does the same thing as the client testing the WeatherService. Except
that this one skips the "Setting the weather" task since the weather data should have already
been set by the Spring framework at startup.
Thus, you should get the following as output from the client:

run.client:
[javac] Compiling 1 source file to C:\axis2-
1.2\samples\pojoguidespring\build\cl
asses
[java] Temperature : 89.9
[java] Forecast : Sunny
[java] Rain : false
[java] How much rain (in inches) : 0.2

Which are exactly the values you set in the applicationContext.xml file!

Summary
Apache Axis2 is an excellent way to expose your POJOs as Web services. Spring adds
greater flexibility to your POJOs by adding beans support and initialization abilities, along with
all the other goodies provided by the Spring framework.

For Further Study


Apache Axis2:
● http://ws.apache.org/axis2/
Axis2 Architecture:
● http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html
Introduction to Apache Axis2:
● http://www.redhat.com/magazine/021jul06/features/apache_axis2/
Working With Apache Axis2:
● http://www.wso2.net/articles/axis2/java/2006/09/13/working-with-axis2

125
Apache Tomcat:
● http://tomcat.apache.org
Spring Framework:
● http://www.springframework.org/

Axis2 Integration with the Spring Framework


This document is a guide on how to use Axis2 with the Spring Framework

Content
• Introduction
• Configuring Axis2 to be Spring Aware
• Programming Model
• Simple Spring Config Example
• With a ServletContext
• Without a ServletContext
• Putting it All Together
• Spring Inside an AAR
• The Spring Inside an AAR Layout
• The Spring Inside an AAR init Class
• Known Issues Running Spring Inside the AAR

Introduction
Axis2 and Spring integration takes place when Spring supplies one of its pre-loaded beans
to the Axis2 Message Receiver defined in the AAR services.xml. Axis2 typically uses reflection
to instantiate the ServiceClass defined in the services.xml used by the Message Receiver.
Alternatively, you can define a ServiceObjectSupplier that will supply the Object.
This guide describes how to use two separate ServiceObjectSupplier classes that are a part
of the Axis2 standard distribution - one for use with a ServletContext, and one without. Once
configured, the Web service itself acts like any other Spring wired bean. These Spring beans
can be loaded any way desired as Axis2 has no configuration file dependencies from Spring.
Spring versions 1.2.6, 1.2.8 and 2.0 have been tested, but probably any version would work as
only the core functionality is required.
This guide assumes some basic knowledge of Axis2. See the User's Guide for more
information.

Configuring Axis2 to be Spring Aware

Programming Model
From an Axis2 standpoint, two hooks are needed to be placed into the AAR services.xml -
the ServiceObjectSupplier that hooks Axis2 and Spring together, and the name of the Spring
bean that Axis2 will use as the service. All Message Receivers are currently supported, as
would be any Message Receiver that extends
org.apache.axis2.receivers.AbstractMessageReceiver .

126
Simple Spring Config Example
For the purpose of this example, we'll configure Spring via a WAR file's web.xml. Let's add a
context-param and a listener:

<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener-
class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

Next we will show two examples of Spring's /WEB-INF/applicationContext.xml referenced in


the web.xml listener - one using a ServletContext, and one without.

With a ServletContext
This example (with a ServletContext) applicationContext.xml should be familiar to any
Spring user:

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- Axis2 Web Service, but to Spring, its just another bean that has
dependencies -->
<bean id="springAwareService" class="spring.SpringAwareService">
<property name="myBean" ref="myBean"/>
</bean>

<!-- just another bean / interface with a wired implementation, that's


injected by Spring
into the Web Service -->
<bean id="myBean" class="spring.MyBeanImpl">
<property name="val" value="Spring, emerge thyself" />
</bean>
</beans>

If the service is running in a Servlet Container, i.e., Axis2 will be able to get a hold of the
ServletContext, the services.xml for the example would be using
SpringServletContextObjectSupplier such as:

<service name="SpringAwareService">
<description>
simple spring example
</description>
<parameter name="ServiceObjectSupplier"
locked="false">org.apache.axis2.extensions.spring.receivers.SpringServle
tContextObjectSupplier</parameter>
<parameter name="SpringBeanName"
locked="false">springAwareService</parameter>

127
<operation name="getValue">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

While the above example uses RawXMLINOutMessageReceiver as its messageReceiver class,


all Message Receivers are currently supported, as would be any Message Receiver that extends
org.apache.axis2.receivers.AbstractMessageReceiver .

Without a ServletContext
In case Axis2 can't get a ServletContext, (i.e., uses a different transport or is running Axis2
inside the AAR etc,) you have the option of defining a bean that takes advantage of Spring's
internal abilities (ApplicationContextAware interface, specifically) to provide an Application
Context to Axis2, with a bean ref 'applicationContext' :

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- Configure spring to give a hook to axis2 without a ServletContext
-->
<bean id="applicationContext"
class="org.apache.axis2.extensions.spring.receivers.ApplicationConte
xtHolder" />

<!-- Axis2 Web Service, but to Spring, its just another bean that has
dependencies -->
<bean id="springAwareService"
class="spring.SpringAwareService">
<property name="myBean" ref="myBean" />
</bean>

<!-- just another bean with a wired implementation, that's injected by


Spring
into the Web Service -->
<bean id="myBean"
class="spring.MyBeanImpl">
<property name="val" value="Spring, emerge thyself" />
</bean>
</beans>

If the service is not running in a Servlet Container, i.e., Axis2 will not be able to get a hold
of ServletContext or you prefer not to, the services.xml for the example will be using
SpringAppContextAwareObjectSupplier such as:

<service name="SpringAwareService">
<description>
simple spring example
</description>
<parameter name="ServiceObjectSupplier"
locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppCon
textAwareObjectSupplier</parameter>

128
<parameter name="SpringBeanName"
locked="false">springAwareService</parameter>
<operation name="getValue">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

While the above example uses RawXMLINOutMessageReceiver as its messageReceiver class,


all Message Receivers are currently supported, as would be any Message Receiver that extends
org.apache.axis2.receivers.AbstractMessageReceiver .
In an environment without a ServletContext, one way you could load the
applicationContext.xml file is in a place that will be run once. Upon start-up, execute the
following:

import
org.springframework.context.support.ClassPathXmlApplicationContext;

public void createSpringAppCtx(ClassLoader cl)


throws Exception {

ClassPathXmlApplicationContext ctx = new


ClassPathXmlApplicationContext(new String[] {Constants.MY_PATH +
"spring/applicationContext.xml"}, false);
ctx.setClassLoader(cl);
ctx.refresh();
}

Putting It All Together


From here, it's just standard Axis2 coding. Only now the service has Spring wiring
capabilities. The implementation is the same whether using either
SpringServletContextObjectSupplier or SpringAppContextAwareObjectSupplier. The service is
as follows:

package spring;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;

public class SpringAwareService {

private MyBean myBean = null;

//spring 'injects' this implementation


public void setMyBean(MyBean myBean) {
this.myBean = myBean;
}

129
// The web service
public OMElement getValue(OMElement ignore) {
OMFactory factory=
OMAbstractFactory.getOMFactory();
OMNamespace payloadNs= factory.createOMNamespace(
"http://springExample.org/example1", "example1");
OMElement payload =
factory.createOMElement("string", payloadNs);
OMText response =
factory.createOMText(this.myBean.emerge());
payload.addChild(response);
return payload;
}
}

For those who are new to Spring, one of the ideas is that you program an Interface, as the
implementation is pluggable. This idea is referenced in the Spring config file above. Below is
the interface:
package spring;

/** Interface for Spring aware Bean */


public interface MyBean {
String emerge();
}

Here's the implementation:


/** Spring wired implementation */
public class MyBeanImpl implements MyBean {

String str = null;


// spring 'injects' this value
public void setVal(String s) {
str = s;
}
// web service gets this value
public String emerge() {
return str;
}
}

Lastly here's the client - not really necessary for the example, other than for completeness:

130
public class
package client;
TestClient {
private static EndpointReference targetEPR =
import java.io.StringWriter;
new EndpointReference(
import javax.xml.stream.XMLOutputFactory;
"http://localhost:8080/axis2/services/SpringAwareService"
);
import org.apache.axiom.om.OMAbstractFactory;
import
/**org.apache.axiom.om.OMElement;
import
* Simple
org.apache.axiom.om.OMFactory;
axis2 client.
import
* org.apache.axiom.om.OMNamespace;
import
* @param
org.apache.axis2.addressing.EndpointReference;
args Main
import
*/org.apache.axis2.client.Options;
import
public
org.apache.axis2.client.ServiceClient;
static void main(String[] args) {
try {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace omNs = factory.createOMNamespace(
"http://springExample.org/example1",
"example1");

OMElement method = factory.createOMElement("getValue",


omNs);
OMElement value = factory.createOMElement("Text", omNs);
value.addChild(factory.createOMText(value, "Some String "));
method.addChild(value);

ServiceClient serviceClient = new ServiceClient();

Options options = new Options();


serviceClient.setOptions(options);
options.setTo(targetEPR);

//Blocking invocation
OMElement result = serviceClient.sendReceive(method);

StringWriter writer = new StringWriter();


result.serialize(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();

System.out.println("Response: " + writer.toString());


} catch (Exception ex) {
ex.printStackTrace();
}
}
}

The examples above assume that both the spring framework .jar and the axis2-spring-*.jar
are under WEB-INF/lib. In such a case, the classes shown in this tutorial need to be placed in a
JAR under WEB-INF/lib. In this example the JAR layout is:

./mySpring.jar
./META-INF
./META-INF/MANIFEST.MF
./spring
./spring/MyBean.class
./spring/MyBeanImpl.class
./spring/SpringAwareService.class

Since all the user classes are in mySpring.jar in this example, the AAR merely contains the
services.xml file:

131
./springExample.aar
./META-INF
./META-INF/MANIFEST.MF
./META-INF/services.xml

To run this example, make sure you have the axis2-spring*.jar that comes from the axis2-
std-*-bin distro in the server side WEB-INF/lib, as well as the appropriate Spring jar - most will
use the full spring.jar, but the minimum requirements are spring-core, spring-beans, spring-
context, and spring-web. When running the client, you should see this output:

Response: <example1:string
xmlns:example1="http://springExample.org/example1"
xmlns:tns="http://ws.apache.org/axis2">Spring, emerge
thyself</example1:string>

Spring Inside an AAR


Axis2 users frequently want to run Spring inside the AAR. Here we show you how it is done.
There are four points to be aware of:
(A) You need to configure Spring to use the Axis2 Service Classloader. See the Known issues
running Spring inside the AAR area.
(B) It's up to you to load Spring, though we give an example below.
(C) For reasons such as classloader isolation, the SpringAppContextAwareObjectSupplier is
the best choice.
(D) The springframework .jar and axis2-spring-*.jar will be placed inside the AAR under the
lib directory. Please move the axis2-spring-*.jar from WEB-INF/lib to inside the AAR, as shown
below - it will not work otherwise.

The Spring inside an AAR layout

./springExample.aar
./META-INF
./META-INF/MANIFEST.MF
./META-INF/services.xml
./applicationContext.xml
./lib
./lib/axis2-spring-SNAPSHOT.jar
./lib/spring.jar
./spring
./spring/MyBean.class
./spring/MyBeanImpl.class
./spring/SpringAwareService.class
./spring/SpringInit.class

As explained in the Without a ServletContext section, the 'Spring inside an AAR' config
needs to hook Axis2 and Spring together via a Spring bean. Place the following in your Spring
config file:

<!-- Config spring to give a hook to axis2 without a ServletContext -->


<bean id="applicationContext"
class="org.apache.axis2.extensions.spring.receivers.ApplicationConte
xtHolder" />

132
The Spring inside an AAR init class
One way to initialize Spring inside the AAR is to use the
org.apache.axis2.engine.ServiceLifeCycle interface. Here we give an example:

package spring;

import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import
org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringInit implements ServiceLifeCycle {

/**
* This will be called during the deployement time of the service.
* irrespective
* of the service scope this method will be called
*/
public void startUp(ConfigurationContext ignore, AxisService
service) {

try {
System.out.println("Starting spring init");
ClassLoader classLoader = service.getClassLoader();
ClassPathXmlApplicationContext appCtx = new
ClassPathXmlApplicationContext(new String[]
{"applicationContext.xml"}, false);
appCtx.setClassLoader(classLoader);
appCtx.refresh();
System.out.println("spring loaded");
} catch (Exception ex) {
ex.printStackTrace();
}
}

/**
* This will be called during the system shut down time.
* irrespective
* of the service scope this method will be called
*/
public void shutDown(ConfigurationContext ctxIgnore, AxisService
ignore) {
}
}

Here's the services.xml that now includes SpringInit and the SpringAwareService shown
above. There is also the composite parameter which is needed when loading Spring in the AAR
- see the Known issues running Spring inside the AAR area.

<serviceGroup>
<!-- Invoke SpringInit on server startup and shutdown -->
<service name="SpringAwareService" class="spring.SpringInit">
<description>
simple spring example - inside the AAR
</description>

133
<!-- need the TCCL param when using spring inside the AAR -->
<parameter name="ServiceTCCL" locked="false">composite</parameter>
<parameter name="ServiceObjectSupplier"
locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppCon
textAwareObjectSupplier</parameter>
<parameter name="SpringBeanName"
locked="false">springAwareService</parameter>
<operation name="getValue">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>
</serviceGroup>

Known issues running Spring inside the AAR


By default, the Axis2 classloader strategy does not permit Spring to run inside the AAR. To
allow Spring to run inside the AAR, the 'composite' parameter is used in the services.xml as
shown in the example above. There was default behavior of 'composite' in the development
cycle in between 1.0 and 1.1, but it resulted in the JIRA issue AXIS2-1214 -problems with
getting an initContext.lookup() handle inside the AAR. Spring users typically have little desire
to use initContext.lookup(), as they get their Datasources via
org.springframework.jdbc.datasource.DriverManagerDataSource in an XML file or with
annotations. For EJB home references and the like, Spring provides JndiObjectFactoryBean.
While fully testing JndiObjectFactoryBean with EJB has not been done yet (if you do, please
send a message to the axis users list) Datasources via Spring inside the AAR have been tested.
Basically it works as typically done with Spring, though if you are passing Hibernate XML files
you need to put them in a place where Spring will find them. The most flexible way is as
follows, using logging in DEBUG mode to see where Spring will look in your jar / class
locations:

<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<value>classpath*:**/MyEntity.hbm.xml</value>
</property>
...
</bean>

Writing Your Own Axis2 Module


Axis2 provides extended support for modules (See the Architecture Guide for more details
about modules in Axis2). Let's create a custom module and deploy it to MyService, which we
created earlier.
Send your feedback or questions to: axis-dev@ws.apache.org. ( Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

Content List
• MyService with a Logging Module
• Step1 : LoggingModule Class
• Step2 : LogHandler

134
• Step3 : module.xml
• Step4: Modify the "axis2.xml"
• Step5 : Modify the "services.xml
• Step6 : Packaging
• Step7 : Deploy the Module in Axis2
The following steps show the actions that need to be performed to deploy a custom module
for a given Web service:
1. Create the Module Implementation
2. Create the Handlers
3. Create the module.xml
4. Modify the "axis2.xml" (if you need custom phases)
5. Modify the "services.xml" to engage modules at the deployment time.
6. Package in a ".mar" (Module Archive)
7. Deploy the module in Axis2

MyService with a Logging Module


Let's write a simple logging module for our sample located at the
"samples\userguide\src" directory of the binary distribution. This module contains one
handler that just logs the message that is passed through it. Axis2 uses ".mar" (Module
Archive) to deploy modules in Axis2. The following diagram shows the file structure inside
which needs to be there in the ".mar" archive. Let's create all these and see how it works.

Step1 : LoggingModule Class


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

public void init(ConfigurationContext configContext, AxisModule module)


throws AxisFault;//Initialize the module
public void shutdown(ConfigurationContext configurationContext) throws
AxisFault;//End of module processing
public void engageNotify(AxisDescription axisDescription) throws
AxisFault;
public String[] getPolicyNamespaces() throws AxisFault;
public void applyPolicy(Policy policy, AxisDescription axisDescription)
throws AxisFault ;
public boolean canSupportAssertion(Assertion assertion) ;

135
The first three methods can be used to control the module initialization and the termination,
and the next three methods are used to perform policy related operations. With the input
parameter AxisConfiguration, the user is provided with the complete configuration hierarchy.
This can be used to fine-tune the module behavior by the module writers. For a simple logging
service, we can keep these methods blank in our implementation class.

Step2 : LogHandler
A module in Axis2 can contain, one or more handlers that perform various SOAP header
processing at different phases. (See the Architecture Guide for more information on phases).
To write a handler one should implement org.apache.axis2.engine.Handler. But for
convenience, org.apache.axis2.handlers.AbstractHandler provides an abstract implementation
of the Handler interface.
For the logging module, we will write a handler with the following methods. "public void
invoke(MessageContext ctx);" is the method that is called by the Axis2 engine when the
control is passed to the handler. "public void revoke(MessageContext ctx);" is called when the
handlers are revoked by the Axis2 engine.

public class LogHandler extends AbstractHandler implements Handler {


private static final Log log = LogFactory.getLog(LogHandler.class);
private String name;

public String getName() {


return name;
}

public InvocationResponse invoke(MessageContext msgContext) throws


AxisFault {
log.info(msgContext.getEnvelope().toString());
return InvocationResponse.CONTINUE;
}

public void revoke(MessageContext msgContext) {


log.info(msgContext.getEnvelope().toString());
}

public void setName(String name) {


this.name = name;
}
}

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

<module name="logging" class="userguide.loggingmodule.LoggingModule ">


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

136
<outflow>
<handler name="OutFlowLogHandler"
class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</outflow>

<Outfaultflow>
<handler name="FaultOutFlowLogHandler"
class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</Outfaultflow>

<INfaultflow>
<handler name="FaultInFlowLogHandler"
class="userguide.loggingmodule.LogHandler">
<order phase="loggingPhase"/>
</handler>
</INfaultflow>
</module>

As you can see, there are four flows defined in the "module.xml"
1. inflow - Represents the handler chain that will run when a message is coming in.
2. outflow - Represents the handler chain that will run when the message is going out.
3. Outfaultflow - Represents the handler chain that will run when there is a fault, and
the fault is going out.
4. INfaultflow - Represents the handler chain that will run when there is a fault, and the
fault is coming in.
The following set of tags describe the name of the handler, handler class, and the phase in
which this handler is going to run. "InFlowLogHandler" is the name given for the particular
instance of this handler class. The value of the class attribute is the actual implementation
class for this handler. Since we are writing a logging handler, we can reuse the same handler in
all these phases. However, this may not be the same for all the modules. "<order
phase="loggingPhase" />" describes the phase in which this handler runs.

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

To learn more about Phase rules, check out the article Axis2 Execution Framework

Step 4: Modify the "axis2.xml"


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

137
<!-- 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 service author can add
any phase he wants -->
<phase name="OperationInPhase"/>
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="outflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutPhase"/>
<phase name="loggingPhase"/>
<!--system predefined phases-->
<!--these phases 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="OperationInFaultPhase"/>
<phase name="loggingPhase"/>
</phaseOrder>
<phaseOrder type="Outfaultflow">
<!-- user can add his own phases to this area -->
<phase name="OperationOutFaultPhase"/>
<phase name="loggingPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>

138
The text in green, the custom phase "loggingPhase" is placed in all the flows, hence that
phase will be called in all the message flows in the engine. Since our module is associated with
this phase, the LogHandler inside the module will now be executed in this phase.

Step5 : Modify the "services.xml"


Up to this point, we have created the required classes and configuration descriptions for the
logging module, and by changing the "axis2.xml" we created the required phases for the
logging module.
Next step is to "engage" (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 similar operations.
The code for this service can be found in the
"Axis2_HOME/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.

<service name="MyServiceWithModule">
<description>
This is a sample Web service with a logging module engaged.
</description>
<module ref="logging"/>
<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>

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 "<module ref="logging"/>" 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".

Step6 : Packaging
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. Else, you can find the
"logging.mar" that has already been created in the "Axis2_HOME/samples/userguide"
directory.

Step7 : Deploy the Module in Axis2


Deploying a module in Axis2 requires the user to create a directory with the name
"modules" in the "webapps/axis2/WEB-INF" directory of their servlet container, and then
copying the ".mar" file to that directory. So let's first create the "modules" directory and drop
the "logging.mar" into this directory.
Although the required changes to the "services.xml" is very little, we have created a separate

139
service archive (MyServiceWithModule.aar) for users to deploy the service..
Deploy this service using the same steps used in the 'Step 4: Deploy Web Service' sub
section in 'Writing a New Service using Codegeneration', and copy the "logging.mar" file to the
"modules" directory.
Then run 'ant run.client.servicewithmodule' from axis2home/samples/userguide
directory
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".
Note (on samples): All the samples mentioned in the user's guide are located at the
"samples\userguide\src" directory of the binary distribution.

ADB Data Binding


Axis2 Databinding Framework
This document aims to provide an architectural overview of the Axis2 Databinding
Framework (referred to as ADB from here onwards) and be a guide to anyone who wants to
use and modify ADB. The information is presented under the following topics.

Content
• Introduction
• Architectural Overview
• Code and Dependencies
• Invoking the ADB Code Generator
• As a Stand-alone Schema Compiler
• Through the API
• Generation Modes
• Deep into Generated Code
• An Example!
• Known Limitations
• Want to Learn More?

Introduction
The objective of the Axis2 Databinding framework is to provide a lightweight and simple
schema compiler/Java bean generator for Axis2. By no means is it intended to be a fully
functional schema compiler like XMLBeans. Note that ADB is written in a fashion that allows it
to be used as a stand-alone schema compiler and also to be extended to generate code for
other languages.

Architectural Overview
ADB is built on a modular architecture that allows it to utilize a pre-configured writer
depending on the configuration. The 'big block diagram' for the code generator architecture is

140
depicted below.
ADB utilizes the WS-Commons XmlSchema library for reading the Schema. The object
model for the schema comes in the form of an XmlSchema object. The schema compiler keeps
an instance of the writer (in the default case it's the JavaBeanWriter) which actually writes the
classes. The writers may use whatever technique they prefer, in the case of the
JavaBeanWriter, it uses an XSLT template. The SchemaCompiler also uses a typemapper object
that tells it what classnames to use for the QNames that it encounters. This type mapper is
also part of the configuration and the users can override the default type mapper by overriding
the property setting.

Code and Dependencies


As explained in the previous section, the schema compiler depends on the WS-Commons
XmlSchema library. The XSLT transformations are dependent on the JVM's DOM
implementation (either Crimson or Xerces) which means that the underlying JVM should be 1.4
or higher. Apart from that ADB has no dependencies on any other special jar files. The code for
the schema compiler is completely in the org.apache.axis2.schema.* package. This package
resides in the codegen module of the Axis2 source tree.
The following are the important classes and files of ADB:
1. SchemaCompiler - The work horse that really compiles the schema into classes.
2. BeanWriter - BeanWriters handle the the actual rendering of the classes.
BeanWriter is the interface that writers need to implement in order to be used by the
SchemaCompiler.
3. JavaBeanWriter - The default implementation of the BeanWriter interface.
4. TypeMap - represents the interface that the schema compiler uses to find class
names for a given QName.
5. JavaTypeMap - the default implementation of the TypeMap
6. ADBBeanTemplate.xsl - the XSLtemplate the JavaBeanWriter uses.
7. Schema-compile.properties - The property file for the schema compiler
The easiest way to obtain the ADB binaries is to run the maven build for the Axis2 adb-
codegen module. This will generate the axis2-adb-codegen-{$version}.jar inside the target
folder which is directly usable when the ADB schema compiler is required.
The runtime dependencies for the ADB generated classes is in the Axis2 adb module and the
kernal module. Hence to compile and work with the generated classes the axis2-adb-
{$version}.jar and axis2-kernal-{$version}.jar needs to be in the classpath in addition to
other dependencies such as StAX, Axiom, Commons-logging and javax.activation.

Invoking the ADB Code Generator

As a Standalone Schema Compiler


ADB comes with a XSD2Java code generator that allows the schemas to be compiled just by
giving the schema file reference. This main class is presently rather primitive and does not
provide much control over the code generation process. This is bound to improve in the near
future.
XSD2Java accepts the following parameters:
1. The Schema file name - This should be a complete file name pointing to the local file
system
2. The output folder name - This should be the name of a folder within the local file

141
system
Since the code generator presently has no validations built into it, the compiler is likely to
show various error messages if these parameters are not supplied properly.

Through the API


This is the only way to harness the full potential of the schema compiler. The current Axis2
integration of ADB happens through this API. The most important classes and methods of the
Schema compiler are as follows.
• SchemaCompiler - Constructor
The constructor of the schema compiler expects a CompilerOptions object. This
compilerOptions object is more of a holder for the parameters that are passed to the
SchemaCompiler. The only mandatory parameter in the CompilerOptions is the output
directory.
• SchemaCompiler - Compile(XMLSchema schema)
The compile method to call for a single schema. The expected object is a XMLSchema
which is part of the XmlSchema library.
• SchemaCompiler - Compile(List schemaList)
Similar to the previous method but accepts a list of schemas instead of one.
For a comprehensive code sample in invoking the schema compiler through the API, the
following classes would be helpful. One would also need an understanding of the generation
modes of the ADB schema compiler when using it through the API. Hence the following section
includes a brief description of the generation modes.
• org.apache.axis2.schema.XSD2Java
• org.apache.axis2.schema.ExtensionUtility

Generation Modes
ADB extension provides several generation modes for the data bound classes.
1. Integrated Mode
In this mode the classes are generated as inner classes of the stub, message receiver or
the interface. The ADB framework does not actually write the classes but instead
provides a map of DOM document objects that contains the model for the databinding
classes. The Axis2 codegen engine in turn parses these documents within its own XSLT
parser to create the necessary classes. Implementers are free to use these models
differently for their own particular needs.
Integrated mode is intended to be used by tool builders.
2. Wrapped Mode
In the wrapped mode, the ADB databinder generates one class that contains all the
databound classes. This is convenient when the number of classes need to be limited.
3. Expanded Mode
This is the usual mode where the code generator generates a class for each of the outer
elements and the named complex types. The command line tool (XSD2Java) always
generates code in the expanded mode.
The rules for generating code (described in the next section) applies regardless of the
mode. Switching these modes can be done by passing the correct options via the
CompilerOptions object. The following table lists the options and the effects of using them.

142
Field Name in
Description
Options
This determines whether to write the output or not. If the flag is on
writeOutput
then the classes will be written by ADB. The default is off.
This determines whether to wrap the generated classes. If the flag is on
wrapClasses then a single class (with adb added to the end of the specified package)
will be generated. The default is off.
The package name for the mapper class. Please see the advanced
mapperClassPackage
section for details of the mapper class.
The switch that determines whether to switch to helper mode or not.
helperMode
Please see the advanced section for details of helper mode.
A map that stores the namespace name against the package name
ns2PackageMap
These details are used to override the default packages

Deep into Generated Code


When the schema compiler is invoked (one-way or another) it generates code depending on
the following rules:
1. All named complex types become bean classes. Any attribute or element
encapsulated in this complex type will become a field in the generated class. Note that
the support for constructs other than xsd:sequence and xsd:all is not yet implemented.
2. All top level elements become classes. This is a rather obvious feature since unless
classes are generated for the top level elements the handling of elements becomes
difficult and messy!
3. SimpleType restrictions are handled by replacing the relevant type with the basetype
Once the code is generated according to the rules it looks like the following. Consider the
following schema:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://soapinterop.org/types"
targetNamespace="http://soapinterop.org/types"
elementFormDefault="qualified" >
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="SOAPStruct">
<sequence>
<element name="varString" type="xsd:string"/>
<element name="varInt" type="xsd:int"/>
<element name="varFloat" type="xsd:float"/>
</sequence>
</complexType>
<element name="myElement" type="tns:SOAPStruct"/>
</schema>

For comprehension let us consider the expanded mode for the code generator. Unless
specifically mentioned, the rest of this document assumes that the expanded mode of the code
generation is used. This particular schema will generate the following two classes in the
designated package, which in this case would be org.soapinterop.types. The package name
is derived from the target namespace of the schema.
1. MyElement.java
2. SOAPStruct.java

143
As explained earlier, SOAPStruct refers to the complexType. MyElement is the class that
refers to the element. Just as expected, the SOAPStruct bean has getters and setters for
varString, varInt and varFloat which are String, int and float respectively. MyElement on the
other hand has a single field representing the SOAPStruct object that it encapsulates.
The most important aspect of the generated code is that it encapsulates two methods for
creating and serializing the beans. Note that to make this work, the generated beans
implement the org.apache.axis2.databinding.ADBBean interface
The creator and serializer methods look like the following:
• public javax.xml.stream.XMLStreamReader
getPullParser(javax.xml.namespace.QName qName)

This method returns a pull parser that throws the right events for this particular object.
However there is a subtle difference between element based classes and complexType
based classes
1. An element based bean class (like MyElement.java in the example) will
ignore the passed in QName. Instead of using the passed in QName it'll utilize
its own QName which is embedded in the class under the constant MY_QNAME,
during the code generation. Hence it is usual to call getPullparser() with a null
parameter for elements.
2. A ComplexType based bean class (like SOAPStruct.java in the example) will
use the passed-in QName to return an instance of the ADBpullparser. This will
effectively wrap the elements inside with an element having the passed QName
• public org.apache.axiom.om.OMElement getOMElement(
final javax.xml.namespace.QName parentQName,
final org.apache.axiom.om.OMFactory factory){

This method returns an OMElement representing the ADB bean object.


1. Inside the getOMElement method an anonymous ADBDataSource class is
created. This anonymous class implements a serialize() method where the
serialization logic for that particular bean class is handled. Finally an
OMSourcedElementImpl object with the above anonymous class type object as
the data source is returned.
• public static [Object].Factory.
parse(javax.xml.stream.XMLStreamReader reader)
throws java.lang.Exception

This method returns a populated instance of the class in question. Note that
[Object]
will be replaced by the actual class that contains this method. Say for SOAPStruct the
method looks like
public static SOAPStruct.Factory.
parse(javax.xml.stream.XMLStreamReader reader)
throws java.lang.Exception

Also note that the above parse method is available in the Factory nested class within
the relevant top level class. Hence one will have to get the static Factory instance
before calling the parse method.

An Example!
Consider the following XML fragment

144
<myElement xmlns="http://soapinterop.org/types">
<varInt>5</varInt>
<varString>Hello</varString>
<varFloat>3.3</varFloat>
</myElement>

Enthusiastic readers might already have figured out that this XML fragment complies with
the Schema mentioned above. The following code snippet shows how to build a populated
instance of MyElement with the XML above:

XMLStreamReader reader = XMLInputFactory.newInstance().


createXMLStreamReader(
new
ByteArrayInputStream(xmlString.getBytes()));
MyElement elt = MyElement.Factory.parse(reader);

Optionally, the above xml fragment can be reproduced with the following code fragment:
OMElement omElement = myElement.getOMElement
(MyElement.MY_QNAME,
OMAbstractFactory.getSOAP12Factory());
String xmlString = omElement.toStringWithConsume();

Although this example takes on the tedious effort of creating a reader out of a String, inside
the Axis2 environment an XMLStreamReader can be directly obtained from the OMElement!
Hence, the parse method becomes a huge advantage for hassle free object creation.
Similarly the reader obtained from the object can also be utilized as needed. The following code
fragment shows how to utilize the getPullParser method to create an OMElement :

XMLStreamReader reader = elt.getPullParser(null);


OMElement omElt = new StAXOMBuilder(reader).getDocumentElement();

That's all to it! If you are interested in learning more on ADB the following documents may
also be helpful. However, be sure to check the limitations section that follows if you are
planning to use ADB for something serious.

Known Limitations
ADB is meant to be a 'Simple' databinding framework and was not meant to compile all
types of schemas. The following limitations are the most highlighted.
1. Complex Type Extensions and Restrictions.

Want to Learn More?


• Advanced features of the ADB code generator - explains xsi:type based
deserialization and helper mode
• Tweaking the ADB Code Generator - explains available mechanisms to extend ADB
and possibly adopt it to compile schemas to support other languages.
• ADB and Axis2 Integration - explains how the ADB schema compiler was attached to
the Axis2 framework

145
Advanced Axis2 Databinding Framework Features
The aim of this section is provide an insight into the newly added advanced features of the
Axis2 Databinding (ADB) Framework.

Content
• xsi:type Support
• Helper Mode
• Additional ADB Topics

xsi:type Support
This is implemented by adding a extension mapping class. The code that calls the extension
mapper is generated inside the Factory.parse method of the beans and gets activated when the
xsi:type attribute is present. The following code fragment shows what the generated type
mapper looks like :

public static java.lang.Object getTypeObject(java.lang.String


namespaceURI, java.lang.String typeName,
javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception{

if(
"http://soapinterop.org/types".equals(namespaceURI) &&
"SOAPStruct".equals(typeName)){
return com.test.SOAPStruct.Factory.parse(reader);
}
throw new java.lang.RuntimeException("Unsupported type " +
namespaceURI + " " + typeName);
}

Inside every Factory.parse method, the extension mapper gets called when a xsi:type
attribute is encountered and that type is not the type that is currently being parsed.
The following code fragment shows how the ADB deserialize method calls the mapper class:

if (reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-
instance","type")!=null){
String fullTypeName =
reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance",
"type");
if (fullTypeName!=null){
String nsPrefix = fullTypeName.substring(0,fullTypeName.indexOf(":"));
nsPrefix = nsPrefix==null?"":nsPrefix;
String type = fullTypeName.substring(fullTypeName.indexOf(":")+1);
if (!"SOAPStruct".equals(type)){
//find namespace for the prefix
String nsUri = reader.getNamespaceContext().getNamespaceURI(nsPrefix);
return (SOAPStruct)org.soapinterop.types.ExtensionMapper.getTypeObject(
nsUri,type,reader);
}
}
}

This makes xsi:type based parsing possible and results in proper xsi:type based
serializations at runtime.

146
By default, the mapping package is derived from the targetnamespace of the first schema
that is encountered. The package name can also be explicitly set by a CompilerOption:

CompilerOptions compilerOptions = new CompilerOptions();


compilerOptions.setWriteOutput(true);

compilerOptions.setOutputLocation(new File("src"));
try {
SchemaCompiler schemaCompiler = new
SchemaCompiler(compilerOptions);
XmlSchemaCollection xmlSchemaCollection = new
XmlSchemaCollection();
XmlSchema xmlSchema =xmlSchemaCollection.read(new
FileReader("schema/sample.xsd"),null);
schemaCompiler.compile(xmlSchema);
} catch (Exception e) {
e.printStackTrace();
}

Helper mode
Helper mode is a fairly new feature. In the helper mode, the beans are plain Java beans and
all the deserialization/serialization code is moved to a helper class. For example, the simple
schema mentioned in the ADB-howto document will yield four classes instead of the two
previously generated:
1. MyElement.java
2. MyElementHelper.java
3. SOAPStruct.java
4. SOAPStructHelper.java
The helpers basically contain all the serialization code that otherwise would go into the
ADBBeans. Hence the beans in the helper mode are much more simplified. Also note that the
helper mode is available only if you are in unpacked mode. The code generator by default does
not expand the classes.
Helper mode can be switched on by using the setHelperMode method in CompilerOptions:

Additional ADB Topics


• Tweaking the ADB Code Generator- explains available mechanisms to extend ADB
and possibly adopt it to compile schemas to support other languages.
• ADB and Axis2 Integration - explains how the ADB schema compiler was attached to
the Axis2 framework

ADB Integration With Axis2


This document will assist you in writing an extension using the integrator in order to
integrate ADB with Axis2.

Content
• Introduction

147
• Selection of Generation Modes for ADB
• Things to Remember

Introduction
ADB Integration with Axis2 is simple and straightforward. Given the extension mechanism of
the Axis2 code generator, the obvious choice for the integrator is to write an extension. The
extension that is added to support ADB is the SimpleDBExtension
(org.apache.axis2.wsdl.codegen.extension.SimpleDBExtension) and can be found in the
extensions list of the codegen-config.properties file.

Selection of Generation Modes for ADB


The extension sets the options for the code generator via the CompilerOptions, depending
on the user's settings. The following table summarizes the use of options. Please refer to the
ADB-How to document for the different generation modes and their descriptions.

User parameters Selected code generation parameters


None (no parameter other than mandatory ones) wrapClasses=false,writeClasses=false
-ss (server side) wrapClasses=false,writeClasses=true
-u (unwrap classes) wrapClasses=false,writeClasses=true
The following parameters (prefixed with -E) can be used to override these settings
manually:

Parameter Name Allowed values Description


Sets the write flag. If set to true the classes will be written by
r true, false
ADB
w true, false Sets the wrapping flag. if true the classes will be wrapped.
Note that these parameters have no corresponding long names and MUST be prefixed with a
-E to be processed by the code generator. For example:
WSDL2Java .... -Er true

Things to Remember
1. SimpleDBExtension is for the ADB databinding framework only and will process
requests only when this framework is specified during code generation (using the switch
-d adb). In the most recent release, the default has been set as ADB and hence if the -d
option is missing then the databinding framework will be ADB.

ADB Tweaking Guide


This document explains the mechanisms available to extend ADB and possibly adopt it to
compile schemas to support other languages.

Content
• Introduction
• Know the Configuration
• The First Tweak - Generate Plain Java Beans

148
• A More Advanced Tweak - Generate Code for Another Language

Introduction
ADB was written with future extensibility in mind, with a clear and flexible way to extend or
modify its functionality. Available mechanisms to extend ADB and possibly adopt it to compile
schemas to support other languages are described below.

Know the Configuration


The configuration for the ADB framework is in the schema-compile.properties file found
in the org.apache.axis2.schema package. This properties file has the following important
properties
• schema.bean.writer.class
This is the writer class. This is used by the schema compiler to write the beans and
should implement the org.apache.axis2.schema.writer.BeanWriter interface. The
schema compiler delegates the bean writing task to the specified instance of the
BeanWriter.
• schema.bean.writer.template
This specifies the template to be used in the BeanWriter. The BeanWriter author is free
to use any mechanism to write the classes but the default mechanism is to use a xsl
template. This property may be left blank if the BeanWriter implementation does not
use a template.
• schema.bean.typemap
This is the type map to be used by the schema compiler. It should be an
implementation of the org.apache.axis2.schema.typemap.TypeMap interface. The
default typemap implementation encapsulates a hashmap with type QName to Class
name string mapping.

The First Tweak - Generate Plain Java Beans


The first, most simple tweak for the code generator could be to switch to plain bean
generation. The default behavior of the ADB framework is to generate ADBBeans, but most
users, if they want to use ADB as a standalone compiler, would prefer to have plain java beans.
This can in fact be done by simply changing the template used.
The template for plain java beans is already available in the
org.apache.axis2.schema.template package. To make this work replace the
/org/apache/axis2/databinding/schema/template/ADBBeanTemplate.xsl with the
/org/apache/axis2/databinding/schema/template/PlainBeanTemplate.xsl in the
schema-compile.properties.
Congratulations! You just tweaked ADB to generate plain java beans.
To generate custom formats, the templates need to be modified. The schema for the xml
generated by the JavaBeanWriter is available in the source tree under the Other directory in
the codegen module. Advanced users with knowledge of XSLT can easily modify the templates
to generate code in their own formats.

A More Advanced Tweak - Generate Code for Another


Language
To generate code for another language, there are two main components that need to be

149
written.
• The BeanWriter
Implement the BeanWriter interface for this class. A nice example is the
org.apache.axis2.schema.writer.JavaBeanWriter which has a lot of reusable code.
In fact if the target language is object-oriented (such as C# or even C++), one would
even be able to extend the JavaBeanWriter itself.
• The TypeMap
Implement the TypeMap interface for this class. The
org.apache.axis2.schema.typemap.JavaTypeMap class is a simple implementation
for the typemap where the QName to class name strings are kept inside a hashmap
instance. This technique is fairly sufficient and only the type names would need to
change to support another language.
Surprisingly, this is all that needs to be done to have other language support for ADB.
Change the configuration and you are ready to generate code for other languages!
This tweaking guide is supposed to be a simple guideline for anyone who wishes to dig deep
into the mechanics of the ADB code generator. Users are free to experiment with it and modify
the schema compiler accordingly to their needs. Also note that the intention of this section is
not to be a step by step guide to custom code generation. Anyone who wish to do so would
need to dig into the code and get their hands dirty!

JiBx Data Binding


JiBX Integration With Axis2
This document describes using JiBX data binding with Axis2. JiBX differs from the other data
binding techniques supported by Axis2 in that it allows you to use your own Java data objects
(as opposed to Java data objects generated from a schema definition). JiBX also provides a
nicer form of unwrapped Web services interface than is supported by the other data binding
techniques. On the downside, JiBX requires more setup than the other data binding techniques
- in particular, you need to come up with a set of data classes and a binding definition in order
to work with JiBX in Axis2.
JiBX support for Axis2 and Web services in general is continuing to evolve. This page covers
the basics of using JiBX with Axis2 as of the current release. Check the JiBX Axis2 Wiki page
for updated information about using JiBX with Axis2.

Content
• Introduction
• Wrapped vs. unwrapped
• Starting from Java
• Starting from WSDL
• Axis2 JiBX Code Generation
• Coming Attractions

Introduction
JiBX data binding supports fast and flexible conversions between plain old Java objects
(POJOs) and XML. JiBX uses a mapped binding approach that's based on binding definition

150
documents you provide. This approach let's you customize the way your Java objects are
converted to and from XML. You can even define multiple bindings to use the same Java
objects with different XML representations. These features make JiBX especially useful if you're
developing a Web service based on existing Java code, or when you need to support multiple
XML representations for a Web service (as when you're using versioned schema definitions).
Axis2 supports using JiBX with your Web services, including generating the necessary
linkage code for both client and server sides. However, the Axis2 support for JiBX does not
currently include code generation from the schema for a Web service - you need to provide
your own data classes and JiBX binding definition, and you also need to make sure that the
binding definition matches the XML structures defined for your Web service. The JiBX project
provides some basic tools to help with code generation from schema, binding generation from
Java classes, and schema generation from the combination of Java classes and a binding
definition. In the future, improved versions of these tools will be integrated directly into the
Axis2 framework support, but for now you're on your own with this part of the setup.
You can use JiBX data binding both to expose existing Java code as a service, and to build a
client for an existing service. This document runs through the sequence of steps involved for
each of these cases, just to help users understand the basic approach to working with JiBX in
Axis2. You can find full instructions on the standard JiBX parts of this sequence on the JiBX
Web site.

Wrapped vs. unwrapped


Axis2 support for JiBX currently only works with the document-literal (doc/lit) form of Web
services definitions. Doc/lit Web services generally use particular schema elements as input
and output from each operation, and the Axis2 support for JiBX assumes this structure (which
is also the structure required for compatibility with the WS-I Basic Profile).
A popular subset of doc/lit Web services use a form called "wrapped". Wrapped doc/lit Web
services define service operations that correspond to method calls, using input and output
element names based on the method name and embedding the actual parameter values for
the method call within the input element.
When used with Axis2, JiBX supports both general doc/lit and wrapped service definitions.
Wrapped service definitions can be "unwrapped" during code generation to provide a greatly
simplified interface. JiBX unwrapping of service definitions is not compatible with the
unwrapping support for other data binding frameworks used with Axis2, but most users will
find the JiBX approach easy and convenient. See the JiBX Unwrapped Example and the JiBX
Document/Literal Example pages for a detailed comparison of the two forms of service
interface.

Starting from Java


Here's the sequence of steps for using JiBX with Axis2 to expose existing Java code as a
Web service:
1. Create a JiBX binding definition for the data being transferred by the Web service
(you may be able to use the JiBX binding generator to help with this step).
2. Create a schema that matches the XML defined by your binding (you may be able to
use the JiBX schema generator to help with this). If you're using a wrapped form of
interface to your service you'll also need to create schema definitions for the wrapper
input and output elements used by each operation.
3. Create a WSDL document for your service, with the schema embedded or imported.
4. Generate Axis2 server-side linkage code using WSDL2Java with the WSDL and your
binding definition.
5. Run the JiBX binding compiler on your Java classes to add the actual binding code.

151
6. Include the axis2-jibx.jar in your runtime classpath, along with the jibx-runtime.jar.
If you use a wrapped interface for your Web service you can expose method calls in your
existing code directly as operations in the service. In this case you normally just use your
existing data objects with JiBX data binding, and add schema definitions for the wrapper
elements. See the JiBX Unwrapped Example page for more details on how this works.
If you use a non-wrapped interface for your Web service you need to define classes to hold
the data input and output from each operation. In this case these holder classes need to be
included in the JiBX binding definition. See the JiBX Document/Literal Example page for more
details on this case.

Starting from WSDL


Here's the sequence of steps for using JiBX with Axis2 to implement a client for an existing
Web service (or the actual service, when you've been supplied with the WSDL your service is
to implement):
1. Create Java classes for the data being transferred by the Web service, and a JiBX
binding definition that maps these classes to the schema defined by the Web service
(you may be able to use the JiBX xsd2jibx tool to help with this).
2. Generate Axis2 client linkage code using WSDL2Java with the WSDL and your binding
definition.
3. Run the JiBX binding compiler on your Java classes to add the actual binding code.
4. Include the axis2-jibx.jar in your runtime classpath, along with the jibx-runtime.jar
As with the starting from Java case, there are some differences in the handling depending
on whether your service definition fits the wrapped form. See the JiBX Unwrapped Example
and JiBX Document/Literal Example pages for more details.

WSDL2Java usage
To run the WSDL2Java tool for JiBX data binding you need:
1. To specify -d jibx to select JiBX binding.
2. You also generally need an additional parameter, -Ebindingfile {file} (where {file} is
the file path to your JiBX binding definition).
3. Finally, you need to have the axis2-jibx-XXXX.jar, the jibx-bind-XXXX.jar, and the
jibx-run-XXXX.jar files from your Axis2 distribution included in the WSDL2Java
classpath.
If you want to use the unwrapped form of interface you also need to specify the -uw option
to WSDL2Java. In this case your JiBX binding definition must include abstact mappings for all
the complex objects which correspond to method parameters, and each abstract mapping must
specify a type-name attribute that matches the schema complexType used in the WSDL. You
can also use formats in the binding definition to define the handling of schema simpleTypes.
Schema types corresponding to Java primitives and simple objects with built-in JiBX
conversions are handled automatically, and if all the parameter and return values in your
wrapped WSDL are of these types you don't even need a JiBX binding definition. This is the
one case where the -Ebindingfile {file} parameter is not needed.
If you're not unwrapping the interface, you must use a JiBX binding definition and it must
include a concrete mapping for each element used as input or output by any operation.

Coming Attractions
Work is in-progress on better tools to support generating Java classes and corresponding

152
JiBX binding definitions from an input schema, and also for generating binding+schema
generation from existing code. These features will be integrated into the Axis2 JiBX support
when they are available. Check the JiBX project site for updates on JiBX, and the JiBX Axis2
Wiki page for updated information about using JiBX with Axis2.

References
JiBX: Bindings Tutorial

JiBX general document/literal


Code generation for JiBX data binding converts operations defined by a Web service to
method calls. With general document/literal (doc/lit) Web services the generated methods each
take a single parameter object and return a single result object. Here's a sample doc/lit WSDL
(partial) by way of an example:

<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"
xmlns:tns="http://ws.sosnoski.com/library/types"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">

<wsdl:types>

<schema elementFormDefault="qualified"
targetNamespace="http://ws.sosnoski.com/library/types"
xmlns="http://www.w3.org/2001/XMLSchema">

<element name="getBook">
<complexType>
<sequence>
<element name="isbn" type="string"/>
</sequence>
</complexType>
</element>

<element name="getBookResponse">
<complexType>
<sequence>
<element name="book" minOccurs="0"
type="tns:BookInformation"/>
</sequence>
</complexType>
</element>

<element name="addBook">
<complexType>
<sequence>
<element name="type" type="string"/>
<element name="isbn" type="string"/>
<element name="author" minOccurs="0" maxOccurs="unbounded"
type="string"/>
<element name="title" type="string"/>
</sequence>
</complexType>
</element>

153
<element name="addBookResponse">
<complexType>
<sequence>
<element name="success" type="boolean"/>
</sequence>
</complexType>
</element>

<complexType name="BookInformation">
<sequence>
<element name="author" minOccurs="0" maxOccurs="unbounded"
type="string"/>
<element name="title" type="string"/>
</sequence>
<attribute name="type" use="required" type="string"/>
<attribute name="isbn" use="required" type="string"/>
</complexType>

</schema>

</wsdl:types>

<wsdl:message name="getBookRequest">
<wsdl:part element="wns:getBook" name="parameters"/>
</wsdl:message>

<wsdl:message name="getBookResponse">
<wsdl:part element="wns:getBookResponse" name="parameters"/>
</wsdl:message>

<wsdl:message name="addBookRequest">
<wsdl:part element="wns:addBook" name="parameters"/>
</wsdl:message>

<wsdl:message name="addBookResponse">
<wsdl:part element="wns:addBookResponse" name="parameters"/>
</wsdl:message>

<wsdl:portType name="Library">

<wsdl:operation name="getBook">
<wsdl:input message="wns:getBookRequest" name="getBookRequest"/>
<wsdl:output message="wns:getBookResponse"
name="getBookResponse"/>
</wsdl:operation>

<wsdl:operation name="addBook">
<wsdl:input message="wns:addBookRequest" name="addBookRequest"/>
<wsdl:output message="wns:addBookResponse"
name="addBookResponse"/>
</wsdl:operation>

</wsdl:portType>
...
</wsdl:definitions>

This WSDL defines a service with just two operations: getBook and addBook. The
getBook operation takes a getBook element as input, and returns a getBookResponse element
as output, while addBook takes an addBook element as input and returns an
addBookResponse as output. Here's the body of the client interface generated by the standard

154
JiBX code generation:

public interface LibraryJibxUnwrapped {


/**
* Auto generated method signatures
* @param addBook
*/
public com.sosnoski.ws.library.jibx.wrappers.AddBookResponse
addBook(
com.sosnoski.ws.library.jibx.wrappers.AddBookRequest addBook)
throws java.rmi.RemoteException;

/**
* Auto generated method signatures
* @param getBook
*/
public com.sosnoski.ws.library.jibx.wrappers.GetBookResponse
getBook(
com.sosnoski.ws.library.jibx.wrappers.GetBookRequest getBook)
throws java.rmi.RemoteException;
}

You can see that the JiBX code generation converted the operations into simple method call
interfaces using objects corresponding to the input and output elements of the operation (see
JiBX Unwrapped Example for the interface generated when unwrapping is instead used). The
server-side interface is the same.
You need to supply an appropriate JiBX binding definition for use in code generation (using
the -Ebindingfile {file} parameter for WSDL2Java - see JiBX Codegen Integration - WSDL2Java
usage for more details). This must define concrete mappings for each element used as the
input or output of an operation. The JiBX code generation extension matches the element
names to the binding in order to determine the corresponding class to use in generated code.
For example, here's a binding definition that matches the above WSDL:

<binding add-constructors="true">
<namespace uri="http://ws.sosnoski.com/library/types"
default="elements"/>
<mapping name="getBook"
class="com.sosnoski.ws.library.jibx.wrappers.GetBookRequest">
<value name="isbn" field="m_isbn"/>
</mapping>

<mapping name="getBookResponse"
class="com.sosnoski.ws.library.jibx.wrappers.GetBookResponse">
<structure name="book" field="m_book"/>
</mapping>

<mapping name="addBook"
class="com.sosnoski.ws.library.jibx.wrappers.AddBookRequest">
<structure field="m_book">
<value name="type" field="m_type"/>
<value name="isbn" field="m_isbn"/>
<collection field="m_authors">
<value name="author" type="java.lang.String"/>
</collection>
<value name="title" field="m_title"/>
</structure>
</mapping>

155
<mapping name="addBookResponse"
class="com.sosnoski.ws.library.jibx.wrappers.AddBookResponse"/>

<mapping abstract="true"
class="com.sosnoski.ws.library.jibx.beans.Book">
<value name="type" style="attribute" field="m_type"/>
<value name="isbn" style="attribute" field="m_isbn"/>
<collection field="m_authors">
<value name="author" type="java.lang.String"/>
</collection>
<value name="title" field="m_title"/>
</mapping>

</binding>

And here are the actual data object classes:

package com.sosnoski.ws.library.jibx.wrappers;

import com.sosnoski.ws.library.jibx.beans.Book;

public class AddBookRequest {


private Book m_book;

public AddBookRequest(Book book) {


m_book = book;
}

public Book getBook() {


return m_book;
}
}

public class AddBookResponse {


}

public class GetBookRequest {


private String m_isbn;

public GetBookRequest(String isbn) {


m_isbn = isbn;
}

public String getIsbn() {


return m_isbn;
}
}

156
public class GetBookResponse {
private Book m_book;

public GetBookResponse(Book book) {


m_book = book;
}

public Book getBook() {


return m_book;
}
}

package com.sosnoski.ws.library.jibx.beans;

public class Book {


private String m_type;
private String m_isbn;
private String m_title;
private String[] m_authors;

public Book() {}

public String getType() {


return m_type;
}

public String getIsbn() {


return m_isbn;
}

public String getTitle() {


return m_title;
}

public String[] getAuthors() {


return m_authors;
}
}

JiBX Unwrapped document/literal


Code generation for JiBX data binding converts operations defined by a Web service to
method calls. In the most general case of document/literal (doc/lit) Web services the
generated methods each take a single parameter object and return a single result object. This
type of interface can be painful for developers because it adds both a layer of indirection and
potentially a large number of extra classes (one input and one output class for each generated
method).
Fortunately, there's an alternative way of generating methods that gives a much more
usable API for many Web services. This alternative is called unwrapping, and the service
definitions that it applies to are called wrapped definitions. The key difference that qualifies a
service definition as wrapped is the structure of the input and output elements used for
operations.
Here's a sample wrapped WSDL (partial) by way of an example:

157
<wsdl:definitions targetNamespace="http://ws.sosnoski.com/library/wsdl"
xmlns:tns="http://ws.sosnoski.com/library/types"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">

<wsdl:types>
<schema elementFormDefault="qualified"
targetNamespace="http://ws.sosnoski.com/library/types"
xmlns="http://www.w3.org/2001/XMLSchema">

<element name="getBook">
<complexType>
<sequence>
<element name="isbn" type="string"/>
</sequence>
</complexType>
</element>

<wsdl:message name="getBookRequest">
<wsdl:part element="wns:getBook" name="parameters"/>
</wsdl:message>

<wsdl:message name="getBookResponse">
<wsdl:part element="wns:getBookResponse" name="parameters"/>
</wsdl:message>
<element name="getBookResponse">
<complexType>
<wsdl:message name="addBookRequest">
<sequence>
<wsdl:part
<element element="wns:addBook"
name="book" name="parameters"/>
minOccurs="0" type="tns:BookInformation"/>
</wsdl:message>
</sequence>
</complexType>
<wsdl:message
</element>name="addBookResponse">
<wsdl:part element="wns:addBookResponse" name="parameters"/>
</wsdl:message>
<element name="addBook">
<complexType>
<wsdl:portType name="Library">
<sequence>
<element name="type" type="string"/>
<wsdl:operation name="getBook">
<element name="isbn" type="string"/>
<wsdl:input message="wns:getBookRequest" name="getBookRequest"/>
<element name="author" minOccurs="0" maxOccurs="unbounded"
<wsdl:output message="wns:getBookResponse"
type="string"/>
name="getBookResponse"/>
<element name="title" type="string"/>
</wsdl:operation>
</sequence>
</complexType>
<wsdl:operation name="addBook">
</element>
<wsdl:input message="wns:addBookRequest" name="addBookRequest"/>
<wsdl:output message="wns:addBookResponse"
<element name="addBookResponse">
name="addBookResponse"/>
<complexType>
</wsdl:operation>
<sequence>
<element name="success" type="boolean"/>
</wsdl:portType>
... </sequence>
</complexType>
</wsdl:definitions>
</element>
<complexType name="BookInformation">
<sequence>
<element name="author" minOccurs="0" maxOccurs="unbounded"
type="string"/>
<element name="title" type="string"/>
</sequence>
158
<attribute name="type" use="required" type="string"/>
<attribute name="isbn" use="required" type="string"/>
</complexType>
</schema>
</wsdl:types>
This WSDL defines a service with just two operations: getBook and addBook. The
getBook operation takes a getBook element as input, and returns a getBookResponse element
as output, while addBook takes an addBook element as input and returns an
addBookResponse as output. Each of these input and output elements in turn consists of a
sequence of child elements, with some of the child elements defined directly using standard
schema types and others referencing user-defined schema types.
As I said up front, this WSDL qualifies for unwrapped handling using JiBX. Here's the body
of the client interface generated when using unwrapping (the -uw option for WSDL2Java):

public interface LibraryJibxUnwrapped {


/**
* Auto generated method signatures
* @param type* @param isbn* @param author* @param title
*/
public boolean addBook(
java.lang.String type,java.lang.String isbn,java.lang.String[]
author,java.lang.String title) throws java.rmi.RemoteException;
/**
* Auto generated method signatures
* @param isbn
*/
public com.sosnoski.ws.library.jibx.beans.Book getBook(
java.lang.String isbn) throws java.rmi.RemoteException;
}

You can see that the JiBX code generation converted the operations into simple method call
interfaces without introducing any extraneous objects (see JiBX Document/Literal Example for
the interface generated when unwrapping is not used). The server-side interface is the same.
The key points that allow unwrapped handling with JiBX are:
1. Each operation either accepts no input, or the input consists of a single element.
2. Each input element is defined as a schema complexType consisting of a sequence of
any number of child elements.
3. Each operation either generates no output, or the output consists of a single
element.
4. Each output element is defined as a schema complexType consisting of a sequence
that's either empty or contains a single child element.
5. The child elements of both inputs and outputs are defined using type references,
rather than an embedded type definitions.
You also need to supply an appropriate JiBX binding definition (using the -Ebindingfile {file}
parameter for WSDL2Java - see JiBX Codegen Integration - WSDL2Java usage for more
details). This must define abstract mappings for the complexTypes referenced by child
elements of the inputs and outputs, with a type-name attribute matching the schema
complexType name. If the child elements reference schema simpleType definitions the binding
must also define a formats for each simpleType, with a label attribute matching the schema
simpleType name. The binding definition must also specify the force-classes='true' attribute on
the binding element.
For example, here's a binding definition that matches the above WSDL:

159
<binding force-classes="true"
xmlns:tns="http://ws.sosnoski.com/library/types">

<namespace uri="http://ws.sosnoski.com/library/types"
default="elements"/>

<mapping abstract="true"
class="com.sosnoski.ws.library.jibx.beans.Book"
type-name="tns:BookInformation">
<value name="type" style="attribute" field="m_type"/>
<value name="isbn" style="attribute" field="m_isbn"/>
<collection field="m_authors">
<value name="author"/>
</collection>
<value name="title" field="m_title"/>
</mapping>
</binding>

And here's the actual com.sosnoski.ws.library.jibx.beans.Book class:

public
package String getIsbn() {
com.sosnoski.ws.library.jibx.beans;
return
public class m_isbn;
Book {
}
private String m_type;
private String m_isbn;
public
privateString
StringgetTitle()
m_title; {
return m_title;
private String[] m_authors;
}
public Book() {}
public String[] getAuthors() {
return
public m_authors;
String getType() { return m_type; }
}
}

The JiBX code generation for Axis2 currently requires that classes coresponding to
unwrapped child elements (such as com.sosnoski.ws.library.jibx.beans.Book, in this
case) provide public default (no-argument) constructors.
JiBX handling allows the child elements of both inputs and outputs to be optional (with
nillable='true', minOccurs='0', or both), providing the binding converts these child elements to
object types rather than primitive types. It also allows repeated child elements (with
minOccurs='unbounded', or any value of minOccurs greater than one), representing the
repeated elements as arrays of the corresponding object or primitive types.

Advanced
Writing Web Services Using Apache Axis2's Primary
APIs
Apache Axis2 dispatches a component called MessageReceiver when Receiving a Message
to the server. Apache Axis2 provides different implementations of this class and it can be
configured by adding a messageReceiver tag to services.xml. Apache Axis2 provides an
implementation for a class of Message receivers called RawXml Message receivers. They work
at the XML level and can only handle OMElements as parameters. This section explains how to
write a service using them.

160
In our example, the Web service will have two operations.

public void ping(OMElement element){}


//IN-ONLY op, just accepts the OMElement and does some processing.
public OMElement echo(OMElement element){}
//IN-OUT op, accepts an OMElement and sends back the same again

How to Write a Web Service?


Writing a new Web service with Apache Axis2 involves four steps:
1. Write the Implementation Class.
2. Write a services.xml file to explain the Web service.
3. Create a *.aar archive (Axis Archive) for the Web service.
4. Deploy the Web service.

Step1: Write the Implementation Class


An implementation class has the business logic for the Web service and implements the
operations provided by the Web service. Unless you have data binding, the signature of the
methods can have only one parameter of the type OMElement.
For more details on OMElement see the OM Tutorial.

public class MyService{


public void ping(OMElement element){
// Business Logic
......
}
public OMElement echo(OMElement element){
......
}
}

Step2: Write the services.xml file


"services.xml" has the configuration for a Web service. Each Web service, deployed in
Apache Axis2 , must have its configuration in "services.xml". The configuration for MyService is
as follows:

161
<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"/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name="ping">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
<actionMapping>urn:ping</actionMapping>
</operation>
</service>

The above XML tags can be explained as follows:


1. The description of the service class is provided in the description tag.

<service >
<description>
This is a sample Web service with two operations, echo and ping.
</description>

2. The name of the service class is provided as a parameter.

<parameter name="serviceClass" locked="false">


userguide.example1.MyService
</parameter>

3. The "operation" XML tag describes the operations that are available in this service with
respective message receivers.

<operation name="echo">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
<actionMapping>urn:echo</actionMapping>
</operation>
<operation name="ping">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
<actionMapping>urn:ping</actionMapping>
</operation>

4. Every operation must map to a corresponding MessageReceiver class. After a message is


processed by the handlers, the Axis2 engine hands it over to a MessageReceiver.
5. For the "echo" operation, we have used a RawXMLINOutMessageReceiver since it is
an IN-OUT operation. For the IN-ONLY operation "ping", we have used
RawXMLINOnlyMessageReceiver as the message receiver.
6. The actionMapping is required only if you want to enable WS-Addressing. This will be
used later in this user guide.

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

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

Note : The name of the service is a compulsory attribute.

Step3: Create the Web Service Archive


Apache Axis2 uses the ".aar" (Axis Archive) file as the deployment package for Web
services. Therefore, for MyService we will use "MyService.aar" with the "services.xml"
packaged in the META-INF in the directory structure shown below. Please note that the name
of the archive file will be the same as that of the service only if the services.xml contains only
one service element.

To create the archive file, you can create a .jar file containing all the necessary files and
then rename it to a .aar file. This archive file can be found in the
"Axis2_HOME/samples/userguide" directory. This file has to be deployed now.

Step4: Deploy the Web Service


The service can be deployed by dropping the ".aar" file into the "services" directory in
"/webapps/axis2/WEB-INF" of your servlet container. Start the servlet container (if you have
not already started), click the link "Services" on the Home Page of Axis2 Web Application
(http://localhost:8080/axis2) and see whether MyService is deployed properly. If you can see
the following output, then you have successfully deployed MyService on Apache Axis2.
Congratulations !!

163
Note: Apache Axis2 provides an easy way to deploy Web services using the "Upload Service"
tool on the Axis2 Web Application's Administration module. Please refer to the Web
Administration Guide for more information.

Writing Web Service Clients Using Axis2's Primary


APIs
This section presents a complex yet powerful XML based client API, which is intended for
advanced users. However, if you are a new user, we recommend using code generation given
in the Advance User's Guide.
Web services can be used to provide a wide-range of functionality to the user from simple,
quick operations such as "getStockQuote" to time consuming business services. When we
utilize (invoke using client applications) these Web services, we cannot use simple generic
invocation paradigms that suite all the timing complexities involved in the service operations.
For example, if we use a single transport channel (such as HTTP) to invoke a Web service with
an IN-OUT operation that takes a long time to complete, then most often we may end up with
"connection time outs". On the other hand, if there are simultaneous service invocations that
we need to perform from a single client application, then the use of a "blocking" client API will
degrade the performance of the client application. Similarly, there are various other

164
consequences such as One-Way transports that come into play when we need them. Let's try
to analyze some common service invocation paradigms.
Many Web service engines provide users with Blocking and Non-Blocking client APIs.
• Blocking API - Once the service invocation is called, the client application hangs
and only regains control when the operation completes, after which the client receives a
response or a fault. This is the simplest way of invoking Web services, and it also suites
many business situations.
• Non-Blocking API - This is a callback or polling based API. Hence once a service
invocation is called, the client application immediately regains control and the response
is retrieved using the callback object provided. This approach provides flexibility to the
client application to invoke several Web services simultaneously without blocking the
operation already invoked.
Both mechanisms work at the API level. Let's name the asynchronous behavior that we can
get using the Non-Blocking API as API Level Asynchrony.
Both mechanisms use single transport connections to send the request and to receive the
response. They severely lag the capability of using two transport connections for the request
and the response (either One-Way or Two-Way). So both these mechanisms fail to address the
problem of long running transactions (the transport connection may time-out before the
operation completes). A possible solution would be to use two separate transport connections
for request and response. The asynchronous behavior that we gain using this solution can be
called Transport Level Asynchrony.
By combining API Level Asynchrony and Transport Level Asynchrony, we can obtain
four different invocation patterns for Web services as shown in the following table.
API Dual Transports? Description

Blocking No The simplest and more familiar invocation pattern

Non-Blocking No Using callbacks or polling

This is useful when the service operation is IN-OUT in nature


Blocking Yes
but the transport used is One-Way (e.g. SMTP)

This is can be used to gain the maximum asynchronous


Non-Blocking Yes behavior. Non blocking at the API level and also at the
transport level.

Axis2 provides the user with all these possibilities to invoke Web services.
The following section presents clients that use the different possibilities presented above to
invoke a Web Service using ServiceClients. All the samples mentioned in this guide are
located at the "samples\userguide\src" directory of the binary distribution.
This section presents four types of clients.
1. Request-Response, Blocking Client
2. One Way Client
3. Request-Response, Non-Blocking that uses one transport connection
4. Request-Response, Non-Blocking that uses two transport connections

165
Request-Response, Blocking Client
Axis2 provides the user with several invocation patterns for Web services, ranging from pure
blocking single channel invocations to non-blocking dual channel invocations. First let us see
how we can write a client to invoke the "echo" operation of "MyService" using the simplest
blocking invocation. The client code you need to write is as follows.

try {
OMElement payload = ClientUtil.getEchoOMElement();

Options options = new Options();


options.setTo(targetEPR);
// this sets the location of MyService service

ServiceClient serviceClient = new ServiceClient();


serviceClient.setOptions(options);

OMElement result = serviceClient.sendReceive(payload);

System.out.println(result);

} catch (AxisFault axisFault) {


axisFault.printStackTrace();
}

1. The lines highlighted in green show the set of operations that you need to perform in
order to invoke a Web service.
2. 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
"Axis2_HOME/samples/userguide" directory. Run the "run.client.blocking" target. If you
can see the response OMElement printed in your command line, then you have successfully
tested the client.

One Way Client


In the Web service "MyService", we had an IN-ONLY operation with the name "ping" (see
Creating a New Web Service). Let's write a client to invoke this operation. The client code is as
follows:

166
try {
OMElement payload = ClientUtil.getPingOMElement();
Options options = new Options();
options.setTo(targetEPR);
ServiceClient serviceClient = new ServiceClient();
serviceClient.setOptions(options);
serviceClient.fireAndForget(payload);
/**
* We have to block this thread untill we send the request , the problem
* is if we go out of the main thread , then request wont send ,so
* you have to wait some time :)
*/
Thread.sleep(500);
}
catch (AxisFault axisFault) {
axisFault.printStackTrace();
}

Since we are accessing an IN-ONLY operation, we can directly use the fireAndForget() in
the ServiceClient to invoke this operation. This will not block the invocation and will return the
control immediately back to the client. You can test this client by running the target
"run.client.ping" of the Ant build file at "Axis2Home/samples/userguide".
We have now invoked the two operations in our service. Are we done? No! There's a lot
more to explore. Let's see some other ways to invoke the same operations.

Request-Response, Non-Blocking that uses one transport


connection
In the "EchoBlockingClient" once the serviceClient.sendReceive(payload); is called, the
client is blocked till the operation is complete. This behavior is not desirable when there are
many Web service invocations to be done in a single client application or within a GUI. A
solution would be to use a Non-Blocking API to invoke Web services. Axis2 provides a callback
based non-blocking API for users.
A sample client for this can be found under
"Axis2_HOME/samples/userguide/src/userguide/clients" with the name
"EchoNonBlockingClient". If we consider the changes that users may have to do with respect to
the "EchoBlockingClient" that we have already seen, it will be as follows:
● serviceClient.sendReceiveNonblocking(payload, callback);
The invocation accepts a callback object as a parameter. Axis2 client API provides an
abstract Callback with the following methods:

public abstract void onComplete(AsyncResult result);


public abstract void onError(Exception e);
public boolean isComplete() {}

The user is expected to implement the "onComplete " and "onError " methods of their
extended call back class. The Axis2 engine calls the "onComplete" method once the Web
service response is received by the Axis2 Client API (ServiceClient). This will eliminate the
blocking nature of the Web service invocation and provide users with the flexibility to use Non
Blocking API for Web service Clients.
To run the sample client ("EchoNonBlockingClient") you can simply use the
run.client.nonblocking target of the Ant file found in the
"Axis2_HOME/samples/userguide" directory.

167
Request-Response, Non-Blocking that uses two transport
connections
The solution provided by the Non-Blocking API has one limitation when it comes to Web
service invocations that take a long time to complete. The limitation is due to the use of single
transport connections to invoke the Web service and retrieve the response. In other words,
client API provides a non-blocking invocation mechanism for users, but the request and the
response come in a single transport (Two-Way transport) connection (like HTTP). Long running
Web service invocations or Web service invocations using One-Way transports (like SMTP)
cannot be utilized by simply using a non-blocking invocation.
The trivial solution is to use separate transport connections (either One-Way or Two-Way)
for the request and response. The next problem that needs to be solved is the correlation
(correlating the request and the response). WS-Addressing provides a neat solution to this
using <wsa:MessageID> and <wsa:RelatesTo> headers. Axis2 provides support for an
addressing based correlation mechanism and a complying Client API to invoke Web services
with two transport connections. (The core of Axis2 does not depend on WS-Addressing, but
contains a set of parameters, like in addressing, that can be populated by any method. WS-
Addressing is one of the uses that may populate them. Even the transports can populate them.
Hence, Axis2 has the flexibility to use different versions of addressing)
Users can select between Blocking and 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. The following code fragment shows how to invoke the same "echo"
operation using Non-Blocking API with two transport connections. The ultimate asynchrony!!

try {
OMElement payload = ClientUtil.getEchoOMElement();

Options options = new Options();


options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setUseSeparateListener(true);
options.setAction("urn:echo");
// this is the action mapping we put within the service.xml

//Callback to handle the response


Callback callback = new Callback() {
public void onComplete(AsyncResult result) {
System.out.println(result.getResponseEnvelope());
}

public void onError(Exception e) {


e.printStackTrace();
}
};

168
//Non-Blocking Invocation
sender = new ServiceClient();
sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
sender.sendReceiveNonBlocking(payload, callback);
//Wait till the callback receives the response.
while (!callback.isComplete()) {
Thread.sleep(1000);
}
//Need to close the Client Side Listener.
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
sender.cleanup();
} catch (AxisFault axisFault) {
//have to ignore this
}
}

The boolean flag (value True) in the options.setUseSeparateListener(...) method


informs the Axis2 engine to use separate transport connections for the request and response.
Finally sender.cleanup() informs the Axis2 engine to stop the client side listener, which
started to retrieve the response.
To run the sample client ("EchoNonBlockingDualClient") you can simply use the
"run.client.nonblockingdual" target of the Ant file found in the
"Axis2_HOME/samples/userguide/" directory.

Handling Binary Data with Axis2 (MTOM/SwA)


This document describes how to use the Axis2 functionality to send/receive binary data with
SOAP.

Content
• Introduction
• Where Does MTOM Come In?
• MTOM with Axis2
• Programming Model
• Enabling MTOM Optimization at Client Side
• Enabling MTOM Optimization at Server Side
• Accessing Received Binary Data (Sample Code)
• Service
• Client
• MTOM Databinding
• Using ADB
• SOAP with Attachments with Axis2

169
• Sending SwA Type Attachments
• Receiving SwA Type Attachments
• MTOM Backward Compatibility with SwA
• Advanced Topics
• File Caching for Attachments

Introduction
Despite the flexibility, interoperability, and global acceptance of XML, there are times when
serializing data into XML does not make sense. Web services users may want to transmit
binary attachments of various sorts like images, drawings, XML docs, etc., together with a
SOAP message. Such data is often in a particular binary format.
Traditionally, two techniques have been used in dealing with opaque data in XML;
1. "By value"
Sending binary data by value is achieved by embedding opaque data (of course after
some form of encoding) as an element or attribute content of the XML component of
data. The main advantage of this technique is that it gives applications the ability to
process and describe data, based only on the XML component of the data.
XML supports opaque data as content through the use of either base64 or hexadecimal
text encoding. Both techniques bloat the size of the data. For UTF-8 underlying text
encoding, base64 encoding increases the size of the binary data by a factor of 1.33x of
the original size, while hexadecimal encoding expands data by a factor of 2x. The above
factors will be doubled if UTF-16 text encoding is used. Also of concern is the overhead
in processing costs (both real and perceived) for these formats, especially when
decoding back into raw binary.
2. "By reference"
Sending binary data by reference is achieved by attaching pure binary data as external
unparsed general entities outside the XML document and then embedding reference
URIs to those entities as elements or attribute values. This prevents the unnecessary
bloating of data and wasting of processing power. The primary obstacle for using these
unparsed entities is their heavy reliance on DTDs, which impedes modularity as well as
the use of XML namespaces.
There were several specifications introduced in the Web services world to deal with this
binary attachment problem using the "by reference" technique. SOAP with Attachments
is one such example. Since SOAP prohibits document type declarations (DTD) in
messages, this leads to the problem of not representing data as part of the message
infoset, therefore creating two data models. This scenario is like sending attachments
with an e-mail message. Even though those attachments are related to the message
content they are not inside the message. This causes the technologies that process and
describe the data based on the XML component of the data to malfunction. One
example is WS-Security.

Where Does MTOM Come In?


MTOM (SOAP Message Transmission Optimization Mechanism) is another specification that
focuses on solving the "Attachments" problem. MTOM tries to leverage the advantages of the
above two techniques by trying to merge the two techniques. MTOM is actually a "by
reference" method. The wire format of a MTOM optimized message is the same as the SOAP
with Attachments message, which also makes it backward compatible with SwA endpoints. The
most notable feature of MTOM is the use of the XOP:Include element, which is defined in the
XML Binary Optimized Packaging (XOP) specification to reference the binary attachments

170
(external unparsed general entities) of the message. With the use of this exclusive element,
the attached binary content logically becomes inline (by value) with the SOAP document even
though it is actually attached separately. This merges the two realms by making it possible to
work only with one data model. This allows the applications to process and describe by only
looking at the XML part, making the reliance on DTDs obsolete. On a lighter note, MTOM has
standardized the referencing mechanism of SwA. The following is an extract from the XOP
specification.
At the conceptual level, this binary data can be thought of as being base64-encoded in the
XML Document. As this conceptual form might be needed during some processing of the XML
document (e.g., for signing the XML document), it is necessary to have a one-to-one
correspondence between XML Infosets and XOP Packages. Therefore, the conceptual
representation of such binary data is as if it were base64-encoded, using the canonical lexical
form of the XML Schema base64Binary datatype (see [XML Schema Part 2: Datatypes Second
Edition] 3.2.16 base64Binary). In the reverse direction, XOP is capable of optimizing only
base64-encoded Infoset data that is in the canonical lexical form.
Apache Axis2 supports Base64 encoding, SOAP with Attachments and MTOM (SOAP
Message Transmission Optimization Mechanism).

MTOM with Axis2

Programming Model
AXIOM is (and may be the first) Object Model that has the ability to hold binary data. It has
this ability as OMText can hold raw binary content in the form of javax.activation.DataHandler.
OMText has been chosen for this purpose with two reasons. One is that XOP (MTOM) is capable
of optimizing only base64-encoded Infoset data that is in the canonical lexical form of XML
Schema base64Binary datatype. Other one is to preserve the infoset in both the sender and
receiver. (To store the binary content in the same kind of object regardless of whether it is
optimized or not).
MTOM allows to selectively encode portions of the message, which allows us to send
base64encoded data as well as externally attached raw binary data referenced by the "XOP"
element (optimized content) to be sent in a SOAP message. You can specify whether an
OMText node that contains raw binary data or base64encoded binary data is qualified to be
optimized at the time of construction of that node or later. For optimum efficiency of MTOM, a
user is advised to send smaller binary attachments using base64encoding (non-optimized) and
larger attachments as optimized content.

OMElement imageElement = fac.createOMElement("image", omNs);

// Creating the Data Handler for the file. Any implementation of


// javax.activation.DataSource interface can fit here.
javax.activation.DataHandler dataHandler = new
javax.activation.DataHandler(new FileDataSource("SomeFile"));

//create an OMText node with the above DataHandler


//and set optimized to true
OMText textData = imageElement.addChild(textData);

//User can set optimized to false by using the following


//textData.doOptimize(false);

Also, a user can create an optimizable binary content node using a base64 encoded string,
which contains encoded binary content, given with the MIME type of the actual binary
representation.

171
String base64String = "some_base64_encoded_string";
OMText binaryNode =

Axis2 uses javax.activation.DataHandler to handle the binary data. All the optimized binary
content nodes will be serialized as Base64 Strings if "MTOM is not enabled". You can also
create binary content nodes, which will not be optimized at any case. They will be serialized
and sent as Base64 Strings.

//create an OMText node with the above DataHandler and set "optimized"
to false
//This data will be send as Base64 encoded string
//regardless of MTOM is enabled or not
javax.activation.DataHandler dataHandler = new
javax.activation.DataHandler(new FileDataSource("SomeFile"));
OMText textData = fac.createOMText(dataHandler, );
image.addChild(textData);

Enabling MTOM Optimization on the Client Side


In Options, set the "enableMTOM" property to True when sending messages.

ServiceClient serviceClient = new ServiceClient ();


Options options = new Options();
options.setTo(targetEPR);
serviceClient .setOptions(options);

When this property is set to True, any SOAP envelope, regardless of whether it contains
optimizable content or not, will be serialized as an MTOM optimized MIME message.
Axis2 serializes all binary content nodes as Base64 encoded strings regardless of whether
they are qualified to be optimized or not
• if the "enableMTOM" property is set to False.
• if the envelope contains any element information items of the name xop:Include (see
[XML-binary Optimized Packaging] 3. XOP Infosets Constructs ).
The user does not have to specify anything in order for Axis2 to receive MTOM optimised
messages. Axis2 will automatically identify and de-serialize accordingly, as and when an MTOM
message arrives.

Enabling MTOM Optimization on the Server Side


The Axis 2 server automatically identifies incoming MTOM optimized messages based on the
content-type and de-serializes them accordingly. The user can enableMTOM on the server side
for outgoing messages,
To enableMTOM globally for all services, users can set the "enableMTOM" parameter to True
in the Axis2.xml. When it is set, all outgoing messages will be serialized and sent as MTOM
optimized MIME messages. If it is not set, all the binary data in the binary content nodes will
be serialized as Base64 encoded strings. This configuration can be overriden in services.xml on
the basis of per service and per operation.
● <parameter name="enableMTOM" locked="false">true</parameter>
You must restart the server after setting this parameter.

172
Accessing Received Binary Data (Sample Code)

Service
public class MTOMService {
public void uploadFileUsingMTOM(OMElement element) throws Exception {
... ...
}
}

Client

ServiceClient sender = new ServiceClient();


Options options = new Options();
options.setTo(targetEPR);
// enabling MTOM
............
OMElement result = sender.sendReceive(payload);
OMElement ele = result.getFirstElement();
OMText binaryNode = (OMText) ele.getFirstOMChild();

// Retrieving the DataHandler & then do whatever the processing to the


data
DataHandler actualDH;
actualDH = binaryNode.getDataHandler();
.............

MTOM Databinding
You can define a binary element in the schema using the schema type="xsd:base64Binary".
Having an element with the type "xsd:base64Binary" is enough for the Axis2 code generators
to identify possible MTOM attachments, and to generate code accordingly.
Going a little further, you can use the xmime schema
(http://www.w3.org/2005/05/xmlmime) to describe the binary content more precisely. With
the xmime schema, you can indicate the type of content in the element at runtime using an
MTOM attribute extension xmime:contentType. Furthermore, you can identify what type of
data might be expected in the element using the xmime:expectedContentType. Putting it all
together, our example element becomes:

<element name="MyBinaryData" xmime:expectedContentTypes='image/jpeg' >


<complexType>
<simpleContent>
<extension base="base64Binary" >
<attribute ref="xmime:contentType" use="required"/>
</extension>
</simpleContent>
</complexType>
</element>

You can also use the xmime:base64Binary type to express the above mentioned data much
clearly.

173
<element name="MyBinaryData"
xmime:expectedContentTypes='image/jpeg' type="xmime:base64Binary"/>

MTOM Databinding Using ADB


Let's define a full, validated doc/lit style WSDL that uses the xmime schema, has a service
that receives a file, and saves it in the server using the given path.

<wsdl:definitions xmlns:tns="http://ws.apache.org/axis2/mtomsample/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://ws.apache.org/axis2/mtomsample/">

<wsdl:types>
<xsd:schema xmlns="http://schemas.xmlsoap.org/wsdl/"
attributeFormDefault="qualified" elementFormDefault="qualified"
targetNamespace="http://ws.apache.org/axis2/mtomsample/">

<xsd:import namespace="http://www.w3.org/2005/05/xmlmime"
schemaLocation="http://www.w3.org/2005/05/xmlmime" />

<xsd:complexType name="AttachmentType">
<xsd:sequence>
<xsd:element minOccurs="0" name="fileName" type="xsd:string" />
<xsd:element minOccurs="0" name="binaryData" type="xmime:base64Binary"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="AttachmentRequest" type="tns:AttachmentType" />
<xsd:element name="AttachmentResponse" type="xsd:string" />
</xsd:schema>
</wsdl:types>

<wsdl:message name="AttachmentRequest">
<wsdl:part name="part1" element="tns:AttachmentRequest" />
</wsdl:message>
<wsdl:message name="AttachmentResponse">
<wsdl:part name="part1" element="tns:AttachmentResponse" />
</wsdl:message>
<wsdl:portType name="MTOMServicePortType">
<wsdl:operation name="attachment">
<wsdl:input message="tns:AttachmentRequest" wsaw:Action="attachment"
/>
<wsdl:output message="tns:AttachmentResponse"
wsaw:Action="http://schemas.xmlsoap.org/wsdl/MTOMServicePortType/Attachm
entResponse"/>
</wsdl:operation>
</wsdl:portType>

174
<wsdl:binding name="MTOMServiceSOAP11Binding"
type="tns:MTOMServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<wsdl:operation name="attachment">
<soap:operation soapAction="attachment" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="MTOMServiceSOAP12Binding"
type="tns:MTOMServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<wsdl:operation name="attachment">
<soap12:operation soapAction="attachment" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MTOMSample">
<wsdl:port name="MTOMSampleSOAP11port_http"
binding="tns:MTOMServiceSOAP11Binding">
<soap:address
location="http://localhost:8080/axis2/services/MTOMSample"/>
</wsdl:port>
<wsdl:port name="MTOMSampleSOAP12port_http"
binding="tns:MTOMServiceSOAP12Binding">
<soap12:address
location="http://localhost:8080/axis2/services/MTOMSample"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

The important point here is we import http://www.w3.org/2005/05/xmlmime and define the


element 'binaryData' that utilizes MTOM.
The next step is using the Axis2 tool 'WSDL2Java' to generate Java source files from this
WSDL. See the 'Code Generator Tool' guide for more information. Here, we define an Ant task
that chooses ADB (Axis2 Data Binding) as the databinding implementation. The name we list
for the WSDL above is MTOMSample.wsdl, and we define our package name for our generated
source files to 'sample.mtom.service' . Our Ant task for this example is:

175
<target name="generate.service">
<java classname="org.apache.axis2.wsdl.WSDL2Java">
<arg value="-uri" />
<arg value="${basedir}/resources/MTOMSample.wsdl" />
<arg value="-ss" />
<arg value="-sd" />
<arg value="-g"/>
<arg value="-p" />
<arg value="sample.mtom.service" />
<arg value="-o" />
<arg value="${service.dir}" />
<classpath refid="class.path" />
</java>
</target>

Now we are ready to code. Let's edit


output/src/sample/mtom/service/MTOMSampleSkeleton.java and fill in the business logic. Here
is an example:

public org.apache.ws.axis2.mtomsample.AttachmentResponse attachment(


org.apache.ws.axis2.mtomsample.AttachmentRequest param0) throws
Exception {
AttachmentType attachmentRequest = param0.getAttachmentRequest();
Base64Binary binaryData = attachmentRequest.getBinaryData();
DataHandler dataHandler = binaryData.getBase64Binary();
File file = new File(attachmentRequest.getFileName());
FileOutputStream fileOutputStream = new FileOutputStream(file);
dataHandler.writeTo(fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();

AttachmentResponse response = new AttachmentResponse();


response.setAttachmentResponse("File saved succesfully.");
return response;
}

The code above receives a file and writes it to the disk using the given file name. It returns
a message once it is successful. Now let's define the client:

176
public static void transferFile(File file, String destination)
throws RemoteException {
MTOMSampleStub serviceStub = new MTOMSampleStub();

// Enable MTOM in the client side


serviceStub._getServiceClient().getOptions().setProperty(
Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);

//Increase the time out when sending large attachments


serviceStub._getServiceClient().getOptions().setTimeOutInMilliSeconds(
10000);

// Populating the code generated beans


AttachmentRequest attachmentRequest = new AttachmentRequest();
AttachmentType attachmentType = new AttachmentType();
Base64Binary base64Binary = new Base64Binary();

// Creating a javax.activation.FileDataSource from the input file.


FileDataSource fileDataSource = new FileDataSource(file);

// Create a dataHandler using the fileDataSource. Any implementation of


// javax.activation.DataSource interface can fit here.
DataHandler dataHandler = new DataHandler(fileDataSource);
base64Binary.setBase64Binary(dataHandler);
base64Binary.setContentType(dataHandler.getContentType());
attachmentType.setBinaryData(base64Binary);
attachmentType.setFileName(destination);
attachmentRequest.setAttachmentRequest(attachmentType);

AttachmentResponse response =
serviceStub.attachment(attachmentRequest);
System.out.println(response.getAttachmentResponse());
}

The last step is to create an AAR with our Skeleton and the services.xml and then deploy
the service. You can find the completed sample in the Axis2 standard binary distribution under
the samples/mtom directory

SOAP with Attachments (SwA) with Axis2

Receiving SwA Type Attachments


Axis2 automatically identifies SwA messages based on the content type. Axis2 stores the
references on the received attachment parts (MIME parts) in the Message Context. Axis2
preserves the order of the received attachments when storing them in the MessageContext.
Users can access binary attachments using the attachement API given in the Message Context
using the content-id of the mime part as the key. Care needs be taken to rip off the "cid" prefix
when content-id is taken from the "Href" attributes. Users can access the message context
from whithin a service implementation class using the "setOperationContext()" method as
shown in the following example.
Note: Axis2 supports content-id based referencing only. Axis2 does not support Content
Location based referencing of MIME parts.
• Sample service which accesses a received SwA type attachment

177
public class SwA {
public SwA() {
}

public void uploadAttachment(OMElement omEle) throws AxisFault {


OMElement child = (OMElement) omEle.getFirstOMChild();
OMAttribute attr = child.getAttribute(new QName("href"));

//Content ID processing
String contentID = attr.getAttributeValue();
contentID = contentID.trim();
if (contentID.substring(0, 3).equalsIgnoreCase("cid")) {
contentID = contentID.substring(4);
}

MessageContext msgCtx =
MessageContext.getCurrentMessageContext();
Attachments attachment = msgCtx.getAttachmentMap();
DataHandler dataHandler = attachment.getDataHandler(contentID);
...........
}
}

Sending SwA Type Attachments


The user needs to set the "enableSwA" property to True in order to be able to send SwA
messages. The Axis2 user is not expected to enable MTOM and SwA together. In such a
situation, MTOM will get priority over SwA.
This can be set using the axis2.xml as follows.
● <parameter name="enableSwA" locked="false">true</parameter>
"enableSwA" can also be set using the client side Options as follows
● options.setProperty(Constants.Configuration.ENABLE_SwA,
Constants.VALUE_TRUE);
Users are expected to use the attachment API provided in the MessageContext to specify
the binary attachments needed to be attached to the outgoing message as SwA type
attachments. Client side SwA capability can be used only with the OperationClient api, since
the user needs the ability to access the MessageContext.
• Sample client which sends a message with SwA type attachments

public void uploadFileUsingSwA(String fileName) throws Exception {

Options options = new Options();


options.setTo(targetEPR);
options.setProperty(Constants.Configuration.ENABLE_SWA,
Constants.VALUE_TRUE);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI
);
options.setTo(targetEPR);

ServiceClient sender = new ServiceClient(null,null);


sender.setOptions(options);
OperationClient mepClient =
sender.createClient(ServiceClient.ANON_OUT_IN_OP);

178
MessageContext mc = new MessageContext();
mc.setEnvelope(createEnvelope());
FileDataSource fileDataSource = new FileDataSource("test-
resources/mtom/test.jpg");
DataHandler dataHandler = new DataHandler(fileDataSource);
mc.addAttachment("FirstAttachment",dataHandler);

mepClient.addMessageContext(mc);
mepClient.execute(true);
}

MTOM Backward Compatibility with SwA


MTOM specification is designed to be backward compatible with the SOAP with Attachments
specification. Even though the representation is different, both technologies have the same
wire format. We can safely assume that any SOAP with Attachments endpoint can accept
MTOM optimized messages and treat them as SOAP with Attachment messages - any MTOM
optimized message is a valid SwA message.
Note : Above backword compatibility was succesfully tested against Axis 1.x
• A sample SwA message from Axis 1.x

Content-Type: multipart/related; type="text/xml";


start="<9D645C8EBB837CE54ABD027A3659535D>";
boundary="----=_Part_0_1977511.1123163571138"

------=_Part_0_1977511.1123163571138
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <9D645C8EBB837CE54ABD027A3659535D>

<?xml version="1.0" encoding="UTF-8"?>


<soapenv:Envelope xmlns:soapenv="...."....>
........
<source href="cid:3936AE19FBED55AE4620B81C73BDD76E" xmlns="/>

........
</soapenv:Envelope>
------=_Part_0_1977511.1123163571138
Content-Type: text/plain
Content-Transfer-Encoding: binary
Content-Id: <3936AE19FBED55AE4620B81C73BDD76E>

Binary Data.....
------=_Part_0_1977511.1123163571138--

• Corresponding MTOM message from Axis2

179
Content-Type: multipart/related;
boundary=MIMEBoundary4A7AE55984E7438034;
type="application/xop+xml";
start="<0.09BC7F4BE2E4D3EF1B@apache.org>";
start-info="text/xml; charset=utf-8"

--MIMEBoundary4A7AE55984E7438034
content-type: application/xop+xml; charset=utf-8;
type="application/soap+xml;"
content-transfer-encoding: binary
content-id: <0.09BC7F4BE2E4D3EF1B@apache.org>

<?xml version='1.0' encoding='utf-8'?>


<soapenv:Envelope xmlns:soapenv="...."....>
........
<xop:Include href="cid:1.A91D6D2E3D7AC4D580@apache.org"
xmlns:xop="http://www.w3.org/2004/08/xop/include">
</xop:Include>
........

</soapenv:Envelope>
--MIMEBoundary4A7AE55984E7438034
content-type: application/octet-stream
content-transfer-encoding: binary
content-id: <1.A91D6D2E3D7AC4D580@apache.org>

Binary Data.....
--MIMEBoundary4A7AE55984E7438034--

Advanced Topics

File Caching for Attachments


Axis2 comes handy with a file caching mechanism for incoming attachments, which gives
Axis2 the ability to handle very large attachments without buffering them in the memory at
any time. Axis2 file caching streams the incoming MIME parts directly into the files, after
reading the MIME part headers.
Also, a user can specify a size threshold for the File caching (in bytes). When this threshold
value is specified, only the attachments whose size is bigger than the threshold value will get
cached in the files. Smaller attachments will remain in the memory.
Note : It is a must to specify a directory to temporarily store the attachments. Also care
should be taken to clean that directory from time to time.
The following parameters need to be set in Axis2.xml in order to enable file caching.

<axisconfig name="AxisJava2.0">
<!-- Parameters -->
<parameter name="cacheAttachments" locked="false">true</parameter>
<parameter name="attachmentDIR" locked="false">temp
directory</parameter>

<parameter name="sizeThreshold" locked="false">4000</parameter>


.........
.........
</axisconfig>

180
Enabling file caching for client side receiving can be done for the by setting the Options as
follows.

options.setProperty(Constants.Configuration.CACHE_ATTACHMENTS,Constants.
VALUE_TRUE);
options.setProperty(Constants.Configuration.ATTACHMENT_TEMP_DIR,TempDir)
;
options.setProperty(Constants.Configuration.FILE_SIZE_THRESHOLD,
"4000");

Transports
HTTP Transport
This document is all about HTTP sender and HTTP receiver, and how they work in Axis2.
Send your feedback or questions to: axis-dev@ws.apache.org. (Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

Content
• CommonsHTTPTransportSender
• HTTPS support
• Timeout Configuration
• HTTP Version Configuration
• Proxy Authentication
• Basic,Digest and NTLM Authentication

CommonsHTTPTransportSender
This is the default transport sender that is used in Server API as well as Client API. As the
name implies, it is based on commons-httpclient-3.0.1. In order to acquire the maximum
flexibility, this sender has implemented POST interface and GET interface. GET and HTTP
interfaces are also involved in Axis2 REST support.
Chunking and KeepAlive support is also integrated via the facilities provided by commons-
httpclient along with HTTP 1.1 support.
<transportSender/> element is used to define transport senders in the axis2.xml as follows:

<transportSender name="http"
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
</transportSender>

The above code snippet shows the simplest configuration of a transport sender for common
use. <parameter/> element introduces the additional parameters that should be compliant
with the sender. HTTP PROTOCOL version sets as HTTP/1.0 or HTTP/1.1. The default version is
HTTP/1.1. It should be noted that chunking support is available only for HTTP/1.1. Thus, even
if the user turns on "chunking", if the HTTP version is 1.0, this setting will be ignored by the
transport framework. KeepAlive is a default property in version 1.1.

181
Some absolute properties are provided at runtime, such as character encoding style (UTF-8,
UTF-16 etc) is provided via MessageContext.

HTTPS support
It should be noted that CommonsHTTPTransportSender can be used to communicate over
https.

<transportSender name=""
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
<parameter name="Transfer-Encoding">chunked</parameter>
</transportSender>

Please note that HTTPS works only when the server does not expect to authenticate the
clients and where the server has the clients' public keys in its trust store.

Timeout Configuration
Two timeout instances exist in the transport level. They are called, Socket timeout and
Connection timeout. This can be configured at deployment time or run time. At the time of
deployment, the user has to add the following lines in axis2.xml.
For Socket timeout:
<parameter name="SO_TIMEOUT" locked="false">some_int_value</parameter>
For Connection timeout:
<parameter name="CONNECTION_TIMEOUT" locked="false">some_int_value</parameter>
At runtime, it is set as follows in the Stub.

...
Options options = new Options();
options.setProperty(HTTPConstants.SO_TIMEOUT,new
Integer(timeOutInMilliSeconds));
options.setProperty(HTTPConstants.CONNECTION_TIMEOUT,new
Integer(timeOutInMilliSeconds));

// or
options.setTimeOutInMilliSeconds(timeOutInMilliSeconds);
...

HTTP Version Configuration


The default HTTP version is 1.1. There are two methods in which the user can change the
HTTP version to 1.0
1. By defining the version in axis2.xml as shown below.
<parameter name="PROTOCOL" locked="false">HTTP/1.0</parameter>
2. Or the user can change the version at runtime by doing the following
...
options.setProperty(org.apache.axis2.context.MessageContextConstants.HTTP_
PROTOCOL_VERSION,org.apache.axis2.transport.http.HTTPConstants.HEADER_PROT
OCOL_10);
...

182
Proxy Authentication
The Commons-http client has the inbuilt ability to support proxy authentication. Axis2 uses
deployment time and runtime mechanisms to authenticate proxies. At deployment time, the
user has to change the axis2.xml as follows. This authentication will be available in HTTP and
HTTPS.

<transportSender name=""
class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
<parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
<parameter name="PROXY" proxy_host="proxy_host_name"
proxy_port="proxy_host_port"
locked="true>userName:domain:passWord</parameter>
</transportSender>

For a particular proxy, if authentication is not available, enter thel


"userName:domain:passWord"as "anonymous:anonymous:anonymous".
At runtime, the user can override the PROXY settings with an Object of
HttpTransportProperties.ProxyProperties. On the stub, initiate an object of the prior setting and
set it to the MessageContext's property bag via HttpConstants.PROXY. On the stub, it depicts
as follows,

...
Options options = new Options();
....

HttpTransportProperties.ProxyProperties proxyProperties = new


HttpTransportProperties.new ProxyProperties();
proxyProperties.setProxyHostName(....);
proxyProperties.setProxyPort(...);
...
options.setProperty(HttpConstants.PROXY, proxyProperties);
....

The above code would eventually override the deployment proxy configuration settings.

Basic, Digest and NTLM Authentication


HttpClient supports three different types of HTTP authentication schemes: Basic, Digest and
NTLM. Based on the challenge provided by the server, httpclient automatically selects the
authentication scheme with which the request should be authenticated.. The most secure will
be NTLM and the least secure will be Basic.
NTLM is the most complex of the authentication protocols supported by HttpClient. It
requires an instance of NTCredentials to be available for the domain name of the server or the
default credentials. Note that since NTLM does not use the notion of realms, HttpClient uses
the domain name of the server as the name of the realm. Also note that the username
provided to the NTCredentials should not be prefixed with the domain - ie: "axis2" is correct
whereas "DOMAIN\axis2" is not correct.
There are some significant differences in the way that NTLM works compared with basic and
digest authentication. These differences are generally handled by HttpClient, however having
an understanding of these differences can help avoid problems when using NTLM
authentication.
1. NTLM authentication works almost exactly the same way as any other form of
authentication in terms of the HttpClient API. The only difference is that you need to

183
supply 'NTCredentials' instead of 'UsernamePasswordCredentials' (NTCredentials
actually extends UsernamePasswordCredentials so you can use NTCredentials right
throughout your application if need be).
2. The realm for NTLM authentication is the domain name of the computer to which you
are being connected. This can be troublesome as servers often have multiple domain
names that refer to them. Only the domain name that the HttpClient connects to (as
specified by the HostConfiguration) is used to look up the credentials. It is generally
advised that while initially testing NTLM authentication, you pass the realm as null,
which is used by default.
3. NTLM authenticates a connection and not a request. So you need to authenticate
every time a new connection is made, and keeping the connection open during
authentication is vital. Due to this, NTLM cannot be used to authenticate with both a
proxy and the server, nor can NTLM be used with HTTP 1.0 connections or servers that
do not support HTTP keep-alives.
Axis2 also allows to add a custom Authentication Scheme to httpclient.
The static inner bean Authenticator of HttpTransportProperties will hold the state of the
server to be authenticated with. Once filled, it has to be set to the Options's property bag with
the key as HTTPConstants.AUTHENTICATE. The following code snippet shows the way of
configuring the transport framework to use Basic Authentication:

...
Options options = new Options();

HttpTransportProperties.Authenticator auth = new


HttpTransportProperties.Authenticator();
auth.setUsername("username");
auth.setPassword("password");
// set if realm or domain is know

options.setProperty(org.apache.axis2.transport.http.HTTPConstants.BASIC
_AUTHENTICATE,auth);
...

JMS Transport
This document is all about the JMS (Java Messaging Service) Transport support in Apache
Axis2,, and how it should be configured.
Send your feedback or questions to: axis-dev@ws.apache.org. (Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

Contents
• Overview
• Configuration
• Writing Services to Use the JMS Transport

Overview
A new Java Messaging Service (JMS) transport implementation has been added to Axis2 to
overcome some drawbacks of the previous JMS implementation. One of the enhancements
provided with this new implementation is the ability to assign custom JMS destination
names or existing JMS destinations to Axis2 services being deployed.

184
Configuration
To use the JMS transport, the axis2.xml configuration must be setup as follows, in order to
configure the JMSListener and the JMS Sender

<transportReceiver name="jms"
class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</parameter>
<parameter name="java.naming.provider.url" locked="false">
tcp://localhost:61616
</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName"
locked="false">
QueueConnectionFactory
</parameter>
</parameter>
</transportReceiver>

<transportSender name="jms"
class="org.apache.axis2.transport.jms.JMSSender"/>

The JMS transport receiver configuration allows you to define the default connection factory
(named as "default" ~ JMSConstants.DEFAULT_CONFAC_NAME) for use by Axis2 services using
the JMS transport. This connection factory will be used by any service that does not explicitly
specify a connection factory name in its services.xml file. The configuration required to
associate a (local) Axis2 connection factory to an actual implementation must be provided as
shown above. To specify the JNDI URL, the initial context factory class and the JNDI name of
the actual JMS connection factory is used. You can also specify the parameters
"java.naming.security.principal" and "java.naming.security.credentials", if required, to access
the actual connection factory. The example shown above uses an ActiveMQ JMS
implementation.

<parameter name="myTopicConnectionFactory" locked="false">


<parameter name="java.naming.factory.initial" locked="false">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</parameter>
<parameter name="java.naming.provider.url" locked="false">
tcp://localhost:61616
</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName"
locked="false">
TopicConnectionFactory
</parameter>
</parameter>

If it is required or applicable, you are free to define additional (local) connection factories to
Axis2 as shown above, which your services can use. For a service to specify that such a
connection factory should be used, its services.xml may specify the following configuration
parameter:

services.xml
<parameter name="transport.jms.ConnectionFactory"
locked="true">myTopicConnectionFactory</parameter>

185
Note: Depending on your JMS implementation, you will need to make available all the
required libraries for your Axis2 instance. This example assumes you are using an ActiveMQ
instance. To run the given code samples, it is required to make the following JAR files
available: activeio-core-3.0-beta1.jar, activemq-core-4.0-RC2.jar, geronimo-j2ee-
management_1.0_spec-1.0.jar at a minimum. It also requires you to start ActiveMQ separately
from Axis2, and then provide the appropriate configuration settings (e.g. URL) to Axis2.
During initialization, the JMS Listener creates a dedicated JMS message processor for each
connection factory defined, and utilizes a shared thread pool to process the received
messages.
A service on an Axis2 instance is deployed on all the started transports by default, unless a
list of transports is specified in its services.xml file. Hence, if a service must only be deployed
on JMS, you should specify it on the services.xml as follows:

<transports>
<transport>jms</transport>
</transports>

If the services.xml does not provide an explicit JMS destination name, it is assumed that the
service will listen for messages on a JMS Queue by the same name as the name of the
service. If an explicit connection factory definition name has not been specified, it is assumed
that the "default" connection factory definition configured within the transport receiver is used.
To provide a custom JMS destination name and connection factory, the services.xml file
provides the following optional parameters.

<parameter name="transport.jms.ConnectionFactory"
locked="true">myTopicConnectionFactory</parameter>
<parameter name="transport.jms.Destination"
locked="true">dynamicTopics/something.TestTopic</parameter>

Writing Services to Use the JMS Transport


This section assumes that you are already familiar with writing service implementations for
Axis2, and provides information on how to write your own service implementations, which are
exposed over JMS.

Echo - Service implementation and services.xml


This sample demonstrates a very simple service which is to be exposed over JMS. It does
not specify a custom connection factory name, and hence uses the default value as specified in
the JMS transport listener configuration. It also does not specify a custom destination name,
and hence would listen to messages over a JMS Queue named "Echo" (which is the name of
the service). This service will be exposed over all defined Axis2 transports, and the resulting
URL for the service over JMS will be:
jms:/echo?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.nami
ng.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provid
er.url=tcp://localhost:61616

186
public class Echo {
public String echoString(String in) {
return in;
}
public String echoString1(String in) {
return "echoString1 " + in;
}
public String echoString2(String in) {
return "echoString2 " + in;
}
}

<service name="echo">
<description>Echo Service</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="true">Echo</parameter>
</service>

Echo2 - Service implementation and services.xml


This example shows a simple service which specifies that it should only be exposed over the
JMS transport, and that the custom connection factory named "myTopcConnectionFactory"
should be used to listen for requests at the JMS destination named
"dynamicTopics/something.TestTopic". The JMS URL to access this service is:
jms:/dynamicTopics/something.TestTopic?transport.jms.ConnectionFactoryJNDIName=Topic
ConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContex
tFactory&java.naming.provider.url=tcp://localhost:61616&java.naming.security.principal=syste
m&java.naming.security.credentials=manager

public class Echo2 {


public String echoString(String in) { return in; }
}

<service name="echo">
<transports>
<transport>jms</transport>
</transports>
<description>Echo2 Service</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="true">Echo2</parameter>
<parameter name="transport.jms.ConnectionFactory"
locked="true">myTopicConnectionFactory</parameter>
<parameter name="transport.jms.Destination"
locked="true">dynamicTopics/something.TestTopic</parameter>
</service>

187
Starting up the Axis2 JMS transport
The Axis2 standalone binary distribution ships with an Axis2 Server, which starts up all the
transports that are configured as per the axis2.xml. Hence, configure the JMS transport in your
axis2.xml, and use the axis2server.bat or the axis2server.sh to start the JMS transport.

TCP Transport
This document explains how to send and receive SOAP messages via TCP in Axis2.
Send your feedback or questions to: axis-dev@ws.apache.org. Prefix subject with [Axis2].
Subscription details are available on the Axis2 site.

Content
• Introduction
• How to Start the TCPServer
• How to Send SOAP Messages Using TCP Transport
• Samples
• Transport Components

Introduction
Axis2 supports TCP as a transport. It supports both sending and receiving SOAP messages
via TCP. A TCP transport does not have any application level headers and the SOAP message
that is sent should be self-contained. This makes the interaction fast and simple. However,
since there are no application headers, it does not have the privilege of having a request URI,
and Service dispatching should be done by an alternative method. Thus,
RequestURIBasedDispatcher cannot be used. The following are the two main alternatives
available for dispatching in the Axis2 environment:
1. Use the name space URI of the first child element of SOAPBody.
(SOAPMessageBodyBasedDispatcher).
2. Enable WS-Addressing. In the case of version 1.1 and 1.1.1 releases Addressing is
default (SOAPActionBasedDispatcher).
When the TCP request is sent, it is the user's responsibility to use either Addressing or the
SOAP body base mechanism.

How to Start the TCPServer


The TCP server can be started by running the class
org.apache.axis2.transport.tcp.TCPServer with two parameters - repository and port number,
as arguments. This class needs all the Axis dependency JARs in the classpath. New services
can be added in the usual way by dropping the archives to the repository (See Advanced
User's Guide for more information)

How to Send SOAP Messages Using TCP Transport


TCP transport can be enabled easily from the call API. The following code segment
demonstrates how this can be done.

188
OMElement payload = ...
ServiceClient serviceClient = new ServiceClient();
Options options = new Options();
options.setTo(targetEPR);
serviceClient.setOptions(options);
OMElement response = serviceClient.sendReceive(payload);

The transport that should be invoked is inferred from the targetEPR (tcp://...). In this case
it is TCP and the listener is also TCP. The SOAP message has to be self contained in order to
use Addressing. The other option is to use the URI of the first child of the SOAP Body to
dispatch the service. The parameter is of the type OMElement, the XML representation of
Axis2.

Samples
A sample for a TCP Client can be found from the
samples/userguide/src/userguide/clients/TCPClient.java in the binary distribution. This
accesses the same Web service explained in the Axis2 Advanced User's Guide. The client first
starts the TCPServer with the same repository used for the Axis2 Advanced User's Guide
samples. Since the sample is already deployed in the repository, as per the userguide, it will be
automatically available.
In order to run the TCPClient.java, addressing should be engaged both in the client and
server sides. On the client side, you can engage addressing by copying the addressing-1.2.mar
(AXIS2_HOME/repository/module) to AXIS2_HOME/lib directory.

Transport Components
The Axis2 TCP transport has two components, a transport Listener for receiving the
messages and a transport Sender to send the SOAP Messages. The Axis2 installation has both
the components built into itself by default. In the axis2.xml configuration file, the two TCP
transport components can be configured as shown below.
The following XML lines initialize the TCPTransport Receiver:

<transportReceiver name="tcp"
class="org.apache.axis2.transport.tcp.TCPServer">
<parameter name="port" locked="false">6060</parameter>
</transportReceiver>

The following XML lines add the TCPTransport Sender:

<transportSender name="tcp"
class="org.apache.axis2.transport.tcp.TCPTransportSender"/>

Note: If the TCP server is started manually, this configuration does not take effect. In
return, this affects the transport Listener's start by Axis2. (e.g. Listener started by the
Complete Async interaction)

Mail Transport

Invoking a Service Using a Mail Transport


This document explains how to invoke a service through Mail transports.

189
Send your feedback or questions to: axis-dev@ws.apache.org. (Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

Content
• Prologue
• Introduction
• Using Simple Mail Server Included in Axis2
• Using a Generic Mail Server

Prologue
Most of the Web services that we interact with are synchronous and request-response in
nature. However, we see that the synchronous request-response type of interaction is only a
part of the messaging scenarios we encounter in real life. Asynchronous messaging is very
important in constructing loosely coupled systems. Take for instance a chain of stores. At the
end of the day, all the stores can send a mail to the central system telling it about that day's
business activities, and when the store opens in the morning, there will be a reply to that mail
with new instructions and updates. It is a lot like the way old businesses worked, but with a
modern touch. Similarly, the Axis2 mail transport can be used to implement asynchronous
messaging through mail.

Introduction
First, you need to go through the Mail Transport Configuration document. It provides first
hand experience in setting up the mail transports to operate with Axis2.
Broadly speaking, there are three ways of calling a service through mail.
1. Using the simple mail server included in Axis2 (not recommended in production).
2. Using a generic mail server.
3. Using mailets.
Options 1 and 2 are fairly simple and easy to implement, whereas option 3 is somewhat
harder. The mailet scenario however does provide a more robust and useful solution in a
production environment.
It is very easy to start learning the workings of mail transports with the aid of the Simple
Mail Server that is provided with Axis2. Once you get the hang of Axis2 related issues, then
you can move on to tackle the mail beast. Please do note that the Simple Mail Server provided
with Axis2 is not graded for production use.

1. Using the Simple Mail Server Included in Axis2


The SMTP/POP server that we have included has the ability to function as a standalone
SMTP/POP server and also has the ability to work as a mailet. All this is done through a small
filter that keeps watch for certain pre-configured email addresses. These pre-configured email
addresses can be changed by doing a simple edit of the filter class
org.apache.axis2.transport.mail.server.Sorter.
Now that we have the environment set up, we can use the code below to get the mail
functionality started. First we'll have a look at it from the mail server side.

190
// Start the mail server using the default configurations.
ConfigurationContext configContext = UtilsMailServer.start();

// Start the default mail listener. It will starting polling for mail
// using the configuration from the XML file.
SimpleMailListener ml = new SimpleMailListener();
ml.init(configContext,
configContext.getAxisConfiguration().getTransportIn(new
QName(Constants.TRANSPORT_MAIL)));
ml.start();

private QName serviceName = new QName("EchoXMLService");


private QName operationName = new QName("echoOMElement");

// Setup a service that will echo what we send to the server.


AxisService service = Utils.createSimpleService(serviceName,
Echo.class.getName(), operationName);
serverConfigContext.getAxisConfiguration().addService(service);

This code sets up your Axis2 server which uses a single service to work through the mail. If
you want to have a look under the hood, check out the MailServer and UtilsMailServer classes.
Moving onto the client side, have a look at the code listing below. It will call the axisService
that was setup in the previous code listing.

ConfigurationContext configContext =
UtilsMailServer.createClientConfigurationContext();
AxisService service = new AxisService(serviceName.getLocalPart());
AxisOperation axisOperation = new OutInAxisOperation();
axisOperation.setName(operationName);
axisOperation.setMessageReceiver(new MessageReceiver() {
public void receive(MessageContext messageCtx) {
envelope = messageCtx.getEnvelope();
}
Callback
}); callback = new Callback() {
public void onComplete(AsyncResult result) {
service.addOperation(axisOperation);
try {
configContext.getAxisConfiguration().addService(service);
result.getResponseEnvelope().serializeAndConsume(XMLOutputFactory.
ServiceContext serviceContext = new ServiceGroupContext(configContext,
newInstance().createXMLStreamWriter(System.out));
(AxisServiceGroup) service.getParent()).getServiceContext(service);
} catch (XMLStreamException e) {
onError(e);
Options options = new Options();
} finally {
options.setTo(targetEPR);
finish = true;
options.setAction(operationName.getLocalPart());
}
options.setTransportInProtocol(Constants.TRANSPORT_MAIL);
}
options.setUseSeparateListener(true);
public void onError(Exception e) {
log.info(e.getMessage());
finish = true;
}
};

ServiceClient sender = new ServiceClient(configContext, service);


sender.setOptions(options);
//options.setTo(targetEPR);
sender.sendReceiveNonBlocking(operationName,createEnvelope(), callback);

int index = 0;
while (!finish) {
Thread.sleep(1000);
index++;
if (index > 10) {
throw new AxisFault("Server was 191
shutdown as the async response is
taking too long to complete.");
}
}
}
This will call the service that was setup on the server, and will poll the mail server until the
response is received. Please note that the serviceName and operationName need to be
QNames.

2. Using a Generic Mail Server


First you will need two email accounts that work with POP/SMTP. One will act as a server
and the other will act as the client. For the time being, we will use server@somewhere.org and
client@somewhere.org as the server and the client email addresses. Now that we have the
email addresses, you will have to set up the client and the server using the Mail Transport
configuration document.
When you call the generic mail server, the client side code will remain the same and there
will be some modification to the server-side code.

// Create a configuration context. This will also load the details


// about the mail address to listen to from the configuration file.
File file = new File(MAIL_TRANSPORT_SERVER_ENABLED_REPO_PATH);
ConfigurationContextFactory builder = new ConfigurationContextFactory();
ConfigurationContext configContext =
configContextbuilder.buildConfigurationContext(file.getAbsolutePath());

// Start the default mail listener. It will starting poling for mail
// using the configuration from the XML file.
SimpleMailListener ml = new SimpleMailListener();
ml.init(configContext,
configContext.getAxisConfiguration().getTransportIn(new
QName(Constants.TRANSPORT_MAIL)));
ml.start();

private QName serviceName = new QName("EchoXMLService");


private QName operationName = new QName("echoOMElement");

// Setup a service that will echo what we send to the server.


AxisService service = Utils.createSimpleService(serviceName,
Echo.class.getName(), operationName);
serverConfigContext.getAxisConfiguration().addService(service);

Note that a separate ConfigurationContext needs to be created and used.

Resources
For more information on Mail client invocation, see
AXIS2_HOME\samples\userguide\src\userguide\clients\MailClient.java

Mail Transport Configuration


This document provides guidelines on how to configure Axis2 in order to get the mail
transport working.
Send your feedback or questions to: axis-dev@ws.apache.org. (Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

192
Content
• Introduction
• Transport Sender
• Transport Receiver
• Using Mail Transport in the Server Side
• Configure James as SMTP and POP Server
• Using the Included Mail Server

Introduction
The inner workings of the mail transport has been divided into two parts: the transport
sender for SMTP and the transport listener for POP3. The transport listener will listen to a
particular email address periodically. When an email comes in, it will be tunneled into an Axis2
engine. On the other hand, the mail transport sender sends emails to a mail server to a
particular email address.
Mail transport can be used against a generic mail server or it can be used like a mailet. The
simple mailet provided with Axis2 directs any message that comes in to a particular address
into the Axis engine. The engine will process the message and use the Transport sender to
send the reply.
The mail transports have been written with the use of Sun's JavaMail and Activation jars.
They should be available in your classpath to get the mail transport to work.

Transport Sender
You need to have a mail account to activate the mail functionality. This can either be a
generic mail server or you can start up a James mail server.
JavaMail sets its properties to a Properties object. In Axis2, this has been mapped to a
Parameter object. Mapping has been done as follows,
• Every JavaMail property can be set to @name of the <parameter/>. Thus, an SSL
connection is mapped the way it is done in JavaMail
• Few properties, such as password,, are set to @name with the prefix "transport"
For a non-SSL connection, as an example, the mail transport sender can be activated by
adding the following entry to the axis2.xml file.

<transportSender name="mail"
class="org.apache.axis2.transport.mail.MailTransportSender">
<parameter name="mail.smtp.host"
locked="false">localhost</parameter>
<parameter name="mail.smtp.user" locked="false">mary</parameter>
<parameter name="transport.mail.smtp.password"
locked="false">mary</parameter>
</transportSender>

At runtime, tuning a client to set the mail transport is as easy as follows,

193
...

Options options = new Options();


HttpTransportProperties.MailProperties mailProps
= new HttpTransportProperties.MailProperties();
mailProps.addProperty("mail.smtp.host","localhost");
mailProps.addProperty("mail.smtp.user","mary");
mailProps.setPassword("mary");

options.setProperty(HTTPConstants.MAIL_SMTP,mailProps);

...

Thus, a user who is familiar with setting up an SSL connection, should easily do it with the
MailProperties object. For example, tuning the sender to talk to the gmail account. This
configuration should also be done with <parameter/> in axis2.xml.

HttpTransportProperties.MailProperties props = new


HttpTransportProperties.MailProperties();
props.put("mail.smtp.user", "address@gmail.com");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.auth", "true");
//props.put("mail.smtp.debug", "true"); // if the user wants
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
props.setPassword("password");

Transport Receiver
For a non-SSL connection, as an example, the mail Listener can be activated by adding the
following entry to the axis2.xml file.

<transportReceiver name="mail"
class="org.apache.axis2.transport.mail.SimpleMailListener">
<parameter name="mail.pop3.host"
locked="false">localhost</parameter>
<parameter name="mail.pop3.user" locked="false">bob</parameter>
<parameter name="transport.mail.pop3.password"
locked="false">bob</parameter>
<parameter name="transport.mail.replyToAddress"
locked="false">bob@localhost</parameter>
</transportReceiver>

Note: The @name="transport.mail.replyToAddress" is an important parameter. It supplies


the Endpoint reference to the listener.
For an advanced user, this can be set to an SSL connection. For example, let's use this
transport listener to pop from a specified gmail account.

194
<transportReceiver name="mail"
class="org.apache.axis2.transport.mail.SimpleMailListener">
<parameter name="mail.pop3.host"
locked="false">pop.gmail.com</parameter>
<parameter name="mail.pop3.user"
locked="false">address@gmail.com</parameter>
<parameter name="mail.pop3.socketFactory.class"
locked="false">javax.net.ssl.SSLSocketFactory</parameter>
<parameter name="mail.pop3.socketFactory.fallback"
locked="false">false</parameter>
<parameter name="mail.pop3.port" locked="false">995</parameter>
<parameter name="mail.pop3.socketFactory.port"
locked="false">995</parameter>
<parameter name="transport.mail.pop3.password"
locked="false">password</parameter>
<parameter name="transport.mail.replyToAddress"
locked="false">address@gmail.com</parameter>
</transportReceiver>

Using Mail Transport in the Server Side


If the Mail Listener is to be started as a standalone mail listener, it can be done with the
following command with the all the Axis2 jars and the mail dependency jars in the classpath.
java org.apache.axis2.transport.mail.SimpleMailListener repository-directory

Using Mail Transport in the Client Side


The following code segment shows how to send a one-way (IN-Only MEP) SOAP message
using the mail transport. This needs the Transport Sender to be configured.

OMElement payload = ....


String targetEPR = "mail:axis2@localhost/axis2/services/Foo";

ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(rep
o, axis2XML);

ServiceClient servicClient = new ServiceClient(configurationContext,


null);

Options options = new Options();


options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_MAIL);

servicClient.setOptions(options);

servicClient.sendRobust(payload);

Configure James as SMTP and POP Server


Download Apache James and start James. Connect to the James server via Telnet as
administrator James using the following code:

195
$telnet 127.0.0.1 4555
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
JAMES Remote Administration Tool 2.2.0
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands

Add users to James

adduser axis2-server axis2


User axis2-server added
adduser axis2-client axis2
User axis2-client added
Connection closed by foreign host.

Now James is up and running with the accounts.

Using the Included Mail Server


The inbuilt mail server can be started from the command line using the following command
when all the necessary JARS are in the class path.
java org.apache.axis2.transport.mail.server.MailServer
The server itself does not need any configuration or tinkering to work. A
ConfigurationContext and the ports to operate on are the only details needed. The server will
store the mails in the memory against the recipient till the recipient pops it from the server. To
facilitate the use in Linux environments as a non root user, the POP and SMTP ports used by
default configuration/test cases are, 1024, 25 and 1024, 110 respectively.

How to Write Your Own Axis2 Transport

Prologue
To stop you from re-inventing the wheel, before we get started, I will quickly list the
transports that are already supported in Axis2 with a small description.
• HTTP - In the HTTP transport, the transport Listener is either a Servlet or a Simple
HTTP server provided by Axis2. The transport Sender uses sockets to connect and send
the SOAP message. Currently we have the commons-httpclient based HTTP Transport
sender as the default transport.
• TCP - This is the most simple transport, but needs Addressing support to be
functional.
• SMTP - This can work off a single email account or a mail server. The Mail Transport
Receiver is a thread that checks for emails in fixed time intervals.
To understand the rest of this document you will need some understanding of the
architecture of Axis2. If you are not familiar with the Axis2 architecture, please go through the
Axis2 Architecture Guide before you read any further.

196
Introduction
Broadly speaking, a transport inside Axis2 can be classified as a way of getting messages
that arrive though some channel into the Axis2 engine. The core of Axis2 is transport
independent. All data that is transport specific is stripped out of the incoming message and
inserted into the MessageContext. In the outgoing message, all transport specific information,
like headers, are added and sent.
To write your own transport, you will primarily need to write two classes: one is the
TransportSender and the other is the TransportReceiver. To register a transport with Axis2 you
will need to put entries corresponding to these two classes in the axis2.xml file. I will take you
through the process of adding the entries in the relevant sections.

Transport Receiver
Any message that is coming into Axis2 needs to go through a transport receiver. All
information about how the message is received at the Axis2 server from the wire (or via an e-
mail) is isolated inside the transport receiver. It extracts the data that is coming on the wire
and transforms it into a state that the Axis2 server understands.
So now that we have some background information about how transports work inside Axis2,
without further delay, lets dive into some coding and start building our own transport.
To get things stared, you will first need to extend from the
org.apache.Axis2.transport.TransportListener class and write your own transport listener. To
create an engine to process the MessageContext, we need a configuration context. The
following code fragment will do this. This should ideally be only done once for the lifetime of
the Transport receiver.

try {
//Create a factory
ConfigurationContextFactory factory = new
ConfigurationContextFactory();
//Use factory and Axis2 repository to create a new Configuration Context
configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(rep
ository_directory, axis2xmllocation);
} catch (Exception e) {
log.info(e.getMessage());
}

Now we need some kind of a Listener to listen to the requests that come in. You need to
implement this according to the transport that you are trying to build. After a message is
received at the Receiver, you can use the following code to process the request and then
forward the message context to the engine using the engine.receive(msgContext) method.
(The following code is extracted from the MailListener as an example)

197
AxisEngine engine = new AxisEngine(configurationContext);
MessageContext msgContext = null;

// create and initialize a message context


try {
TransportInDescription transportIn =
reg.getAxisConfiguration().getTransportIn(new
QName(Constants.TRANSPORT_NAME));
TransportOutDescription transportOut =
reg.getAxisConfiguration().getTransportOut(new
QName(Constants.TRANSPORT_NAME));
if (transportIn != null && transportOut != null) {
//create Message Context
msgContext = new MessageContext(configurationContext, transportIn,
transportOut);
msgContext.setServerSide(true);
msgContext.setProperty(MailSrvConstants.CONTENT_TYPE,
message.getContentType());
msgContext.setProperty(MessageContext.CHARACTER_SET_ENCODING,
message.getEncoding());

String soapAction = message.getSOAPActionHeader();


msgContext.setWSAAction(soapAction);
msgContext.setSoapAction(soapAction);

// Here we are trying to set the reply to if it is present in the


//transport information.
msgContext.setReplyTo(new
String soapNamespaceURI = "";EndpointReference(message.getReplyTo());
if(message.getContentType().indexOf(SOAP12Constants.SOAP_12_CONTENT_TY
//Create
PE) > -1){the SOAP Message -- This code in from the mail transport and
//will change depending
soapNamespaceURI on how the data is handled in each transport.
= SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
ByteArrayInputStream
} bais = new
ByteArrayInputStream(message.getContent().toString().getBytes());
else
XMLStreamReader reader =
if(message.getContentType().indexOf(SOAP11Constants.SOAP_11_CONTENT_
XMLInputFactory.newInstance().createXMLStreamReader(bais);
TYPE) > -1){
soapNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
}

StAXBuilder builder = new StAXSOAPModelBuilder(reader,


soapNamespaceURI);

SOAPEnvelope envelope = (SOAPEnvelope) builder.getDocumentElement();


msgContext.setEnvelope(envelope);
if (envelope.getBody().hasFault()) {
engine.receiveFault(msgContext);
} else {
engine.receive(msgContext);
}
} else {
throw new
AxisFault(Messages.getMessage("unknownTransport",Constants.TRANSPORT_NAM
E));
}

} catch (Exception e) {
try {
if (msgContext != null) {
MessageContext faultContext =
engine.createFaultMessageContext(msgContext, e);
engine.sendFault(faultContext);
} else {
log.error(e);
} 198
} catch (AxisFault e1) {
log.error(e);
}
}
Now that we have the coding in place, we need to let Axis2 know about our new transport
receiver. We do this by adding an entry into the axis2.xml file. If you need to pass any
properties for the transport to operate, it can also be done through the axis2.xml file.

<transportReceiver name="TRANSPORT_NAME"
class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_LISTNER_CLASS
">
<parameter name="PROPERTY_NAME"
locked="false">PROPERTY_VALUE</parameter>
<parameter name="PROPERTY_NAME_2"
locked="false">PROPERTY_VALUE_2</parameter>
</transportReceiver>

By using a code fragment like


Utils.getParameterValue(transportOut.getParameter(MailSrvConstants.SMTP_USER))
we can extract the parameters that we inserted into the axis2.xml file.
As you can see, getting a new transport receiver up and running is a task that requires very
little effort.

Transport Sender
Any message that is to be sent out of Axis2, is sent through the Transport Sender. The
Transport Sender needs to be extended from the
org.apache.Axis2.transport.AbstractTransportSender class.
The following bit of code from the abstract transport sender will call the Transport Sender
that you wrote.

199
// If an EPR is present then the message is going on a different
channel.
if (epr != null) {
out = openTheConnection(epr, msgContext);
OutputStream newOut = startSendWithToAddress(msgContext, out);
if (newOut != null) {
out = newOut;
}
writeMessage(msgContext, out);
finalizeSendWithToAddress(msgContext, out);
} else {
out = (OutputStream)
msgContext.getProperty(MessageContext.TRANSPORT_OUT);
if (out != null) {
startSendWithOutputStreamFromIncomingConnection(msgConte
xt, out);
writeMessage(msgContext, out);
finalizeSendWithOutputStreamFromIncomingConnection(msgCo
ntext, out);
} else {
throw new AxisFault(
"Both the TO and Property
MessageContext.TRANSPORT_WRITER is Null, No way to send response.");
}
}

Therefore, depending on whether your transport is using the same channel to send the
response or using a different channel, you will need to implement a sub-set of the methods
from the abstract class.
After implementing the necessary methods, you can let Axis2 know about your new
transport sender by adding an entry to the axis2.xml file, like you did for the transport
receiver.

<transportSender name="TRANSPORT_NAME" class=


"org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_SENDER_CLASS">
<parameter name="PROPERTY_NAME" locked="false">PROPERTY_VALUE</parameter>
<parameter name="PROPERTY_NAME_2"
locked="false">PROPERTY_VALUE_2</parameter>
</transportSender>

Have a look at org.apache.Axis2.transport.mail.MailTransportSender for a very simple


Transport Sender. Also have a look at
org.apache.Axis2.transport.http.CommonsHTTPTransportSender which is used to send HTTP
responses.
Once we have written our transport receiver and our transport sender, and inserted the
required entries into the axis2.xml file, we are done. It is as simple as that!

200

You might also like