Official Documentation (Ws Apache Org) - Axis2 - Part 1
Official Documentation (Ws Apache Org) - Axis2 - Part 1
Í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.
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!
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:
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.
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).
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
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.
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
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.
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
WebLogic/ WebSphere
<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
<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
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
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;
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:
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
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>
36
rice=100
and then execute the first getPrice URL, you will see that the price has got updated.
- 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.
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();
OMElement priceElement =
(OMElement)symbolElement.getNextOMSibling();
String price = priceElement.getText();
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
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;
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
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;
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
44
package samples.quickstart.service.jibx;
import java.util.HashMap;
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.
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;
46
public static OMElement updatePayload(String symbol, double price) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs =
fac.createOMNamespace("http://axiom.service.quickstart.samples/xsd",
"tns");
sender.fireAndForget(updatePayload);
System.err.println("done");
OMElement result = sender.sendReceive(getPricePayload);
} 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;
getPrice(stub);
update(stub);
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
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
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;
getPrice(stub);
update(stub);
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
stub.update(reqDoc);
System.err.println("done");
} catch(Exception e){
e.printStackTrace();
System.err.println("\n\n\n");
}
}
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
package samples.quickstart.clients;
import samples.quickstart.service.jibx.StockQuoteServiceStub;
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");
}
}
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.
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.
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.
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.
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.
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.
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.
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
<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.
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.
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/ .)
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.
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.
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;
return method;
}
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;
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
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.
package org.apache.axis2.axis2userguide;
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
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
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;
}
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.
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
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
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 "[email protected]".
(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.
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.
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;
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.
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();
}
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.
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.
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.
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
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:
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:
<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>
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:
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.
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.
You can change the user name and password values by changing the following two
parameters in the axis2.xml as required.
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.
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.
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
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.
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.
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
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.
Deployment
The Deployment Model provides a concrete mechanism to configure Axis2. This model has
111
three entities that provide the configuration.
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.
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
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.
public static
org.apache.axiom.om.OMElement
toOM(org.soapinterop.xsd.EchoStringParamDocument
param)// This method will handle the serialization.
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;
117
public boolean getRain(){
return rain;
}
package sample.pojo.service;
import sample.pojo.data.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.
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.
- 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.
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;
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);
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;
}
}
}
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.
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.
<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
123
<bean id="weatherSpringService"
class="sample.spring.service.WeatherSpringService">
<property name="weather" ref="weatherBean"/>
</bean>
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.
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.
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.
125
Apache Tomcat:
● http://tomcat.apache.org
Spring Framework:
● http://www.springframework.org/
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.
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>
With a ServletContext
This example (with a ServletContext) applicationContext.xml should be familiar to any
Spring user:
<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>
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>
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' :
<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>
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>
import
org.springframework.context.support.ClassPathXmlApplicationContext;
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;
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;
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");
//Blocking invocation
OMElement result = serviceClient.sendReceive(method);
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>
./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:
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;
/**
* 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>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<value>classpath*:**/MyEntity.hbm.xml</value>
</property>
...
</bean>
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
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.
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:
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
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.
<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.
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.
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.
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.
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
<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 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:
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 :
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.
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 :
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.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:
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.
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.
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.
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!
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.
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.
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
<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:
/**
* 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>
package com.sosnoski.ws.library.jibx.wrappers;
import com.sosnoski.ws.library.jibx.beans.Book;
156
public class GetBookResponse {
private Book m_book;
package com.sosnoski.ws.library.jibx.beans;
public Book() {}
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):
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>
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.
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>
<service >
<description>
This is a sample Web service with two operations, echo and ping.
</description>
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>
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>
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.
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.
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
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();
System.out.println(result);
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.
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.
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();
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
}
}
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.
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).
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.
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);
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.
172
Accessing Received Binary Data (Sample Code)
Service
public class MTOMService {
public void uploadFileUsingMTOM(OMElement element) throws Exception {
... ...
}
}
Client
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:
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"/>
<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>
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>
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();
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
177
public class SwA {
public SwA() {
}
//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);
...........
}
}
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);
}
------=_Part_0_1977511.1123163571138
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <9D645C8EBB837CE54ABD027A3659535D>
........
</soapenv:Envelope>
------=_Part_0_1977511.1123163571138
Content-Type: text/plain
Content-Transfer-Encoding: binary
Content-Id: <3936AE19FBED55AE4620B81C73BDD76E>
Binary Data.....
------=_Part_0_1977511.1123163571138--
179
Content-Type: multipart/related;
boundary=MIMEBoundary4A7AE55984E7438034;
type="application/xop+xml";
start="<[email protected]>";
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: <[email protected]>
</soapenv:Envelope>
--MIMEBoundary4A7AE55984E7438034
content-type: application/octet-stream
content-transfer-encoding: binary
content-id: <[email protected]>
Binary Data.....
--MIMEBoundary4A7AE55984E7438034--
Advanced Topics
<axisconfig name="AxisJava2.0">
<!-- Parameters -->
<parameter name="cacheAttachments" locked="false">true</parameter>
<parameter name="attachmentDIR" locked="false">temp
directory</parameter>
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: [email protected]. (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);
...
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>
...
Options options = new Options();
....
The above code would eventually override the deployment proxy configuration settings.
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();
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: [email protected]. (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.
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>
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>
<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: [email protected]. 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.
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>
<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
189
Send your feedback or questions to: [email protected]. (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.
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();
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;
}
};
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.
// 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();
Resources
For more information on Mail client invocation, see
AXIS2_HOME\samples\userguide\src\userguide\clients\MailClient.java
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>
193
...
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.
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>
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">[email protected]</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">[email protected]</parameter>
</transportReceiver>
ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(rep
o, axis2XML);
servicClient.setOptions(options);
servicClient.sendRobust(payload);
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
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;
} 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>
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.
200