Sie sind auf Seite 1von 80

AXIS 2

Índice de contenido
AXIS 2..................................................................................................................................................1
Apache Axis2 Modules.........................................................................................................................4
Axis2 - WS-Addressing Implementation.........................................................................................4
Using the SOAP Monitor.................................................................................................................4
Welcome to Apache Sandesha2.......................................................................................................6
Resources:...................................................................................................................................6
Securing SOAP Messages with Rampart.........................................................................................7
Content........................................................................................................................................7
Introduction.................................................................................................................................7
Rampart-1.1 Configuration.........................................................................................................7
Rampart Specific Assertions..................................................................................................7
Service Configration...............................................................................................................8
Client Confiuration.................................................................................................................8
Rampart-1.0 Configuration.........................................................................................................8
OutflowSecurity Parameter....................................................................................................8
InflowSecurity Parameter.......................................................................................................9
References.................................................................................................................................10
Examples...................................................................................................................................10
Web Services Policy Support In Apache Axis2..................................................................................12
Content...........................................................................................................................................12
What is Web Services (WS) Policy?..............................................................................................12
Client Side WS-Policy Support.....................................................................................................12
How it works:.................................................................................................................................12
Phase 1: At PolicyEvaluator......................................................................................................12
Phase 2: At AxisServiceBasedMultiLanguageClientEmitter....................................................13
Phase 3: Runtime......................................................................................................................13
Server Side WS-Policy Support.....................................................................................................13
Resources.......................................................................................................................................14
RESTful Web Services Support..........................................................................................................14
Content...........................................................................................................................................14
Introduction....................................................................................................................................14
REST Web Services with HTTP POST.........................................................................................15
Sample REST - HTTP POST Client.........................................................................................15
Access a REST Web Service via HTTP GET................................................................................16
Resources.......................................................................................................................................17
JSON Support in Axis2......................................................................................................................17
What is JSON?...............................................................................................................................17
Why JSON Support for Axis2?......................................................................................................17
How to use JSON in Axis2............................................................................................................18
Step 1.........................................................................................................................................18
Step 2.........................................................................................................................................19
Step 3.........................................................................................................................................19
Tests and Samples..........................................................................................................................19
Integration Test..........................................................................................................................19
Yahoo-JSON Sample.................................................................................................................20

1
Guide to using EJB Provider for Axis2..............................................................................................20
1. Creating a Simple Stateless Session EJB...................................................................................20
2. Creating the Axis2 Service Archive...........................................................................................22
Using the SOAP Monitor...................................................................................................................24
Axis2 Reference Guide.......................................................................................................................27
WSDL2Java Reference..................................................................................................................27
Java2WSDL Reference..................................................................................................................27
Apache Axis2 Tools............................................................................................................................28
Code Generator Tool Guide for Command Line and Ant Task.....................................................29
Content......................................................................................................................................29
Introduction...............................................................................................................................29
Command Line Version.............................................................................................................29
Option Reference..................................................................................................................29
Ant Task....................................................................................................................................30
Ant Task Reference..............................................................................................................30
Example Build File Using the Custom Ant Task..................................................................32
Invoking the Code Generator From Ant...............................................................................33
Appendix...................................................................................................................................40
Service Archive Generator Wizard Guide for Eclipse Plug-in......................................................40
Content......................................................................................................................................40
Introduction...............................................................................................................................40
Installation.................................................................................................................................41
Operation...................................................................................................................................41
Appendix...................................................................................................................................48
Code Generator Wizard Guide for Eclipse Plug-in.......................................................................49
Content......................................................................................................................................49
Introduction...............................................................................................................................49
Installation.................................................................................................................................49
Operation - WSDL2Java...........................................................................................................49
Operation - Java2WSDL...........................................................................................................55
Appendix...................................................................................................................................58
Maven2 AAR Plug-in Guide..........................................................................................................59
Introduction...............................................................................................................................59
Goals.........................................................................................................................................59
Configuration............................................................................................................................59
The aar Goal..............................................................................................................................59
File Sets.....................................................................................................................................60
Maven2 Java2WSDL Plug-in Guide.............................................................................................60
Introduction...............................................................................................................................60
Goals.........................................................................................................................................61
The Java2WSDL Goal..............................................................................................................61
Configuration............................................................................................................................61
Maven2 WSDL2Code Plug-in Guide............................................................................................62
Introduction...............................................................................................................................62
Goals.........................................................................................................................................62
The WSDL2Code Goal.............................................................................................................63
Configuration............................................................................................................................63
Migrating from Apache Axis 1.x to Axis2..........................................................................................64
Content...........................................................................................................................................64
Compatibility.................................................................................................................................64

2
Getting Started...............................................................................................................................65
Custom Deployment of Services, Handlers, and Modules............................................................66
Transports for HTTP Connection..................................................................................................69
Data Binding Support....................................................................................................................69
Best Usage.....................................................................................................................................76
Design Notes......................................................................................................................................76
Axis2 RPC Support........................................................................................................................76
Introduction...............................................................................................................................76
Step 1 - Converting RPC Style WSDL's into Doc/Lit Style WSDL....................................76
Step 2 - Unwrapping the Schema.........................................................................................78
Step 3 - Populate Type Information......................................................................................78
Step 4 - Generate Code with Unwrapped Parameters..........................................................79
Bringing the Parameters Together and Exploding Them..........................................................80
Conclusion................................................................................................................................80

3
Apache Axis2 Modules
Axis2 - WS-Addressing Implementation
This is an implementation of WS-Addressing submission version (2004-08) and WS-
Addressing 2005-08 versions. Complete WS-Addressing Final version will be available, once the
specification itself gets finalized.
Axis2 engine contains addressing support by default. So you may need not put this module,
unless you specifically want to use a particular release of this module.

Using the SOAP Monitor


Web service developers often want to see the SOAP messages that are being used to invoke
the Web services, along with the results of those messages. The goal of the SOAP Monitor
utility is to provide a way for the developers to monitor these SOAP messages without
requiring any special configuration or restarting the server.
In this utility, a handler has been written and added to the global handler chain. As SOAP
requests and responses are received, the SOAP message information is forwarded to a SOAP
monitor service where it can be displayed using a Web browser interface. The SOAP message
information is accessed by a Web browser by going to
http://localhost:8080/axis2/SOAPMonitor (where 8080 is the port number where the
application server is running). The SOAP message information is displayed through a Web
browser by using an applet that opens a socket connection to the SOAP monitor service. This
applet requires a Java plug-in 1.3 or higher to be installed in your browser. If you do not have
a correct plug-in, the browser will prompt you to install one. The port used by the SOAP
monitor service to communicate with applets is configurable. Edit the web.xml file to change
the port used by the Axis2 Web application.
The SOAP Monitor module (soapmonitor.mar) is available in the axis2.war but it is not
engaged by default. The SOAP Monitor is NOT enabled by default for security reasons.
The SOAP Monitor can be engaged by inserting the following in the axis2.xml file.
● <module ref="soapmonitor"/>
In the axis2.xml file, define your phase orders for the 'soapmonitorPhase' referenced in the
module.xml of soapmonitor.mars. Below is an example which should NOT be copied exactly,
since the default phases change occasionally. The important point here is that
'soapmonitorPhase' should be placed under the 'user can add his own phases to this area'
comment in the 'inflow', 'outflow', 'INfaultflow', and 'Outfaultflow' sections.

<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>

4
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="PostDispatch"/>
</handler>
</phase>
<!--System pre defined phases-->
<!--After Postdispatch phase module author or or service author can
add any phase he want-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="outflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>
<phaseOrder type="INfaultflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="Outfaultflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>

To configure the servlet to communicate with the applet, add the following code to the
web.xml (The SOAPMonitorPort is configurable.):

5
<servlet>
<servlet-name>SOAPMonitorService</servlet-name>
<display-name>SOAPMonitorService</display-name>
<servlet-class>
org.apache.axis2.soapmonitor.servlet.SOAPMonitorService
</servlet-class>
<init-param>
<param-name>SOAPMonitorPort</param-name>
<param-value>5001</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SOAPMonitorService</servlet-name>
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>

Finally, compile the applet classes and place them at the root (eg:
<CATALINA_HOME>/webapps/axis2/) of the extracted WAR file. You can find the
SOAPMonitorApplet.java in the source distribution. To compile, use the following command:
● javac -classpath axis2-soapmonitor.jar SOAPMonitorApplet.java
Alternatively, you can directly get the compiled applet classes from the WEB-
INF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2-
soapmonitor-*.jar file, simply execute the command, jar -xf axis2-soapmonitor-*.jar and
place the compiled applet classes in the root directory of the extracted WAR, for example, in
<CATALINA_HOME>/webapps/axis2/.
Using a Web browser, go to http[s]://host[:port][/webapp]/SOAPMonitor
(e.g.http://localhost:8080/axis2/SOAPMonitor) substituting the correct values for your Web
application. This will show the SOAP Monitor applet used to view the service requests and
responses. Any requests to services that have been configured and deployed correctly should
show up in the applet.
The SOAPMonitor with attachments currently serializes themselves as base64 characters. It
is therefore recommended to use the TCPMon tool to correctly capture MTOM and SWA
messages as an multipart mime where the binary data is an attachment.

Welcome to Apache Sandesha2


Sandesha2 is an implementation of WS-ReliableMessaging specification published by IBM,
Microsoft, BEA and TIBCO. Sandesha2 was built on top of Axis2. Therefore by using Sandesha2
you can add reliable messaging capability to the web services hosted using Axis2. Sandesha2
can also be used with Axis2 client to interact with already hosted web services in a reliable
manner. Please see sandesha2 user guide for more information on using Sandesha2. Read
Sandesha2 Architecture guide to see how Sandesha2 work internally.

Resources:
Official Page:
● http://ws.apache.org/sandesha/sandesha2/index.html
WS-ReliableMessaging specification:
● ftp://www6.software.ibm.com/software/developer/library/ws-
reliablemessaging200502.pdf

6
Securing SOAP Messages with Rampart
Axis2 comes with a module based on Apache WSS4J [1] to provide WS-Security features,
called "Rampart". This document explains how to engage and configure Rampart module.

Content
• Introduction
• Rampart-1.1 Configuration
• Rampart Specific Assertions
• Service Configration
• Client Confiuration
• Rampart-1.0 Configuration
• OutflowSecurity Parameter
• InflowSecurity Parameter
• References
• Examples

Introduction
Since rampart module inserts handlers in the system specific security phase, it must be
engaged globally. These handlers can be configured using WS-SecurityPolicy[2] and Rampart
specific policy assertions. Rampart-1.0 used two axis2 parameters for configuration and these
are still supported in the 1.1 release as well.
The rampart-1.1 release is available here:
● http://www.apache.org/dyn/closer.cgi/ws/rampart/1_1
First it should be engaged by inserting the following in the axis2.xml file.
● <module ref="rampart"/>
The web admin interface can be used when Axis2 is deployed in a servlet container such as
Apache Tomcat.
At the server it is possible to provide security on a per service basis. The configuration
parameters should be set in the service.xml file of the service. The client side config
parameters should be set in the axis2.xml of the client's Axis2 repository.

Rampart-1.1 Configuration

Rampart Specific Assertions


Rampart uses the standard WS-SecurityPolicy[2] assertions and also defines its own
assertions to be able capture the configuration information that is not provided in WS-
SecurityPolicy.
The Rampart specific assertion's xsd can be found here:
● http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/rampart-config.xsd
The ramp:RampartConfig assertion must be available as a one of the top level assertions
of the policy as shown here:
● http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/sample-policy.xml

7
Service Configration
To configure the service one will simply have to add the policy element into the sevices.xml
file. A sample service.xml file is available here:
● http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/sample-services.xml

Client Confiuration
On the client side, a policy object should be created and loaded into options. Creating the
policy object can be done using a "policy.xml" file as follows.

//Creating the object


StAXOMBuilder builder = new StAXOMBuilder(pathToPolicyfile);
Policy clientPolicy =
PolicyEngine.getPolicy(builder.getDocumentElement());
//setting the object
Options options = new Options();
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
clientPolicy);

Rampart-1.0 Configuration
Rampart module uses two parameters:
• OutflowSecurity
• InflowSecurity
The configuration that can go in each of these parameters are described below:

OutflowSecurity Parameter
This parameter is used to configure the outflow security handler. The outflow handler can be
invoked more than once in the outflow one can provide configuration for each of these
invocations. The 'action' element describes one of these configurations. Therefore the
'OutflowSecurity' parameter can contain more than one 'action' elements. The schema of this
'action' element is available here:
● http://ws.apache.org/axis2/modules/rampart/1_2/sec-conf/out-action.xsd
An outflow configuration to add a timestamp, sign and encrypt the message once, is shown
in Example 1 and Example 2 shows how to sign the message twice by chaining the outflow
handler (using two 'action' elements)
Following is a description of the elements that can go in an 'action' element of the
OutflowSecurity parameter

Parameter Description Example


Add a Timestamp, Sign the SOAP body and
Encrypt the SOAP body
items Security actions for the inflow
<items> Timestamp Signature
Encrypt</items>
Set alias of the key to be used to sign
user The user's name
<user> bob</user>
passwordCallback Callback class used to provide <passwordCallbackClass>
Class the password required to org.apache.axis2.security.PWCallback</pass

8
create the UsernameToken or
wordCallbackClass>
to sign the message
property file used to get the Set example.properties file as the signature
signature parameters such as property file
signaturePropFile
crypto provider, keystore and <signaturePropFile>
its password example.properties</signaturePropFile>
Key identifier to be used in Use the serial number of the certificate
signatureKeyIdent
referring the key in the <signatureKeyIdentifier>
ifier
signature IssuerSerial</signatureKeyIdentifier>
Key identifier to be used in Use the serial number of the certificate
encryptionKeyIde
referring the key in <encryptionKeyIdentifier>IssuerSerial</enc
ntifier
encryption ryptionKeyIdentifier>
The user's name for
encryptionUser
encryption. <encryptionUser>alice</encryptionUser>
Use AES-128
encryptionSymAlg Symmetric algorithm to be <encryptionSymAlgorithm>
orithm used for encryption http://www.w3.org/2001/04/xmlenc#aes12
8-cbc</encryptionSymAlgorithm>
Use RSA-OAEP
<parameter
encryptionKeyTran
Key encryption algorithm name="encryptionSymAlgorithm">
sportAlgorithm
http://www.w3.org/2001/04/xmlenc#rsa-
oaep-mgf1p</parameter>
Sign Foo and Bar elements qualified by
"http://app.ns/ns"
Sign multiple parts in the
signatureParts <signatureParts>
SOAP message
{Element}{http://app.ns/ns}Foo;{Element}
{http://app.ns/ns}Bar </signatureParts>
Optimize the CipherValue
MTOM Optimize the elements <optimizeParts>
optimizeParts
specified by the XPath query //xenc:EncryptedData/xenc:CipherData/xen
c:CipherValue </optimizeParts>

InflowSecurity Parameter
This parameter is used to configure the inflow security handler. The 'action' element is used
to encapsulate the configuration elements here as well. The schema of the 'action' element is
available here. Example 3 shows the configuration to decrypt, verify signature and validate
timestamp.
Parameter Description Example
first the incoming message should be
decrypted and then the signatures should be
verified and should be checked for the
items Security actions for the inflow
availability of the Timestamp
<items> Timestamp Signature
Encrypt</items>

Callback class used to obtain


passwordCallback <passwordCallbackClass>
password for decryption and
Class org.apache.axis2.security.PWCallback</pass
UsernameToken verification
wordCallbackClass>

Property file used for


signaturePropFile <signaturePropFile>
signature verification
sig.properties</signaturePropFile>

9
Property file used for
decryptionPropFile <decryptionPropFile>
decryption
dec.properties</decryptionPropFile>
Please note that the '.properties' files used in properties such as OutSignaturePropFile are
the same property files that are using in the WSS4J project. Following shows the properties
defined in a sample property file

org.apache.ws.security.crypto.provider=org.apache.ws.security.components
.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=pkcs12
org.apache.ws.security.crypto.merlin.keystore.password=security
org.apache.ws.security.crypto.merlin.keystore.alias=16c73ab6-b892-458f-
abf5-2f875f74882e
org.apache.ws.security.crypto.merlin.alias.password=security
org.apache.ws.security.crypto.merlin.file=keys/x509.PFX.MSFT

org.apache.ws.security.crypto.provider defines the implementation of the


org.apache.ws.security.components.crypto.Crypto interface to provide the crypto information
required by WSS4J. The other properties defined are the configuration properties used by the
implementation class (org.apache.ws.security.components.crypto.Merlin).

References
1. Apache WSS4J:
○ http://ws.apache.org/wss4j
2. ws-securitypolicy.pdf:
○ http://specs.xmlsoap.org/ws/2005/07/securitypolicy/ws-securitypolicy.pdf

Examples
Example 1: An outflow configuration to add a timestamp, sign and encrypt the message
once

10
Example 2: An outflow configuration to sign the message twice and add a timestamp

Example 3: An inflow configuration to decrypt, verify signature and validate timestamp

11
Web Services Policy Support In Apache Axis2
This document gives you an introduction to the role of Web services policy in Apache Axis2.
Send your feedback to: axis-dev@ws.apache.org. (Subscription details are available on the
Axis2 site.) Kindly prefix every email subject with [Axis2].

Content
• What is Web Services (WS) Policy?
• Client Side WS-Policy Support
• Server Side WS-Policy Support
• Resources

What is Web Services (WS) Policy?


To consume non trivial web services you must fully understand its XML contract (WSDL)
along with any other additional requirements, capabilities, or preferences that translate to the
configuration of the service and essentially becomes the policies of the service.
WS Policy framework provides a way to express the policies of a service in a machine-
readable way. A Web services infrastructure can be enhanced to understand and enforce
policies at runtime. For instance, a service author might write a policy requiring a digital
signature and encryption, while service consumers can use the policy information to reason out
whether they can adhere to this policy information to use the service.
Furthermore, Web service infrastructure can be enhanced to enforce those requirements
without requiring the service author to write even a single line of code.

Client Side WS-Policy Support


This release fully supports WS Policy at client-side. It means that when you codegen a
stub against a WSLD which contains policies, the stub will contain the capability to engage the
required modules with the appropriate configurations, plus it will generate additional methods
in the stub where the user can set certain properties. For instance, if there is a security policy
attached to a binding, the generated stub will engage the security module for that service with
the appropriate security configurations with some addtional methods that the user can use to
set properties in the generated stub.

How it works:

Phase 1: At PolicyEvaluator
The Codegen engine runs a few of its registered extensions before it generates the stub.
When the PolicyEvalutor (which is a registered Codegen extension) is initialized, it populates a
registry of QNames of supported policy assertions to PolicyExtensions.
For instance, module Foo might have a mapping of assertion {http://test.com/foo, foo}
which means any assertion that has this name will be processed by this module. The Foo
module might implement the ModulePolicyExtension interface through which the
PolicyExtension object can be obtained.
A PolicyExtension is the access point for a module to add any additional methods to the

12
stub. For instance a Reliable Messaging module can add startSequence() and endSequence()
methods to the stub, that the user must call to start and end an RM sequence.
Then at the engagement of the PolicyEvaluator, the effective policy of each message of
every operation is calculated based on policy information declared in the WSDL document.
Here we assume that the effective policy of an operation contains a single alternative
(Multiple policy alternatives are not supported). Then we split that policy as follows into
few other policies such that, each policy will contain assertions that can be processed by a
single module.

<wsp:Policy> <wsp:Policy> <wsp:Policy>


<a:Foo/>
<b:Bar/> => <a:Foo/> <b:Foo/>
</wsp:Policy> </wsp:Policy> </wsp:Policy>

Then each policy is given the appropriate PolicyExtension with an org.w3c.Element type
object to which the module can append any other elements/attributes it wishes. Those
attributes/elements should resolve to meaningful stub functions through the Custom
PolicyExtensionTemplate.xsl at a latter point of time.
For instance, depending on the policy, the Security module can append <username>,
<passwd> elements to the given element as children, which are later resolved into
setUsername(..), setPasswd(..), functions of the stub. This way a module can include
additional methods to the stub that can be used to get specific propreties from the user. These
methods store any user input in the ServiceClient properties
(ServiceClient.getOptions().putProperty(...)) which can later be accessed by the module.

Phase 2: At AxisServiceBasedMultiLanguageClientEmitter
Further, policies (based on the WSDL) at appropriate levels (service level, operation level)
are stored as policy strings in the stub. If there are a few policies at a given level, they are
merged together and represented as a single policy in the stub. Few more generic methods are
also added to the stub which are used to evaluate and process the policies at runtime.

Phase 3: Runtime
When a new stub object is created, the policy strings in the stub are converted into policy
objects and are set in the AxisDescription hierarchy that is used in the stub. In other words,
any policy information available in the WSDL will be preserved in the AxisService object that is
used in the stub.
Then based on its policy, each AxisDescription is engaged to a set of modules. Modules can
do a prior calculation of configurations if needed at the engagement.
When the stub method is invoked, those modules which are engaged to that
AxisDescription, access the policy for that operation via the AxisDescription object. It can get
the other required information from the MessageContext, which is stored by stub methods that
the module has added to the stub earlier, through the ModulePolicyExtension implementation.
The modules are required to load their configurations according to the effective policy, which is
set at AxisDescription, and the properties they get via MessageContext.

Server Side WS-Policy Support


In this current release, the Apache Axis2 framework uses the WS-Commons/Neethi
framework to manipulate policy documents. All its description builders store the policy
information included in description documents (services.xml, axis2.xml, .. etc) in the
appropriate description classes. This information is available at both deployment and run time

13
via these description classes.
When generating WSDL dynamically for each service, policy information in the description
classes is included. For instance, if you declare a policy in axis2.xml, then that policy is
reflected in the service elements of the WSDL of every service. If a policy is declared in a
services.xml, it is shown in the service element of WSDL for that particular service.
Further, when a service is deployed, an arbitary policy alternative is selected and set for
each AxisOperation and AxisMessages of the AxisService. If the selected Policy alternative
cannot be supported by any modules that are capable of processing the selective alternative,
then the service is considered as a faulty service. Else, the set of modules is engaged at
appropriate levels to support the requirments and capabilities that are defined in the Policies
associated with the AxisDescription.
It is evident that there is some work left to make Apache Axis2 a fully fledged ws-policy
supported Web service infrastructure. However, it is encouraging to note that we've taken the
first steps towards this goal. We appreciate any suggestions, patches, etc., you send us in this
regard. Keep on contributing!

Resources
Apache Neethi (WS Policy Implementation) official site:
● http://ws.apache.org/commons/neethi/index.html
Sanka Samaranayake, March 2006. Web services Policy - Why, What & How:
● http://wso2.org/library/23
WS-commons/policy SVN:
● http://svn.apache.org/viewvc/webservices/commons/trunk/modules/neethi/
Web Services Policy Framework (WS-Policy):
● http://specs.xmlsoap.org/ws/2004/09/policy/ws-policy.pdf

RESTful Web Services Support


This document presents an introduction on REST and REST with HTTP POST and GET.

Content
• Introduction
• Doing REST Web Services with HTTP POST
• Sample REST - HTTP POST Client
• Access a REST Web Service via HTTP GET

Introduction
WSDL 2.0 HTTP Binding defines a way to implement REST (Representational State Transfer)
with Web services. Axis2 implements the most defined HTTP binding specification. REST Web
services are a reduced subset of the usual Web service stack.
The Axis2 REST implementation assumes the following properties:
1. REST Web services are Synchronous and Request Response in nature.
2. When REST Web services are accessed via GET, the service and the operations are
identified based on the URL. The parameters are assumed as parameters of the Web

14
service. In this case, the GET based REST Web services support only simple types as
arguments and it should adhere to the IRI style.
3. POST based Web services do not need a SOAP Envelope or a SOAP Body. REST Web
Services do not have Headers and the payload is sent directly.
Axis2 can be configured as a REST Container and can be used to send and receive RESTful
Web service requests and responses. REST Web services can be accessed using HTTP GET and
POST.

REST Web Services with HTTP POST


If REST is enabled, the Axis2 server will act as both a REST endpoint and a SOAP endpoint.
When a message is received, if the content type is text/xml and if the SOAPAction Header is
missing, then the message is treated as a RESTful Message, if not it is treated as a usual SOAP
Message.
On sending a message, whether the message is RESTful or not, can be decided from the
client API.
Set a property in the client API.

...
Options options = new Options();
options.setProperty(Constants.Configuration.ENABLE_REST,
Constants.VALUE_TRUE);
...

Sample REST - HTTP POST Client


There is an example named, userguide.clients.RESTClient.java found in
AXIS2_HOME/samples/userguide/src/userguide/clients which demonstrates the usage of the
above. It uses the "echo" operation of the userguide.example1.MyServiceof the
AXIS2_HOME/samples/userguide/src/userguide/example1.
The class source will be as follows:

public class RESTClient {


private static String toEpr =
"http://localhost:8080/axis2/services/MyService";
public static void main(String[] args) throws AxisFault {

Options options = new Options();


options.setTo(new EndpointReference(toEpr));

options.setProperty(Constants.Configuration.ENABLE_REST,
Constants.VALUE_TRUE);

ServiceClient sender = new ServiceClient();


sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
sender.setOptions(options);
OMElement result = sender.sendReceive(getPayload());

try {
XMLStreamWriter writer = XMLOutputFactory.newInstance()
.createXMLStreamWriter(System.out);
result.serialize(writer);
writer.flush();
}

15
catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}
private static OMElement getPayload() {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("echo", omNs);
OMElement value = fac.createOMElement("Text", omNs);
value.addChild(fac.createOMText(value, "Axis2 Echo String "));
method.addChild(value);

return method;
}
}

Access a REST Web Service via HTTP GET


Axis2 allows users to access Web services that have simple type parameters via HTTP GET.
For example, the following URL requests the Version Service via HTTP GET. However, the Web
service arriving via GET assumes REST. Other parameters are converted into XML and put into
the SOAP body.
● http://127.0.0.1:8080/axis2/services/Version/getVersion
The result can be shown in the browser as follows:

For example, the following request,


● http://127.0.0.1:8080/axis2/services/Version/getVersion
will be converted into the following SOAP message for processing by Axis2.

16
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<axis2:getVersion xmlns:axis2="http://ws.apache.org/goGetWithREST"/>
</soapenv:Body>
</soapenv:Envelope>

Resources
How I Explained REST to My Wife, By Ryan Tomayko:
● http://naeblis.cx/articles/2004/12/12/rest-to-my-wife
Building Web Services the REST Way, By Roger L. Costello:
● http://www.xfront.com/REST-Web-Services.html
Resource-oriented vs. activity-oriented Web services, By James Snell:
● http://www-128.ibm.com/developerworks/webservices/library/ws-restvsoap/

JSON Support in Axis2


This document explains the JSON support implementation in Axis2. It includes an
introduction to JSON, an outline as to why JSON support is useful to Axis2 and how to it should
be used. Document also provides details on test cases and samples.

What is JSON?
JSON (Java Script Object Notation) is another data exchangeable format like XML, but it is
more lightweight and easily readable. It is based on a subset of JavaScript language.
Therefore, JavaScript can understand JSON, and it can make JavaScript objects by using JSON
strings. JSON is based on key-value pairs and it uses colons to separate keys and values. JSON
doesn't use end tags, and it uses braces (curly brackets) to enclose JSON Objects.
<root><test>json object</test></root> == {?root??:{?test??:??json object??}}
When it comes to converting XML to JSON and vice versa, there are two major conventions,
one named "Badgerfish" and the other, ?Mapped??. The main difference between these two
conventions exists in the way they map XML namespaces into JSON.
<xsl:root xmlns:xsl="http://foo.com"><data>my json string</data></xsl:root>
This XML string can be converted into JSON as follows.
Using ?Badgerfish??
{"xsl:root":{"@xmlns":{"xsl":"http://foo.com"},"data":{"$":"my json string"}}}
Using ?Mapped??
If we use the namespace mapping as http://foo.com -> foo
{"foo.root":{"data":"my json string"}}
JSON support implementation is a new feature in Apache Axis2/Java. It will become a
crucial improvement in the future with applications like JavaScript Web services.

Why JSON Support for Axis2?


Apache Axis2 is a Web services stack that delivers incoming messages into target
applications. In most cases, these messages are SOAP messages. In addition, it is also

17
possible to send REST messages through Axis2. Both types of messages use XML as their data
exchangeable format. So if we can use XML as a format, why not use JSON as another format?
There are many advantages of implementing JSON support in Axis2. Mainly, it helps the
JavaScript users (services and clients written in JavaScript) to deal with Axis2. When the
service or the client is in JavaScript, it can use the JSON string and directly build JavaScript
objects to retrieve information, without having to build the object model (OMElement in Axis2).
Also, JavaScript services can return the response through Axis2, just as a JSON string can be
shipped in a JSONDataSource.
Other than for that, there are some extra advantages of using JSON in comparison to XML.
Although the conversation ?XML or JSON??? is still a hot topic, many people accept the fact
that JSON can be passed and built easily by machines than in the case of XML.
For more details of this implementation architecture, refer to the article "JSON Support for
Apache Axis2"

How to use JSON in Axis2


At the moment JSON doesn't have a standard and unique content type. ?application/json??
(this is the content type which is approved in the JSON RFC ), ?text/javascript?? and ?
text/json?? are some of the commonly used content types of JSON. Due to this problem, in
Axis2, the user has been given the freedom of selecting the content type.

Step 1
Map the appropriate MessageFormatter and OMBuilder with the content type you are using
in the axis2.xml file.
e.g.1: If you are using the ?Mapped?? convention with the content type ?application/json??

<messageFormatters>
<messageFormatter contentType="application/json"
class="org.apache.axis2.json.JSONMessageFormatter"/>
<!-- more message formatters -->
</messageFormatters>

<messageBuilders>
<messageBuilder contentType="application/json"
class="org.apache.axis2.json.JSONOMBuilder"/>
<!-- more message builders -->
</messageBuilders>

e.g.2: If you are using the ?Badgerfish?? convention with the content type ?
text/javascript??

<messageFormatters>
<messageFormatter contentType="text/javascript"
class="org.apache.axis2.json.JSONBadgerfishMessageFormatter"/>
<!-- more message formatters -->
</messageFormatters>

<messageBuilders>
<messageBuilder contentType="text/javascript"
class="org.apache.axis2.json.JSONBadgerfishOMBuilder"/>
<!-- more message builders -->
</messageBuilders>

18
Step 2
On the client side, make the ConfigurationContext by reading the axis2.xml in which the
correct mappings are given.

File configFile = new File("test-resources/axis2.xml");


configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(nul
l, configFile.getAbsolutePath());
..........
ServiceClient sender = new ServiceClient(configurationContext, null);

Step 3
Set the MESSAGE_TYPE option with exactly the same content type you used in the
axis2.xml.
e.g. If you use the content type ?application/json??,

Options options = new Options();


options.setProperty(Constants.Configuration.MESSAGE_TYPE, ?
application/json??);
//more options
//...................

ServiceClient sender = new ServiceClient(configurationContext, null);


sender.setOptions(options);

If you are sending a request to a remote service, you have to know the exact JSON content
type that is used by that service, and you have to use that content type in your client as well.
HTTP POST method is used as the default to send JSON messages through Axis2, if the
HTTP method is not set by the user. But if you want to send JSON in HTTP GET method as a
parameter, you can do that by just setting an option on the client side.

options.setProperty(Constants.Configuration.HTTP_METHOD,
Constants.Configuration.HTTP_METHOD_GET);

Here, the Axis2 receiving side (JSONOMBuilder) builds the OMElement by reading the JSON
string which is sent as a parameter. The request can be made even through the browser.
e.g. Sample JSON request through HTTP GET. The JSON message is encoded and sent.

GET
/axis2/services/EchoXMLService/echoOM?query=%7B%22echoOM%22:%7B%22data%2
2:%5B%22my%20json%20string%22,%22my%20second%20json%20string%22%5D%7D%7D
HTTP/1.1

Tests and Samples

Integration Test
The JSON integration test is available under ?test?? in the ?json?? module of Axis2. It uses
the SimpleHTTPServer to deploy the service. A simple echo service is used to return the

19
incoming OMSourcedElementImpl object, which contains the JSONDataSource. There are two
test cases for two different conventions and another one test case to send the request in GET.

Yahoo-JSON Sample
This sample is available in the ?samples?? module of Axis2. It is a client which calls the
Yahoo search API using the GET method, with the parameter ?output=json??. The Yahoo
search service sends the response as a ?Mapped?? formatted JSON string with the content
type ?text/javascript??. This content type is mapped with the JSONOMBuilder in the axis2.xml.
All the results are shown in a GUI. To run the sample, execute the ant script.
These two applications are good examples of using JSON support for Axis2. You can
understand the architecture of JSON support implementation in Axis2 by looking at these
samples.

Guide to using EJB Provider for Axis2


The EJB message receiver allows one to access stateless session EJBs (Enterprise
JavaBeans) through Web services. The example used in this guide illustrates how to use EJB
provider that ships with axis2 to access EJBs deployed on a J2EE server such as Geronimo or
Jboss.
This example explains how to use Geronimo 1.1 and Jboss 4.0.4.GA as application server.
The following steps will take you through the example through which we will explain how to
use an EJB provider in Axis2

1. Creating a Simple Stateless Session EJB


First, we need to create a stateless session EJB. Use the following files to make an EJB for
testing:

Remote interface (Hello.java)


package my.ejb;
import javax.ejb.EJBObject;
public interface Hello extends EJBObject, HelloBusiness { }

The following interface defines the business methods available in


1.HelloBusiness.java

package my.ejb;
import java.rmi.RemoteException;
public interface HelloBusiness {
public String sayHello(String name) throws RemoteException;
}

2, Remote home interface - HelloHome.java

package my.ejb;
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import java.rmi.RemoteException;

public interface HelloHome extends EJBHome {


public Hello create() throws CreateException, RemoteException;
}

20
3. Bean class - HelloBean.java

package my.ejb;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.ejb.EJBException;
import javax.ejb.CreateException;

public class HelloBean implements SessionBean {


public void setSessionContext(SessionContext sessionContext) throws
EJBException {}

public void ejbRemove() throws EJBException {}


public void ejbActivate() throws EJBException {}
public void ejbPassivate() throws EJBException {}
public void ejbCreate() throws CreateException {}
public String sayHello(String name) {
return "Hello " + name + ", Have a nice day!";
}
}

4. Deployment descriptor - ejb-jar.xml

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


<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">

<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<home>my.ejb.HelloHome</home>
<remote>my.ejb.Hello</remote>
<ejb-class>my.ejb.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>Hello</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

Now we have to write application server specific deployment descriptor(s) for the Hello EJB.
Following listing shows an example Geronimo/OpenEJB deployment descriptor (openejb-
jar.xml)

21
<?xml version="1.0" encoding="UTF-8"?>
<openejb-jar
xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1"
xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1"
xmlns:security="http://geronimo.apache.org/xml/ns/security-1.1"
xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1"
xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0">
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<jndi-name>my/ejb/HelloBean</jndi-name>
</session>
</enterprise-beans>
</openejb-jar>

If you want to test on JBoss, use the following JBoss deployment descriptor (jboss.xml)

<?xml version="1.0"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd">
<jboss>
<enterprise-beans>
<session>
<ejb-name>Hello</ejb-name>
<jndi-name>my/ejb/HelloBean</jndi-name>
</session>
</enterprise-beans>
</jboss>

Compile the above java classes and bundle the compiled classes and the XML files into a jar
file (HelloEJB.jar) as shown below.

HelloEJB.jar
|
+--META-INF
| +--ejb-jar.xml
| +--jboss.xml [If you want to deploy on Jboss]
| +--openejb-jar.xml [If you want to deploy on Geronimo/Openejb]
|
+--my
+--ejb
|
+--Hello.class
+--HelloBean.class
+--HelloBusiness.class
+--HelloHome.class

Deploy HelloEJB.jar on appropriate J2EE application server.

2. Creating the Axis2 Service Archive


Now we need to make the services.xml file.

22
<serviceGroup>
<service name="HelloBeanService">
<description>Hello! web service</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.ejb.EJBInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.ejb.EJBMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">
my.ejb.HelloBusiness
</parameter>
<parameter name="remoteInterfaceName">my.ejb.Hello</parameter>
<parameter name="homeInterfaceName">my.ejb.HelloHome</parameter>
<parameter name="beanJndiName">my/ejb/HelloBean</parameter>
<parameter name="providerUrl">[URL]</parameter>
<parameter name="jndiContextClass">
[Context Factory Class Name]
</parameter>
</service>
</serviceGroup>

In the above services.xml file, replace the [URL] and [Context Factory Class Name] with
valid values as follows:
i.e. If the EJB is deployed on Geronimo:
Replace [URL] by 127.0.0.1:4201
Replace [Context Factory Class Name] by org.openejb.client.JNDIContext
For Jboss:
Replace [URL] by jnp://localhost:1099
Replace [Context Factory Class Name] by org.jnp.interfaces.NamingContextFactory
Bundle the HelloBeanService.wsdl, services.xml, remote interface class and home interface
class as illustrated below:

HelloBeanService.aar
|
+--META-INF
| +--services.xml
|
+--lib
| +--[jars used by the ejb client eg.initial context factory
classes]
|
+--my
+--ejb
+--Hello.class
+--HelloBusiness.class
+--HelloHome.class

The lib directory of HelloBeanService.aar must contain all the libraries needed to access the
EJB. If the EJB is deployed on Geronimo, add the following jar files to the lib directory.
• cglib-nodep-2.1_3.jar
• geronimo-ejb_2.1_spec-1.0.1.jar
• geronimo-j2ee-jacc_1.0_spec-1.0.1.jar

23
• geronimo-kernel-1.1.jar
• geronimo-security-1.1.jar
• openejb-core-2.1.jar
For JBoss add the following jar files.
• jnp-client.jar
• jboss-client.jar
• jboss-common-client.jar
• jboss-remoting.jar
• jboss-serialization.jar
• jboss-transaction-client.jar
• concurrent.jar
• jbosssx-client.jar
• jboss-j2ee.jar
Deploy HelloBeanService.aar on an Axis2 server.
Now you can access the Hello EJB through Web services. Since our EJB message receivers
extend RPC message receivers, org.apache.axis2.rpc.client.RPCServiceClient can be used to
invoke the service as illustrated in the following code fragment.

...
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();

EndpointReference targetEPR = new


EndpointReference("http://localhost:8080/axis2/services/HelloBeanService
");

options.setTo(targetEPR);
QName hello = new QName("http://ejb.my/xsd", "sayHello");
Object[] helloArgs = new Object[] {"John"};

System.out.println(serviceClient.invokeBlocking(hello,
helloArgs).getFirstElement().getText());
...

Using the SOAP Monitor


Web service developers often want to see the SOAP messages that are being used to invoke
the Web services, along with the results of those messages. The goal of the SOAP Monitor
utility is to provide a way for the developers to monitor these SOAP messages without
requiring any special configuration or restarting the server.
In this utility, a handler has been written and added to the global handler chain. As SOAP
requests and responses are received, the SOAP message information is forwarded to a SOAP
monitor service where it can be displayed using a Web browser interface. The SOAP message
information is accessed by a Web browser by going to
http://localhost:8080/axis2/SOAPMonitor (where 8080 is the port number where the
application server is running). The SOAP message information is displayed through a Web
browser by using an applet that opens a socket connection to the SOAP monitor service. This
applet requires a Java plug-in 1.3 or higher to be installed in your browser. If you do not have
a correct plug-in, the browser will prompt you to install one. The port used by the SOAP

24
monitor service to communicate with applets is configurable. Edit the web.xml file to change
the port used by the Axis2 Web application.
The SOAP Monitor module (soapmonitor.mar) is available in the axis2.war but it is not
engaged by default. The SOAP Monitor is NOT enabled by default for security reasons.
The SOAP Monitor can be engaged by inserting the following in the axis2.xml file.
<module ref="soapmonitor"/>
In the axis2.xml file, define your phase orders for the 'soapmonitorPhase' referenced in the
module.xml of soapmonitor.mars. Below is an example which should NOT be copied exactly,
since the default phases change occasionally. The important point here is that
'soapmonitorPhase' should be placed under the 'user can add his own phases to this area'
comment in the 'inflow', 'outflow', 'INfaultflow', and 'Outfaultflow' sections.

<phaseOrder type="inflow">
<!--System pre defined phases-->
<phase name="TransportIn"/>
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="InstanceDispatcher"
class="org.apache.axis2.engine.InstanceDispatcher">
<order phase="PostDispatch"/>
</handler>
</phase>
<!--System pre defined phases-->
<!--After Postdispatch phase module author or or service author can
add any phase he want-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>

<phaseOrder type="outflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>

25
<phaseOrder type="INfaultflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>

<phaseOrder type="Outfaultflow">
<!--user can add his own phases to this area-->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
</phaseOrder>

To configure the servlet to communicate with the applet, add the following code to the
web.xml (The SOAPMonitorPort is configurable.):

<servlet>
<servlet-name>SOAPMonitorService</servlet-name>
<display-name>SOAPMonitorService</display-name>
<servlet-class>
org.apache.axis2.soapmonitor.servlet.SOAPMonitorService
</servlet-class>
<init-param>
<param-name>SOAPMonitorPort</param-name>
<param-value>5001</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SOAPMonitorService</servlet-name>
<url-pattern>/SOAPMonitor</url-pattern>
</servlet-mapping>

Finally, compile the applet classes and place them at the root (eg:
<CATALINA_HOME>/webapps/axis2/) of the extracted WAR file. You can find the
SOAPMonitorApplet.java in the source distribution. To compile, use the following command:
javac -classpath axis2-soapmonitor.jar SOAPMonitorApplet.java
Alternatively, you can directly get the compiled applet classes from the WEB-
INF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2-
soapmonitor-*.jar file, simply execute the command, jar -xf axis2-soapmonitor-*.jar and
place the compiled applet classes in the root directory of the extracted WAR, for example, in
<CATALINA_HOME>/webapps/axis2/.
Using a Web browser, go to:
● http[s]://host[:port]/[webapp]/SOAPMonitor(http://localhost:8080/axis2/SOAPMonitor)
substituting the correct values for your Web application. This will show the SOAP Monitor
applet used to view the service requests and responses. Any requests to services that have
been configured and deployed correctly should show up in the applet.
The SOAPMonitor with attachments currently serializes themselves as base64 characters. It
is therefore recommended to use the TCPMon tool to correctly capture MTOM and SWA
messages as an multipart mime where the binary data is an attachment.

26
Axis2 Reference Guide
WSDL2Java Reference
NAME
wsdl2java.sh or wsdl2java.bat - Generates java code according to a given WSDL
file to handle Web service invocation.
These scripts can be found under the bin directory of the Axis2 distribution.

SYNOPSIS
wsdl2java.sh [OPTION]... -uri <Location of WSDL>

DESCRIPTION
Given a WSDL file, this generates java code to handle Web service invocations.

-o <output Location> : output file location


-a : Generate async style code only. Default is off
-s : Generate sync style code only. Default is off. takes precedence over -a
-p <package name> : set custom package name
-l <language> : valid languages are java and csharp. Default is java
-t : Generate TestCase to test the generated code
-ss : Generate server side code (i.e. skeletons). Default is off
-sd : Generate service descriptor (i.e. services.xml). Default is off. Valid
with -ss
-d <databinding> : valid databinding(s) are adb, xmlbeans and jaxme. Default is
adb
-g : Generates all the classes. valid only with the -ss (This will generate
client and server codes)
-pn <port_name> : name of port in the presence of multiple ports
-sn <service_name> : name of service in the presence of multiple services
-u : unpacks the databinding classes
-r <repository_path> : path of the repository against which code is generated
-ns2p ns1=pkg1,ns2=pkg2 : Specify a custom package name for each namespace
specified in the wsdl's schema
-ssi : Generate an interface for the service implementation (Default: off)
-em : Specify an external mapping file
-wv : WSDL Version. Valid Options : 2, 2.0, 1.1
-f : Generate the source output folder without the src directory
-uw : Switch on un-wrapping.
-S <folder name> : Generated source folder name. (Default: src)
-R <folder name> : Generated resources folder name. (Default: resources)

EXAMPLES
wsdl2java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl
wsdl2java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd
wsdl2java.sh -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -d xmlbeans -o
../samples -p org.apache.axis2.userguide

Java2WSDL Reference
NAME
Java2WSDL.sh or Java2WSDL.bat - Generates the appropriate WSDL file for a given
java class.
These scripts can be found under the bin directory of the Axis2 distribution.

SYNOPSIS
Java2WSDL.sh [OPTION]... -cn <fully qualified class name>

DESCRIPTION

27
Given a java class generates a WSDL file for the given java class.

-o <output Location> : output file location


-cp <class path uri> : list of classpath entries - (urls)
-tp <target namespace prefix> : target namespace prefix
-stn <schema target namespace> : target namespace for schema
-stp <schema target namespace prefix> : target namespace prefix for schema
-sn <service name> : service name
-of <output file name> : output file name for the WSDL
-st <binding style> : style for the WSDL
-u <binding use> : use for the WSDL
-l <soap address> : address of the port for the WSDL
-efd <qualified/unqualified> : Setting for elementFormDefault (defaults to
qualified)
-afd <qualified/unqualified> : Setting for attributeFormDefault (defaults to
qualified)
-xc <extra class> : Extra class for which schematype must be generated. Use as
: -xc class1 -xc class2 ...
EXAMPLES
Java2WSDL.sh -cn ../samples/test/searchTool.Search
Java2WSDL.sh -cn ../samples/test/searchTool.Search -sn search
Java2WSDL.sh -cn ../samples/test/searchTool.Search -u -sn search
Java2WSDL.sh -cn ../samples/test/searchTool.Search -sn search -o
../samples/test/wsdl

Apache Axis2 Tools


Axis2 is bundled with a set of tools in order to make users' life easier. This page is
maintained to keep track of the tools supported by Axis2.
Name Description
Code Tool consists of a command line version and an Ant Task. It is implemented by
Generator Tool- the WSDL2Code class and WSDL2Java class. One can choose to run the main
Command Line classes directly or use one of the scripts to run the WSDL2Code and
& Ant Task WSDL2Java appropriately.
Service Archive As part of the Axis2 tool set, the service archive generator is an important tool
Wizard - that allows the generation of service archives ("aar" file or a "jar" files) that
Eclipse Plug-in can be deployed as a Web services to the Axis2.
Code
Axis2 code generator comes built-in with an eclipse plug-in. This can be used
Generator
to generate a WSDL file from a java class (Java2WSDL) and/or a java class file
Wizard -
from a WSDL (WSDL2Java)
Eclipse Plug-in
Code
Generator Using this tool one can create service archives that can be deployed as a Web
Wizard - services to the Axis2, and also generate a java class file from a WSDL file
IntelliJ IDEA (WSDL2Java).
Plug-in
Maven2 AAR
This plugin generates an Axis2 service file (AAR file).
Plug-in
Maven2 This plugin takes as input a Java class and generates a WSDL, which describes
Java2WSDL a Web service for invoking the classes methods.
Plug-in
Maven2 This plugin takes as input a WSDL and generates client and server stubs for
WSDL2Code calling or implementing a Web service matching the WSDL.
Plug-in

28
Code Generator Tool Guide for Command Line and Ant
Task
The Code Generator tool consists of a command line version and an Ant Task. This
document will list the command line references and Ant task references. Also in detail, this
document shows how to build file using custom Ant task and invoking the Code Generator from
Ant. This tool is bundled with the Axis2 Binary Distribution.

Content
• Introduction
• Command Line Version
• Option Reference
• Ant Task
• Ant Task Reference
• Example Build File Using the Custom Ant Task
• Invoking the Code Generator From Ant
• Appendix

Introduction
This basic tool is implemented by the WSDL2Code class and just for the convenience in the
case of Java (which would be the majority) there is another WSDL2Java class. One can choose
to run the main classes directly or use one of the scripts to run the WSDL2Code and
WSDL2Java appropriately. (the scripts are found in the bin directory of the Standard Binary
Distribution)

Command Line Version


For those users who wish to use the command line version of the tool, this section will be of
value.

Option Reference
Usage WSDL2Code <option_reference>
E.g. :- WSDL2Code -uri <Location of WSDL>
Short Option Long Option Description
-uri <Location of WSDL file location. This should point to a WSDL file in
None
WSDL> the local file system.
Output file location. This is where the files would be
-o <output --output <output copied once the code generation is done. If this option
Location> Location> is omitted the generated files would be copied to the
working directory.
Output language. Currently the code generator can
--language
-l <language> generate code in Java but it has the ability to be
<language>
extended to support other languages.
The target package name. If omitted, a default package
-p <package --package
(formed using the target namespace of the WSDL) will
name> <package name>
be used.

29
Generate code only for async style. When this option is
used the generated stubs will have only the
-a --async
asynchronous invocation methods. Switched off by
default.
Generate code only for sync style . When this option is
used the generated stubs will have only the
-s --sync synchronous invocation methods. Switched off by
default. When used with the -a option, this takes
precedence.
Generates a test case. In the case of Java it would be a
-t --test-case
JUnit test case.
Generates server side code (i.e. skeletons). Default is
-ss --server-side
off.
Generates the service descriptor (i.e. server.xml).
--service-
-sd Default is off. Only valid with -ss, the server side code
description
generation option.
--databinding-
-d Specifies the Databinding framework. Valid values are
method
<databinding> xmlbeans, adb, jibx, and none. Default is adb.
<databinding>
Generates all the classes. This option is valid only with
the -ss (server side code generation) option. When on,
-g --generate-all
the client code (stubs) will also be generated along with
the skeleton.
Unpack classes. This option specifies whether to unpack
-u --unpack-classes the classes and generate separate classes for the
databinders.
Specifies the service name to be code generated. If the
-sn <service --service-name
service name is not specified, then the first service will
name> <service name>
be picked.
Specifies the port name to be code generated. If the
-pn <port --port-name <port
port name is not specified, then the first port (of the
name> name>
selected service) will be picked.
Specifies a comma separated list of namespaces and
-- packages where the given package will be used in the
-ns2p namespace2packa place of the auto generated package for the relevant
ge namespace. The list will be the format of
ns1=pkg1,ns2=pkg2.
--serverside-
-ssi Generate an interface for the service skeleton.
interface
Apart from these mentioned options one can pass extra options by prefixing them with -E
(uppercase). These extra options will be processed by the extensions. The extra options that
can be passed are documented separately with the extensions documentation (For example
with ADB).

Ant Task
The code generator also comes bundled with an Ant task. The ant task is implemented by
the org.apache.axis2.tool.ant.AntCodegenTask class. Following are the ant task attributes.

Ant Task Reference


WSDL file location. Maps to the -uri option of the command
wsdlfilename
line tool.

30
Output file location. This is where the files would be copied
once the code generation is done. If this option is omitted the
output
generated files would be copied to the working directory. Maps
to the -o option of the command line tool.
Output language. Currently the code generator can generate
language
code in Java. Maps to the -l option of the command line tool.
The target package name. If omitted, a default package
packageName (formed using the target namespace of the WSDL) will be
used. Maps to the -p option of the command line tool.
Data binding framework name. Maps to the -d option of the
databindingName command line tool. Possible values include "adb", "xmlbeans",
"jibx".
The name of the service in the case of multiple services. Maps
serviceName
to -sn options of the command line tool.
The name of the port in the presence of multiple ports. Maps
portName
to -pn options of the command line tool.
Generate code only for async style. When this option is used
the generated stubs will have only the asynchronous
asyncOnly invocation methods. Defaults to false if omitted. Only true and
false are applicable as values. Maps to the -a option of the
command line tool.
Generate code only for sync style. When this option is used the
generated stubs will have only the synchronous invocation
syncOnly methods. Defaults to false if omitted. Only true and false are
applicable as values. Maps to the -s option of the command
line tool.
Generates server side code (i.e. skeletons). Only true and false
serverSide are applicable as values. Default is false. Maps to the -ss
option of the command line tool.
Generates a test case. Possible values are true and false. Maps
testcase
to the -t options of the command line tool.
Generates server side code (i.e. skeletons). Only true and false
generateServiceXml are applicable as values. Default is false. Maps to the -sd
option of the command line tool.
Unpacks the generated classes. This forces the databinding
unpackClasses classes to be generated separately, which otherwise would
have been generated as inner classes.
Generates all the classes including client and server side code.
generateAllClasses
Maps to the -g option of the command line tool.
namespaceToPackages A list of namespace to package mappings.
Flag stating whether to generate an interface for the server
serverSideInterface
side skeleton.
Sets the repository path to be used. Maps to the -r option of
repositoryPath
the command line tool.
Sets the version of the wsdl that is being used during
codegeneration. This deafults to 1.1 and one can set this to 2,
wsdlVersion
when trying to work with a WSDL 2.0 document. Maps to the
-wv option of the command line tool.
Location of the external mapping file to be used. Maps to the
externalMapping
-em option of the command line tool.
Rather than dumping all the code in the same location, one
targetSourceFolderLocation
has the option to make the sources to be generated in a

31
different location, given using this option. Maps to the -S
option of the command line tool.
Rather than dumping all the code in the same location, one
has the option to make the resources to be generated in a
targetResourcesFolderLocation
different location, given using this option. Maps to the -R
option of the command line tool.
This will select between wrapped and unwrapped during code
unwrap generation. Default is set to false. Maps to the -uw option of
the command line tool.

Example Build File Using the Custom Ant Task


Following is an example ant build file that uses the custom Ant task. You can use any wsdl
file to test the example. Replace the "CombinedService.wsdl" with the name of your wsdl file in
the following script.

1 <?xml version="1.0"?>
2 <project name="CodegenExample" default="main" basedir=".">
3
4 <path id="example.classpath">
5 <fileset dir="classes">
6 <include name="**/*.jar" />
7 </fileset>
8 </path>
9
10 <target name="declare" >
11 <taskdef name="codegen"
12 classname="org.apache.axis2.tool.ant.AntCodegenTask"
13 classpathref="example.classpath"/>
14
15 </target>
16
17 <target name="main" depends="declare">
18 <codegen
19 wsdlfilename="C:\test\wsdl\CombinedService.wsdl"
20 output="C:\output"
21 serverside="true"
22 generateservicexml="true"/>
23 </target>
24
25 </project>

In the above build script, from line 4 to 8 it sets the classpath and includes all the .jar files
(which are listed below) into the classpath. From line 10 to 15 it creates a target to declare a
task called "codegen" and sets the appropriate class
(org.apache.axis2.tool.ant.AntCodegenTask) within the classpath in line 12. From line 17 to 23
it creates the "main" target to generate the code from the given wsdl. There are some
arguments set form line 19 to 22. Here in line 19 it sets the location of the wsdl. In line 20 it
sets the output directory in which the code is generated. Line 21 indicates that this build
generates the server side code(skeleton) and line 22 indicates that the services.xml is also
generated.
Notice the main target that uses the "codegen" task which will use the
org.apache.axis2.tool.ant.AntCodegenTask class and run the code generation tool internally
while passing the relevant arguments and do the proper generation. If a user types
>ant or >ant main
it will generate the server side code and services.xml for the given WSDL file

32
(C:\test\wsdl\CombinedService.wsdl -in the above instance) and the generated code will be
written to the specified output path (C:\output - in the above instance).
For this Ant task to work the following jars need to be in the class path.
• axis2-*.jar (from the Axis2 distribution)
• wsdl4j-1.6.2.jar or higher (The WSDL4J implementation jar. Bundled with the Axis2
distribution)
• stax-api-1.0.1.jar (The StAX API's that contain the javax.xml.namespace.QName
class. This jar may be replaced by any other jar that contains the
javax.xml.namespace.QName implementation. However Axis2 uses this class from the
stax-api-1.0.1.jar which comes bundled with the Axis2 distribution)
• commons-logging-1.1.jar, neethi-2.0.jar and XmlSchema-1.2.jar (from the Axis2
distribution)
• axiom-api-1.2.1.jar and axiom-impl-1.2.1.jar (from the Axis2 distribution)
• activation-1.1.jar (from the Axis2 distribution)
• wstx-asl-3.1.0.jar (from the Axis2 distribution)

Invoking the Code Generator From Ant


Since the users may find altering their ant class path a bit daunting they can also follow an
easier technique. The code generator main class can be invoked directly through the build file.
Below is an example of a full build.xml needed to run WSDL2Java and generate the Java
source files, compile the sources, and build an AAR file ready for deployment (These are done
one by one, by calling the targets in the build file separately):

<!DOCTYPE project>
<project name="wsdl2java-example" default="usage" basedir=".">
<property name="project-name" value="wsdl2java-example"/>
<property file="build.properties"/>
<property name="build" value="build"/>
<property name="src" value="src"/>
<property name="build.classes" value="build/classes" />
<path id="axis.classpath">
<pathelement location="build/classes" />
<fileset dir="${axis.home}/lib">
<include name="**/*.jar" />
</fileset>
<pathelement location="${build.classes}" />
</path>
<path id="axis_client.classpath">
<pathelement location="build/classes" />
<fileset dir="${axis.home}">
<include name="**/*.jar" />
</fileset>
<fileset dir="lib">
<include name="*.jar" />
</fileset>
<pathelement location="${build.classes}" />
</path>

33
<target name="usage" description="Build file usage info (default
task)">
<echo message=" " />
<echo message="${project-name} " />
<echo message="-------------------------------------------------" />
<echo message=" " />
<echo message="Available Targets:" />
<echo message=" " />
<echo message=" Compiling:" />
<echo message=" compile - Compiles the WSDL2Java source code" />
<echo message=" " />
<echo message=" Compiling client:" />
<echo message=" compile_client - Compiles the client source code" />
<echo message=" " />
<echo message=" Cleaning up:" />
<echo message=" clean - Delete class files" />
<echo message=" " />
<echo message=" WSDL:" />
<echo message=" wsdl2java - Generate source from WSDL" />
<echo message=" " />
<echo message=" AAR:" />
<echo message=" aar - Generate an .aar for deployment into WEB-
INF/services" />
<echo message=" " />
<echo message=" Executing:" />
<echo message=" runLogin - Execute the runLogin client" />
</target>
<target name="prepare" >
<mkdir dir="${build.classes}" />
</target>

<target name="clean" >


<delete dir="${build}" />
<delete dir="${dist}" />
</target>

<target name="compile">
<echo message="Compiling wsdl2 files"/>
<javac srcdir="output" destdir="${build.classes}" deprecation="true"
failonerror="true" debug="true">
<classpath refid="axis.classpath"/>
</javac>
</target>

34
<target name="wsdl2java" depends="clean,prepare">
<delete dir="output" />
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="axis.classpath"/>
<arg value="-d"/>
<arg value="xmlbeans"/>
<arg value="-uri"/>
<arg file="wsdl/LoginEndpoint.wsdl"/>
<arg value="-ss"/>
<arg value="-g"/>
<arg value="-sd"/>
<arg value="-o"/>
<arg file="output"/>
<arg value="-p"/>
<arg value="org.example.types"/>
</java>
<!-- Move the schema folder to classpath-->
<move todir="${build.classes}">
<fileset dir="output/resources">
<include name="**/*schema*/**/*.class"/>
<include name="**/*schema*/**/*.xsb"/>
</fileset>
</move>
</target>

<target name="jar_wsdl" depends="compile">


<jar jarfile="lib/axis2_example_wsdl.jar" >
<fileset dir="${build.classes}" />
</jar>
</target>

<!-- build an .aar file for axis2 web services -->


<target name="aar" depends="compile">
<delete dir="${build.classes}/META-INF" />
<mkdir dir="${build.classes}/META-INF" />
<copy todir="${build.classes}/META-INF" >
<fileset dir="output/resources" >
<!-- axis2 web services definitions file -->
<include name="services.xml"/>
</fileset>
<fileset dir="wsdl" >
<include name="LoginEndpoint.wsdl"/>
</fileset>
</copy>
<jar jarfile="dist/LoginEndpoint.aar" >
<fileset dir="${build.classes}" />
</jar>
</target>

<target name="compile_client">
<echo message="Compiling client files"/>
<javac srcdir="src" destdir="${build.classes}" deprecation="true"
failonerror="true" debug="true">
<classpath refid="axis.classpath"/>
</javac>
</target>

35
<target name="runLogin" depends="prepare,compile_client"
description="run simple Login client">
<java classname="org.client.LoginClient" >
<classpath refid="axis_client.classpath"/> </java> </target>
</project>

Place the above build.xml file in the 'bin' directory of the axis2 binary distribution. Then
create a build.properties file in the same directory and specify the axis.home path pointing to
the axis2 binary distribution
E.g. :- axis.home=C://Axis2//axis2-1.1-bin

The above build.xml example also assumes three empty directories exist, 'dist', 'lib', and
'src'.
Below is a validated WSDL Document following the Document/Literal Style. The name of this
file matches the name used in the WSDL2Java ant task above, LoginEndpoint.wsdl.

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


<definitions name="LoginService" targetNamespace="http://login"
xmlns:tns="http://login" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns2="http://login/types">
<types>
<schema targetNamespace="http://login/types"
xmlns:tns="http://login/types" xmlns:soap11-
enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<element name="returnWebLoginElement">
<complexType>
<sequence>
<element ref="tns:soap_session_idElement"/>
<element ref="tns:web_user_nameElement"/>
</sequence>
</complexType>
</element>
<element name="webLoginElement">
<complexType>
<sequence>
<element ref="tns:user_nameElement"/>
<element ref="tns:user_passwordElement"/>
</sequence>
</complexType>
</element>
<element name="user_nameElement" type="xsd:string"/>
<element name="user_passwordElement" type="xsd:string"/>
<element name="soap_session_idElement" type="xsd:string"/>
<element name="web_user_nameElement" type="xsd:string"/>
</schema>
</types>
<message name="LoginEndpoint_webLogin">
<part name="parameters" element="ns2:webLoginElement"/>
</message>
<message name="LoginEndpoint_webLoginResponse">
<part name="result" element="ns2:returnWebLoginElement"/>
</message>
36
<portType name="LoginEndpoint">
<operation name="webLogin">
<input message="tns:LoginEndpoint_webLogin"
name="LoginEndpoint_webLogin"/>
<output message="tns:LoginEndpoint_webLoginResponse"
name="LoginEndpoint_webLoginResponse"/>
</operation>
</portType>

<binding name="LoginEndpointBinding" type="tns:LoginEndpoint">


<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="webLogin">
<soap:operation soapAction="webLogin"/>
<input name="LoginEndpoint_webLogin">
<soap:body use="literal"/>
</input>
<output name="LoginEndpoint_webLoginResponse">
<soap:body use="literal"/>
</output>
</operation>
</binding>

<service name="LoginService">
<port name="LoginEndpointPort" binding="tns:LoginEndpointBinding">
<soap:address
location="http://localhost:8080/axis2/services/LoginService"/></port>
</service>
</definitions>

Place the above file, named LoginEndpoint.wsdl, in the directory 'wsdl' which is also inside
the 'bin' directory. Run the wsdl2java command via the ant task defined above (>ant
wsdl2java), and there will be a directory called 'output' created. This directory contains the
WSDL2Java generated source.
An important detail is that an XMLBean class file is also generated by WSDL2Java,
TypeSystemHolder.class. That file is placed into build/classes by the above ant task and will be
needed to compile the generated sources. A frequent problem is users get an error such as:

ClassNotFoundException : Cannot load SchemaTypeSystem. Unable to load


class with name
schemaorg_apache_xmlbeans.system.s68C41DB812F52C975439BA10FE4FEE54.TypeS
ystemHolder. Make sure the generated binary files are on the classpath.

The TypeSystemHolder.class generated by WSDL2Java must be placed in your classpath in


order to avoid this error.
The next step is to modify the generated Skeleton Java Source file - the Web service. This
file as generated returns null and needs to be updated to contain the business logic.
After the WSDL2Java command runs the file LoginEndpoint.wsdl, edit the following file:
output/src/org/example/types/LoginServiceSkeleton.java. You should see the following
code:

/**
* LoginServiceSkeleton.java
* This file was auto-generated from WSDL
*/
package org.example.types;

37
/**
* LoginServiceSkeleton java skeleton for the axisService
*/
public class LoginServiceSkeleton {
/**
* Auto generated method signature
* @param param0
*/
public login.types.ReturnWebLoginElementDocument webLogin
(login.types.WebLoginElementDocument param0 ) {
//Todo fill this with the necessary business logic
throw new java.lang.UnsupportedOperationException();
}
}

Replace the contents of this file with the following, which uses the complex types generated
by WSDL2Java and the example wsdl file:

/**
* LoginServiceSkeleton.java
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 1.0-RC4 Apr 28, 2006 (05:23:23 IST)
*/
package org.example.types;
import login.types.ReturnWebLoginElementDocument;
import login.types.ReturnWebLoginElementDocument.*;
import login.types.WebLoginElementDocument;
import login.types.WebLoginElementDocument.*;
/**
* Auto generated java skeleton by the Axis code generator
*/
public class LoginServiceSkeleton {
/**
* Auto generated method signature
* @param webLoginElementDocument changed from param0
*/
public ReturnWebLoginElementDocument webLogin(WebLoginElementDocument
webLoginElementDocument){

//Todo fill this with the necessary business logic


System.out.println("LoginServiceSkeleton.webLogin reached
successfully!");
// Get parameters passed in
WebLoginElement webLoginElement =
webLoginElementDocument.getWebLoginElement();
String userName = webLoginElement.getUserNameElement();
String password = webLoginElement.getUserPasswordElement();
System.out.println("LoginServiceSkeleton.webLogin userName: " +
userName);
System.out.println("LoginServiceSkeleton.webLogin password: " +
password);

// input paramaters would be used here


// prepare output
ReturnWebLoginElementDocument retDoc =
ReturnWebLoginElementDocument.Factory.newInstance();

ReturnWebLoginElement retElement =
ReturnWebLoginElement.Factory.newInstance();

38
retElement.setWebUserNameElement("joe sixpack");
retElement.setSoapSessionIdElement("some_random_string");
System.out.println("validate retElement: " + retElement.validate());

retDoc.setReturnWebLoginElement(retElement);
System.out.println("validate retDoc: " + retDoc.validate());

System.out.println("LoginServiceSkeleton.webLogin returning...");

return retDoc;
}
}

The next steps assume the axis2.war has been deployed and has expanded in a servlet
container.
Run the 'jar_wsdl' ant task from the example build.xml (>ant jar_wsdl), which generates a
jar file axis2_example_wsdl.jar in the 'bin/lib' directory. This jar will be used to compile the
client, and also will be placed in the servlet container.
Next, run the 'aar' ant task from the example build.xml (>ant aar), which generates the
deployable axis2 Web service. Place dist/LoginEndpoint.aar into axis2/WEB-INF/services . Place
lib/axis2_example_wsdl.jar into axis2/WEB-INF/lib . Verify the happy axis page loaded the
services correctly - there should be the service 'LoginEndpoint' with the available operation
'webLogin' displayed.
The last step is to create and run the client. In the src directory create the file
org.client.LoginClient.java, with the contents below:

package org.client;

import org.apache.axis2.AxisFault;
import login.types.ReturnWebLoginElementDocument;
import login.types.ReturnWebLoginElementDocument.*;
import login.types.WebLoginElementDocument;
import login.types.WebLoginElementDocument.*;
import org.example.types.LoginServiceStub;

//Login.
public class LoginClient {
public static void main(String[] args) {
try {
System.out.println("webLogin, firing...");
LoginServiceStub stub = new LoginServiceStub();

WebLoginElementDocument webLoginElementDocument =
WebLoginElementDocument.Factory.newInstance();
WebLoginElement webLoginElement =
WebLoginElement.Factory.newInstance();
webLoginElement.setUserNameElement("joe");
webLoginElement.setUserPasswordElement("sixpack");

webLoginElementDocument.setWebLoginElement(webLoginElement);

System.out.println("validate: " + webLoginElement.validate());


stub.webLogin(webLoginElementDocument);

ReturnWebLoginElementDocument returnWebLoginElementDocument =
stub.webLogin(webLoginElementDocument);

System.out.println("Client returned");

39
ReturnWebLoginElementDocument.ReturnWebLoginElement retElement =
returnWebLoginElementDocument.getReturnWebLoginElement();

System.out.println("WebUserName: " +
retElement.getWebUserNameElement());
System.out.println("SOAPSessionId: " +
retElement.getSoapSessionIdElement());
System.out.println("webLogin, completed!!!");

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

Now run the ant task 'runLogin' (>ant runLogin). The following output should appear:

runLogin:
[echo] running the webLogin client
[java] webLogin, firing...
[java] validate: true
[java] Client returned
[java] WebUserName: joe sixpack
[java] SOAPSessionId: some_random_string
[java] webLogin, completed!!!

Appendix
• Eclipse reference - http://www.eclipse.org/
• Custom Ant Tasks - http://ant.apache.org/manual/develop.html

Service Archive Generator Wizard Guide for Eclipse


Plug-in
This document will guide you through the installation and usage of the archive generator
Eclipse plug-in. Download Plugin Tool:
● http://ws.apache.org/axis2/tools/index.html

Content
• Introduction
• Installation
• Operation

Introduction
As part of the Axis2 tool set, the service archive generator is an important tool that allows
the generation of service archives ("aar" file or a "jar" files) that can be deployed as a web
services to the Axis2.

40
Installation
One can easily download (http://ws.apache.org/axis2/tools/index.html) the plugin.
If one needs to build the plug-in from source, Maven2 and Ant builds arevailabe. Please
refer the readme.txt located at module/tools on Axis2 source.
Once you've obtained the plug-in just unzip the content of the plug-in archive to the Eclipse
plug-in directory (if it is the zipped-binary version) or copy the necessary folders to the Eclipse
plug-in directory and restart Eclipse.
NOTE : This plug-in works on Eclipse version 3.1 and upwards, also the java version should
be 1.4 or higher. The provided screen shots may slightly differ with what the user would
actually see but the functionality has not been changed.

Operation
If the plug-in is properly installed you should see a new wizard under the "New" section.
(Use the File -> New -> Other or Ctrl + N )

Selecting the wizard and pressing the "Next" button will start the service generator wizard.
Following is the first page of the wizard.
Page 1:

41
Once the class file folder (which should be a folder in the file system) is browsed and
selected, the "Next" button will be enabled and you can move to the next page. Note that you
have the option of either including all the files or the class files only of the folder on page 1.
Page 2:
Page 2 of the wizard as seen below requires you to locate/browse the WSDL file. If you do
not wish to add a WSDL file to the service archive, select skip WSDL, else you can select the
location of the WSDL file by selecting the select WSDL option.

42
Page 3:
Select the services.xml file on this wizard page by browsing or select the option of
generating service xml automatically, after which you can click "Next" button to go to the next
page. Notice how the browsing option disables when the "Generate service xml automatically"
check box is ticked.

Page 4:
The next step is to add the libraries. The library addition page looks like this:

43
The library name (with full path) can be either typed on the text box or browsed for using
the "Browse" button.

Once there is a library name with full path on the text box, hit the "Add" button to add the
library to the list. Added libraries should be displayed in the "Added libraries" list box. This way
you can add as many external libraries as you wish. See the screen shots below.

44
If any added library needs to be removed, highlight it or in other words, select it from the
"Added libraries" list and hit on the "Remove" button as shown below. Click on the "Next"
button to proceed to the last page of the wizard if the user did not select to auto generate the
services.xml file. If user select to auto generate the services.xml file then the services.xml
option page will be displayed.

Page 5:
This page only appears if the user select to generate the services.xml at page 3 of the
wizard. If the user have selected a services.xml then the user will be directed to the last page
of the wizard.
After entering the correct service name and valid fully qualified class name, try to load the

45
existing methods of that class by clicking the load button.

If successfully loaded the user will be presented with a table at the bottom of the page with
the details of the loaded class. By checking and unchecking the user can select the necessary
methods to include in the services.xml

By clicking on the search declared method only check box, the user can remove the
inherited methods from the class. Click on the "Next" button to proceed to the last page of the
wizard

46
Page 6:
The last page of the wizard asks for the output file location and the output archive file
name. To be able to finish the wizard, user must enter valid output file location and output file
name.

Once all the parameters are filled, hit the "Finish" button to complete the wizard and
generate the service archive.

47
If you see the above message, then you've successfully generated the service archive! This
service archive can be hot deployed (deployed at run time) to the axis2

Appendix
• Eclipse reference - http://www.eclipse.org/
• Custom Ant Tasks - http://ant.apache.org/manual/develop.html

48
Code Generator Wizard Guide for Eclipse Plug-in
This document explains the usage of this code generator plug-in for Eclipse. In other words,
this document will guide you through the operations of generating a WSDL file from a Java
class and/or generating a Java class file from a WSDL file.Download Plugin Tool:
● http://ws.apache.org/axis2/tools/index.html

Content
• Introduction
• Installation
• Operation - WSDL2Java
• Operation - Java2WSDL

Introduction
The Axis2 code generator comes built-in with an Eclipse plug-in. This plug-in can be used to
generate a WSDL file from a java class (Java2WSDL) and/or a java class file from a WSDL
(WSDL2Java). First you need to install the plug-in. The instructions for the installation process
are given below.

Installation
One can easily download the plugin
If one needs to build the plug-in from source, Maven2 and Ant builds arevailabe. Please
refer the readme.txt located at module/tools on Axis2 source.
Once you've obtained the plug-in just unzip the content of the plug-in archive to the Eclipse
plug-in directory (if it is the zipped-binary version) or copy the necessary folders to the Eclipse
plug-in directory and restart Eclipse.
NOTE : This plug-in works on Eclipse version 3.1 and upwards, also the java version should
be 1.4 or higher. The provided screen shots may slightly differ with what the user would
actually see but the functionality has not been changed.

Operation - WSDL2Java
If the plug-in is properly installed you should see a new wizard under the "New" section.(use the
File -> New -> Other or Ctrl + N )

49
Selecting the wizard and pressing the "Next" button will start the code generator wizard.
Following is the first wizard page.
Page 1:

50
Selecting the "Generate Java source code from WSDL file" option and clicking "Next" leads
to the following page.
WSDL2Java Page 2 :

To move on to the next page the WSDL file location must be given. The "Browse" button can
be used to easily browse for a file rather than typing the whole path.
WSDL2Java Page 3 :
Once the WSDL file is selected, the next page will take you to the page from where
codegen options are to be selected. By far this is the most important page in this wizard.
This page determines the characteristics of the code being generated.
Novices need not worry about these options since the most common options are defaulted,
but advanced users will find it very easy to turn the knobs using these options.

51
What advanced users can do is select custom from the select codegen options drop down
list and then change/edit the fields that you need.

52
Once the options are selected, only the final step of the code generation is left which is the
selection of the output file location.
WSDL2Java Page 4 :
Here you can select the output file path by typing or browsing using the "Browse" button.
You have the option of browsing only eclipse workspace projects by selecting the "Add the
source to a project on current eclipse workspace" radio button. Or else you have the option to
save the codegen resutls to file system

53
Here also you have the option to add some value to the codegen results. If you have
enabled the check box "Add Axis2 libraries to the codegen result project" then all other
controls below will get enabled. What you can do is point the downloaded Axis2_HOME location
via the "Browse" button. Then you can verify the availability of the Axis2 libs by clicking on the
"Check Libs" button. If all goes well then you can add the axis 2 libs to the codegen results
location. Another option is available to generate a jar file if the user needs to add the codegen
results to a project as a compiled jar file to the selected locations lib directory.

54
When the output file location is selected, the "Finish" button will be enabled. Clicking the
"Finish" button will generate the code and a message box will pop up acknowledging the
success. Well Done! You've successfully completed Axis2 code generation.

Operation - Java2WSDL
Page 1:
For this operation you need to select the option which says "Generate a WSDL from a Java
source file"

55
Then click the "Next" button which will lead to the next page below.
Java2WSDL Page 2:

56
In this page one needs to select the class to be exposed and the relevant jar files /classes to
be loaded as the classpath. After the libraries have been set, the "Test Class Loading" button
must be clicked in order to test whether the class is loadable. Unless the class loading is
successful proceeding to the "Next" button will not be enabled.
Once the classloading is successful and "Next" button is clicked the page below will appear.
Java2WSDL Page 3:
This page allows the parameters to be modified by setting the options for the generator.

Java2WSDL Page 4:
Here you can select the output file path by typing or browsing using the "Browse" button.
You have the option of browsing only Eclipse workspace projects by selecting the "Add the
source to a project on current eclipse workspace" radio button . Or else you have the option to
save the codegen resutls to file system. Once the output file location and the output WSDL file
name is added you can click the "Finish" button to complete generation.

57
If a message box pops up acknowledging the success, then you've successfully completed
the Java2WSDL code generation.

Appendix
• Eclipse reference - http://www.eclipse.org/
• Custom Ant Tasks - http://ant.apache.org/manual/develop.html

58
Maven2 AAR Plug-in Guide

Introduction
This plugin generates an Axis 2 service file (AAR file). Download Plugin Tool:
● http://ws.apache.org/axis2/tools/index.html

Goals
The AAR plugin allows the packaging of an Axis 2 service aar in 3 different modes:
1. aar (default): generates the aar artifact
2. inplace : package the aar in the source tree
3. exploded : package an exploded aar application
Each mode is materialized by a goal. For instance, to generate an exploded aar from the
current project, one would type
mvn aar:exploded

Configuration
All AAR plugin goals takes the following configuration parameters as input:
Parameter
Default Value Description
Name
aarDirectory ${project.build.directory}/aar Directory where the aar file is built
Directory with compiled classes and
classesDirectory ${project.build.outputDirectory}
resources
Additional file sets, which are being added
fileSets to the archive. See "File Sets" below for an
example
Location of the services.xml file. By default,
it is assumed that the file is already present
servicesXmlFile
in classesDirectory/META-INF and no special
processing is required
Location of the WSDL file. By default, it is
assumed that the file is already present in
wsdlFile
classesDirectory/META-INF and no special
processing is required
Name, to which the WSDL file should be
wsdlFileName service.wsdl
mapped

The aar Goal


The aar goal allows the following additional parameters:
Parameter
Default Value Description
Name
outputDirectory ${project.build.directory} Directory where to generate the AAR file
aarName ${project.build.finalName} The generated AAR files name

59
A Maven archive configuration. This allows, for
archive
example, to configure the MANIFEST.MF file
A classifier, which should be added to the
generated AAR files name. Setting this parameter
classifier has the side effect, that the artifact is treated as
an attachment and not as the projects primary
artifact
Setting this property to false disables installation
primaryArtifact true or deployment of the artifact as the projects
primary artifact

File Sets
Additional file sets may be configured for inclusion into the AAR file. A file set looks as
follows:

<fileSets>
<fileSet>
<directory>src/aar/files</directory>
<outputDirectory>META-INF/docs</outputDirectory>
<includes>
<include>**/*.html</include>
</includes>
</fileSet>
<fileSet>
<directory>src/aar/files</directory>
<outputDirectory>META-INF/etc</outputDirectory>
<excludes>
<exclude>**/*.html</exclude>
</excludes>
</fileSet>
</fileSets>

The example specifies, that the contents of the directory src/aar/files shall be added to the
AAR file. HTML files will go into META-INF/docs, all other files to META-INF/etc.
A file set is configured through the following configuration parameters:
Parameter Name Description
directory The directory, from which to read the file set. This parameter is required
The target directory within the AAR file. Defaults to the AAR files root
outputDirectory
directory
Configures the set of files, which shall be included into the AAR file.
includes
Defaults to **/*
Configures a set of files, which shall be excluded from the file set.
excludes Defaults to the Maven default excludes (**/*~, **/cvs/**/*,
**/.svn/**/*, etc.)
skipDefaultExcludes If this parameter is set to true, then no default excludes are being used

Maven2 Java2WSDL Plug-in Guide

Introduction
This plugin takes as input a Java class and generates a WSDL, which describes a Web
service for invoking the classes methods. Download Plugin Tool:

60
● http://ws.apache.org/axis2/tools/index.html

Goals
The Java2WSDL plugin offers a single goal:
• java2wsdl (default): Reads a java class and generates a WSDL for invoking the
classes methods as a Web service.
To run the plugin, add the following section to your POM (Project Object Model):

<build>
<plugins>
<plugin>
<groupId>org.apache.axis2.maven2</groupId>
<artifactId>axis2-java2wsdl-maven-plugin</artifactId>
<configuration>
<className>com.foo.myservice.MyHandler</className>
</configuration>
<executions>
<execution>
<goals>
<goal>java2wsdl</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

The plugin will be invoked automatically in the generate-resources phase. You can also
invoke it directly from the command line by running the command:
mvn java2wsdl:java2wsdl

The Java2WSDL Goal


By default, the plugin reads the given Java class and creates a file target/generated-
resources/java2wsdl/service.xml. The Java class is given by the configuration element
className above.

Configuration
The Java2WSDL goal takes the following parameters as input. All parameters can be set
from the command line by using properties. For example, the parameter "className" may be
set using the property "axis2.java2wsdl.className". If the parameter isn't set via property or
in the POM, then a default value applies.
Default
Parameter name Command line property Description
value
Fully qualified name of the
class, which is being read
className ${axis2.java2wsdl.className}
and transformed into a
WSDL
${axis2.java2wsdl.outputFileName Path of the generated
outputFileName
} service file.
schemaTargetName ${axis2.java2wsdl.schemaTargetN Target namespace of the
space amespace} generated schema.

61
Prefix, which is being
schemaTargetName ${axis2.java2wsdl.schemaTargetN
associated with the
spacePrefix amespacePrefix}
schemas target namespace.
Unqualifie
d name
Name of the generated Web
serviceName ${axis2.java2wsdl.serviceName} of the
service.
input
class.
Default
${axis2.java2wsdl.targetNamespa Target namespace of the
targetNamespace namespac
ce} generated WSDL
e
Prefix, which is being
targetNamespacePr ${axis2.java2wsdl.targetNamespa
associated with the target
efix cePrefix}
namespace

Maven2 WSDL2Code Plug-in Guide

Introduction
This plugin takes as input a WSDL and generates client and server stubs for calling or
implementing a Web service matching the WSDL.Download Plugin Tool:
● http://ws.apache.org/axis2/tools/index.html

Goals
The WSDl2Code offers a single goal:
• wsdl2code (default): Reads the WSDL and generates code.
To run the plugin, add the following section to your POM (Project Object Model):

<build>
<plugins>
<plugin>
<groupId>org.apache.axis2.maven2</groupId>
<artifactId>axis2-wsdl2code-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>wsdl2code</goal>
</goals>
</execution>
<configuration>
<packageName>com.foo.myservice</packageName>
</configuration>
</executions>
</plugin>
</plugins>
</build>

The plugin will be invoked automatically in the generate-sources phase. You can also invoke
it directly from the command line by running the command
mvn wsdl2code:wsdl2code

62
The WSDL2Code Goal
By default, the plugin reads the file src/main/axis2/service.wsdl. Sources for the Java
programming language and the ADB data binding are generated into target/generated-
sources/axis2/wsdl2code. Note the configuration element packageName above, which
sets the package name, thus a subdirectory.

Configuration
The WSDL2Code goal takes the following parameters as input. All parameters can be set
from the command line by using properties. For example, the parameter "generateServerSide"
may be set using the property "axis2.wsdl2code.generateServerSide". If the parameter isn't
set via property or in the POM, then a default value applies.
Command Line Default
Parameter Name Description
Property Value
Data binding framework, which is
${axis2.wsdl2code.data
databindingName being used by the generated adb
bindingName}
sources.
Whether to generate simply all
${axis2.wsdl2code.gene classes. This is only valid in
generateAllClasses false
rateAllClasses} conjunction with
"generateServerSide".
${axis2.wsdl2code.gene Whether server side sources are
generateServerSide false
rateServerSide} being generated.
${axis2.wsdl2code.gene
generateServerSideInte Whether to generate the server
rateServerSideInterface false
rface side interface.
}
${axis2.wsdl2code.gene Whether a "services.xml" file is
generateServicesXml false
rateServicesXml} being generated.
${axis2.wsdl2code.gene Whether a test case is being
generateTestcase false
rateTestCase} generated.
${axis2.wsdl2code.lang Programming language of the
language java
uage} generated sources.
Map of namespace URI to
packages in the format
uri1=package1,uri2=package2,...
Using this parameter is
${axis2.wsdl2code.nam
namespaceToPackages discouraged. In general, you
espaceToPackages}
should use the namespaceUris
parameter. However, the latter
cannot be set on the command
line.
Map of namespace URI to
packages. Example:
<namespaceURIs>
<namespaceURI>
namespaceURIs
<uri>uri1</uri>
<package>package1</package>
</namespaceURI> ........
</namespaceURI>
Target directory, where sources
${axis2.wsdl2code.targe
outputDirectory are being target/generated-
t}
sources/axis2/wsdl2code

63
generated.
${axis2.wsdl2code.pack Package name of the generated
packageName
age} sources.
Port name, for which sources are
${axis2.wsdl2code.port being generated. By default,
portName
Name} sources are generated for all
ports.
Service name, for which sources
${axis2.wsdl2code.servi are being generated. By default,
serviceName
ceName} sources are generated for all
services.
Sync mode, for which sources are
${axis2.wsdl2code.sync
syncMode being generated; either of "sync", both
Mode}
"async", or "both" (default).
${axis2.wsdl2code.unpa
unpackClasses Whether to unpack classes.
ckClasses}
src/main
${axis2.wsdl2code.wsdl Location of the WSDL file, which /axis2/s
wsdlFile
} is read as input ervice.w
sdl

Migrating from Apache Axis 1.x to Axis2


For all those users who are familiar with Axis 1.x series will be assisted through this
document to switch to Axis2 series. We begin by listing the improvements in Axis2 in
comparison with Axis1. This is followed by guidelines for the migration.
Send your feedback or questions to: axis-dev@ws.apache.org. (Subscription details are
available on the Axis2 site.) Kindly prefix subject with [Axis2].

Content
• Compatibility
• Getting Started
• Custom Deployment of Services, Handlers and Modules
• Transports for HTTP Connection
• Data Binding Support
• Best Usage

Compatibility
Axis1.x and Axis2 have evolved from different architectures.
Speed - Axis2 is based on StAX API, which gives greater speed than SAX event based
parsing that has been used in Axis1.x.
Stability - Axis2 has fixed phases as well as user-defined phases for extensions. This allows
far more stability as well as flexibility than Axis1.x.
Transport framework - Simple abstraction in the designing of transports (i.e., senders
and listeners for SOAP over various protocols such as SMTP, etc), allows far more flexibility and
the core of the engine is completely transport-independent.
WSDL support - Axis2 supports versions 1.1 and 2.0, which allow you to create stubs and

64
skeletons to manipulate the web services arena.
Component - oriented architecture - The components are .mar and .aar archives . Easily
reusable components such as handlers and modules allow pattern processing for your
applications or distribution to partners. Axis2 is more concerned on the "Module" concept
rather the "Handler" concept. Modules contain handlers that have been ordered through the
phase rules. These are ordered to specific service(s).

Getting Started
Let's look at a simple example of echoing at client API.
Axis 1.x

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
public class TestClient {
public static void main(String [] args) {
try {
String endpoint ="http://ws.apache.org:5049/axis/services/echo";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(new QName("http://soapinterop.org/",
echoString"));
String ret = (String) call.invoke( new Object[] { "Hello!" } );
System.out.println("Sent 'Hello!', got '" + ret + "'");
} catch (Exception e) { System.err.println(e.toString()); } } }

Axis 2

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.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
public class EchoBlockingClient {
private static EndpointReference targetEPR = new
EndpointReference("http://127.0.0.1:8080/axis2/services/MyService");
public static void main(String[] args) {
try {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace ns = fac.createOMNamespace("http://soapinterop.org/",
"ns1");
OMElement payload = fac.createOMElement("echoString", ns);
payload.setText("Hello!");
Options options = new Options();
ServiceClient client = new ServiceClient();
options.setTo(targetEPR);
//Blocking invocation
OMElement result = client.sendReceive(payload);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
} } }

65
It has been clearly depicted that the invocation in Axis2 is dealt with the SOAP body
element itself. Here the invocation is synchronous, but Axis2 can handle asynchronous
invocations as well. The "payload" variable above contains the SOAP body element which
should go in the SOAP envelope.
Once the service is called through the stub in Axis2, the "payload" will be according to the
data binding framework that will be used. So the extra work of "payload" will vanish.
Apart from synchronous invocation, Axis2 also supports asynchronous invocation through
sendReceiveNonblocking(). Synchronous/Asynchronous invocations can handle both single and
double HTTP connections.
With this advanced architecture, Axis2 is capable of handling megabytes of requests and
responses, which is far from the capabilities of Axis1.x.

Custom Deployment of Services, Handlers, and


Modules
In Axis 1.x, the deployment of services was via WSDD, which in my opinion was highly
cumbersome. Service deployment in Axis2 is straight forward and dynamic. Dynamic behavior
is from the "Administrator" facility given by the development in the server side. It's just a
matter of creating the .aar file and deploying it. More details regarding this is given in the
Axis2 user guide.
Axis2 has moved away from the "Handler concept" and is more into the "Module concept".
Abstractly speaking, the module concept is a collection of handlers with rules that govern
which modules are created as .mar files. It has module.xml, which is the brain behind
manipulating the handlers.
When a service is called through a handler, it is just a matter of giving a reference to the
module that includes the handler in the services.xml (using <module ref="foo/>").
Services are hot deployable in Axis2, but modules are not. This is one feature which is
unique to Axis2.
Let's take a detailed look at what it takes to migrate the Axis 1.x handlers to the Axis 2
modules via the "SOAP Monitor". The SOAP monitor is really a combination of three
components: An applet which displays responses/requests, a servlet which binds to a default
port of 5001 and connects to the applet, and a handler chain used to intercept the SOAP
messages. Here we'll focus on the handler.
Axis 1.x required two WSDD's to use the SOAP Monitor. First, the SOAP Monitor
Handler itself:

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<handler name="soapmonitor"
type="java:org.apache.axis.handlers.SOAPMonitorHandler">
<parameter name="wsdlURL"
value="/wzs/SOAPMonitorService-impl.wsdl"/>
<parameter name="namespace"
value="http://tempuri.org/wsdl/2001/12/SOAPMonitorService-impl.wsdl"/>
<parameter name="serviceName" value="SOAPMonitorService"/>
<parameter name="portName" value="Demo"/>
</handler>
<service name="SOAPMonitorService" provider="java:RPC">
<parameter name="allowedMethods" value="publishMessage"/>
<parameter name="className"
value="org.apache.axis.monitor.SOAPMonitorService"/>
<parameter name="scope" value="Application"/>
</service>
</deployment>

66
Axis 1.x requires a reference to the handler in the user's WSDD that defines their
Web Service:

<deployment name="example" xmlns="http://xml.apache.org/axis/wsdd/"


xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="urn:myService" provider="java:RPC">
<parameter name="className" value="org.MyService"/>
<parameter name="allowedMethods" value="*"/>

<requestFlow>
<handler type="soapmonitor"/>
</requestFlow>
<responseFlow>
<handler type="soapmonitor"/>
</responseFlow>

</service>
</deployment>

Axis 2 requires a module.xml, placed inside a jar with a .mar extension under
WEB-INF/modules, to define a Handler:

<module name="soapmonitor"
class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorModule">
<inflow>
<handler name="InFlowSOAPMonitorHandler"
class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorHandler">
<order phase="soapmonitorPhase"/>
</handler>
</inflow>

<outflow>
<handler name="OutFlowSOAPMonitorHandler"
class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorHandler">
<order phase="soapmonitorPhase"/>
</handler>
</outflow>

<Outfaultflow>
<handler name="FaultOutFlowSOAPMonitorHandler"
class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorHandler">
<order phase="soapmonitorPhase"/>
</handler>
</Outfaultflow>

<INfaultflow>
<handler name="FaultInFlowSOAPMonitorHandler"
class="org.apache.axis2.handlers.soapmonitor.SOAPMonitorHandler">
<order phase="soapmonitorPhase"/>
</handler>
</INfaultflow>
</module>

The SOAPMonitorModule referenced above simply implements the


org.apache.axis2.modules.Module, and is used for any additional tasks needed to initialize the
module and shutdown the module. In this situation, nothing is needed and the implemented
interface methods have blank bodies. Furthermore, the 'soapmonitorPhase' will be used later
(below) in the axis2.xml .

67
Axis 1.x the SOAPMonitorHandler has the class signature as:
● public class SOAPMonitorHandler extends BasicHandler
Axis 2 the SOAPMonitorHandler has the class signature as:
● public class SOAPMonitorHandler extends AbstractHandler
In Axis2, you need to reference the module that contains the handler chain that
you want to use inside your services.xml:

<service name="ExampleService">
<module ref="soapmonitor"/>
<description>
This service has the SOAP Monitor wired in
</description>
<parameter name="ServiceClass"
locked="false">org.ExampleService</parameter>
<operation name="myExecute">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>

Finally, Axis2 requires you to make some changes to axis2.xml. Start by adding a
global module:
● <module ref="soapmonitor"/>
Then define your phase orders for the 'soapmonitorPhase' referenced in the
module.xml:

<phaseOrder type="inflow">
<!-- Global 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="Dispatch"/>
</handler>
</phase>

68
<!-- Global Phases -->
<!-- After Dispatch phase module author or service author can add any
phase he wants -->
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="outflow">
<!-- user can add his own phases to this area -->
<!-- Global phases -->
<!-- these phases will run irrespective of the service -->
<phase name="MessageOut"/>
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<phase name="PolicyDetermination"/>
<!-- Global phases -->
</phaseOrder>

<phaseOrder type="INfaultflow">
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<!-- user can add his own phases to this area -->
</phaseOrder>

<phaseOrder type="Outfaultflow">
<!-- user can add his own phases to this area -->
<!-- Global phases -->
<phase name="MessageOut"/>
<phase name="userphase1"/>
<phase name="soapmonitorPhase"/>
<phase name="PolicyDetermination"/>
<!-- Global phases -->
</phaseOrder>

See the user guide for more information on Axis2 modules.

Transports for HTTP Connection


Axis2 comes with the CommonsHTTPTransportSender which is based on commons-
httpclient.
It should be noted that axis2.xml should be configured to call the commons transports with
the statement,

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

Data Binding Support


ADB is used to provide data binding support. In Axis2, XML is manipulated via AXIOM, which
is based on the StAX API. XML gives full schema support. Thus, serialization and de-
serialization of XML is handled in Axis2 via the xml-data binding framework.

69
Below is an example of migrating an WSDL based Axis 1.x Web Service to Axis2.
First, let's take a look at a simple document/literal style WSDL used in an Axis 1.x Web
Service. This example assumes the name simple.wsdl for the WSDL below:

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


<definitions name="SimpleService" targetNamespace="http://simpleNS"
xmlns:tns="http://simpleNS"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:ns2="http://simpleNS/types">
<types>
<schema targetNamespace="http://simpleNS/types"
xmlns:tns="http://simpleNS/types"
xmlns:soap11-enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<element name="simpleLogin">
<complexType>
<sequence>
<element name="user_name" type="xsd:string"/>
<element name="user_password" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="simpleLoginResponse">
<complexType>
<sequence>
<element name="soap_session_id" type="xsd:string"/>
<element name="web_user_name" type="xsd:string"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="SimpleEndpoint_simpleLogin">
<part name="parameters" element="ns2:simpleLogin"/>
</message>
<message name="SimpleEndpoint_simpleLoginResponse">
<part name="result" element="ns2:simpleLoginResponse"/>
</message>
<portType name="SimpleEndpoint">
<operation name="simpleLogin">
<input message="tns:SimpleEndpoint_simpleLogin"
name="SimpleEndpoint_simpleLogin"/>
<output message="tns:SimpleEndpoint_simpleLoginResponse"
name="SimpleEndpoint_simpleLoginResponse"/>
</operation>
</portType>

70
<binding name="SimpleEndpointBinding" type="tns:SimpleEndpoint">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="simpleLogin">
<soap:operation soapAction="simpleLogin"/>
<input name="SimpleEndpoint_simpleLogin">
<soap:body use="literal"/>
</input>
<output name="SimpleEndpoint_simpleLoginResponse">
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="SimpleService">
<port name="SimpleEndpointPort" binding="tns:SimpleEndpointBinding">
<soap:address
location="http://localhost:8080/axis/services/SimpleEndpointPort"/>
</port>
</service>
</definitions>

The next step is to run WSDL2Java on the wsdl. For axis 1.x, this example uses the
following Ant task:

<target name="wsdl2java" description="axis 1.x">


<delete dir="output" />
<mkdir dir="output" />
<axis-wsdl2java output="output" verbose="true" url="wsdl/simple.wsdl"
serverside="true" skeletondeploy="true" nowrapped="true">
</axis-wsdl2java>
</target>

The Axis 1.x Ant task above takes the simple.wsdl under the directory 'wsdl' , and from that
creates files under the directory 'output'. The files created are shown below:

output/
output/simpleNS
output/simpleNS/types
output/simpleNS/types/SimpleLoginResponse.java
output/simpleNS/types/SimpleLogin.java
output/simpleNS/SimpleEndpoint.java
output/simpleNS/SimpleEndpointBindingStub.java
output/simpleNS/SimpleEndpointBindingSkeleton.java
output/simpleNS/SimpleEndpointBindingImpl.java
output/simpleNS/SimpleService.java
output/simpleNS/SimpleServiceLocator.java
output/simpleNS/deploy.wsdd
output/simpleNS/undeploy.wsdd

Now let's run WSDL2Java with Axis2. In this example, the only change to simple.wsdl
required for Axis2 is that 'soap:address location' be changed to:

71
<soap:address
location="http://localhost:8080/axis2/services/SimpleEndpoint"/>
</port>
</service>
</definitions>

In Axis2, the default databinding uses ADB. However, XMLBeans and JaxMe are also
supported. This example uses XMLBeans. For Axis2, our example uses the following Ant task:

<target name="wsdl2java">
<delete dir="output" />
<java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">
<classpath refid="axis.classpath"/>
<arg value="-d"/>
<arg value="xmlbeans"/>
<arg value="-uri"/>
<arg file="wsdl/simple.wsdl"/>
<arg value="-ss"/>
<arg value="-g"/>
<arg value="-sd"/>
<arg value="-o"/>
<arg file="output"/>
<arg value="-p"/>
<arg value="org.simple.endpoint"/>
</java>

<!-- Move the schema folder to classpath-->


<move todir="${build.classes}">
<fileset dir="output/resources">
<include name="*schema*/**/*.class"/>
<include name="*schema*/**/*.xsb"/>
</fileset>
</move>
</target>

For an explanation of the Axis2 WSDL2Java Ant task and its options, see the
CodegenToolReference Guide.
A feature of XMLBeans is that there is one class file created with WSDL2java, and a series of
.xsb files. They must be referenced when compiling, and as the example shows, these files are
moved to a build directory.
The Axis2 WSDL2Java example also takes the simple.wsdl, which is under the directory
'wsdl', and creates files under the directory 'output'. The relevant non-xmlbean files created
are shown below:

72
output/resources/services.xml
output/src/org/simple
output/src/org/simple/endpoint
output/src/org/simple/endpoint/SimpleEndpointSkeleton.java
output/src/org/simple/endpoint/SimpleEndpointMessageReceiverInOut.java
output/src/org/simple/endpoint/SimpleEndpointCallbackHandler.java
output/src/org/simple/endpoint/SimpleEndpointStub.java
output/src/simplens
output/src/simplens/types
output/src/simplens/types/SimpleLoginDocument.java
output/src/simplens/types/impl
output/src/simplens/types/impl/SimpleLoginDocumentImpl.java
output/src/simplens/types/impl/SimpleLoginResponseDocumentImpl.java
output/src/simplens/types/SimpleLoginResponseDocument.java

The first important distinction is that while the Axis 1.x example generated deploy.wsdd and
undeploy.wsdd, the Axis2 example created a services.xml. The files deploy.wsdd and
services.xml are a breed apart, coming from different architectures. There is no direct parallel
between them. See the Axis2 user guide for an explanation about services.xml
Now we're ready to code. We'll start with Axis 1.x on the service side. To implement the
business logic, we'll change simpleNS/SimpleEndpointBindingImpl.java from:

package simpleNS;

public class SimpleEndpointBindingImpl implements


simpleNS.SimpleEndpoint{
public simpleNS.types.SimpleLoginResponse
simpleLogin(simpleNS.types.SimpleLogin parameters)
throws java.rmi.RemoteException {
return null;
}
}

To:

package simpleNS;

public class SimpleEndpointBindingImpl implements


simpleNS.SimpleEndpoint{
public simpleNS.types.SimpleLoginResponse
simpleLogin(simpleNS.types.SimpleLogin parameters)
throws java.rmi.RemoteException {

String userName = parameters.getUser_name();


String password = parameters.getUser_password();
// do something with those vars...
return new simpleNS.types.SimpleLoginResponse("mySessionID",
"username");
}
}

In Axis 1.x, the next step is to compile the classes and put them in the Axis.war, and then
run the admin client with the generated deploy.wsdd. You then look at the happy axis page to
verify that the service has been installed correctly.
Now let's code Axis2. In Axis 1.x, while the Ant task shown in the example created a
skeleton, a peek inside shows that the skeleton calls the binding implementation class. In

73
Axis2, we work with the skeleton directly. To implement the business logic in the generated
Axis2 classes, we'll change org/simple/endpoint/SimpleEndpointSkeleton.java from:

package org.simple.endpoint;
/**
* SimpleEndpointSkeleton java skeleton for the axisService
*/
public class SimpleEndpointSkeleton {

/**
* Auto generated method signature
* @param param0
*/
public simplens.types.SimpleLoginResponseDocument
simpleLogin(simplens.types.SimpleLoginDocument param0 ) throws Exception
{
//Todo fill this with the necessary business logic
throw new java.lang.UnsupportedOperationException();
}
}

To:

package org.simple.endpoint;

import simplens.types.*;
import simplens.types.SimpleLoginResponseDocument.*;
import simplens.types.SimpleLoginDocument.*;
/**
* SimpleEndpointSkeleton java skeleton for the axisService
*/
public class SimpleEndpointSkeleton {

/**
* Modified
* @param simpleLoginDocument
*/
public SimpleLoginResponseDocument
simpleLogin(simplens.types.SimpleLoginDocument simpleLoginDocument){
//Todo fill this with the necessary business logic

SimpleLoginResponseDocument retDoc =
SimpleLoginResponseDocument.Factory.newInstance();

SimpleLoginResponse retElement =
SimpleLoginResponse.Factory.newInstance();
// Get parameters passed in
SimpleLogin simpleLogin = simpleLoginDocument.getSimpleLogin();
String userName = simpleLogin.getUserName();
String password = simpleLogin.getUserPassword();
// do something with those variables...

retElement.setWebUserName(userName);
retElement.setSoapSessionId("my random string");
retDoc.setSimpleLoginResponse(retElement);
return retDoc;
}
}

74
In Axis2, the next step is to compile the classes, put them along with the generated
services.xml in an AAR, and then hot deploy the AAR by placing it in the Axis2.war under WEB-
INF/services. Point a browser to http://localhost:8080/axis2/listServices, and you should see
the service 'SimpleService' ready for action. See the Axis2 user guide for more info.
The last step is the client. Our Axis 1.x client for this example is:

package org;

import simpleNS.*;
import simpleNS.types.*;

public class Tester {


public static void main(String [] args) throws Exception {
// Make a service
SimpleService service = new SimpleServiceLocator();

// Now use the service to get a stub which implements the SDI.
SimpleEndpoint port = service.getSimpleEndpointPort();

// set the params


SimpleLogin parameters = new SimpleLogin("username","password");
// Make the actual call
SimpleLoginResponse simpleLoginResponse =
port.simpleLogin(parameters);
String session = simpleLoginResponse.getSoap_session_id();
String user = simpleLoginResponse.getWeb_user_name();
System.out.println("simpleLoginResponse, session: " + session + ",
user: " + user);
}
}

Finally, our Axis2 client for this example is:

package org;
import simplens.types.*;
import simplens.types.SimpleLoginDocument.*;
import simplens.types.SimpleLoginResponseDocument.*;
import simplens.types.impl.*;
import org.simple.endpoint.*;

public class Tester {


public static void main(String [] args) throws Exception {

// you may not need to pass in the url to the constructor


// try the default no arg one
SimpleEndpointStub stub = new SimpleEndpointStub(null,
"http://localhost:8080/axis2/services/SimpleService");

SimpleLogin simpleLogin = SimpleLogin.Factory.newInstance();


simpleLogin.setUserName("userName");
simpleLogin.setUserPassword("password");

SimpleLoginDocument simpleLoginDocument =
SimpleLoginDocument.Factory.newInstance();

simpleLoginDocument.setSimpleLogin(simpleLogin);

75
SimpleLoginResponseDocument simpleLoginResponseDocument =
stub.simpleLogin(simpleLoginDocument);

SimpleLoginResponse simpleLoginResponse =
simpleLoginResponseDocument.getSimpleLoginResponse();
String session = simpleLoginResponse.getSoapSessionId();
String user = simpleLoginResponse.getWebUserName();
System.out.println("simpleLoginResponse, session: " + session + ",
user: " + user);

}
}

Axis2 clients also have asynchronous options via a Callback and alternatively a 'Fire and
forget'. See the user guide for more details.

Best Usage
Axis1.x and Axis2 have different ways of seeing the SOAP stack. So the best way to migrate
is to follow the User's Guide and the Architecture Guide of Axis2 properly. Axis2 is very straight
forward and friendly to use than its predecessor.

Design Notes
Axis2 RPC Support
This document describes Axis2's Remote Procedure Call support in a set of easy to
understand implementation steps.

Introduction
Axis2 Remote Procedure Call (RPC) support may seem somewhat tricky and confusing at
first glance. However, Axis2 RPC strategy is based on a set of well defined rules. This
document aims to drill down to the details of the strategy and resolve most of the unknown
bits and pieces. Note that Axis2 currently does not support the rpc/encoded style fully. Its
main support is for the rpc/lit style.
We will discuss the Axis2 RPC strategy in the following steps

Step 1 - Converting RPC Style WSDL's into Doc/Lit Style WSDL


This is probably the most confusing part of the RPC strategy. Since the Axis2 code generator
is based on pure doc/lit style, the first step of the code generation process is to generate a
wrapper schema. This wrapper generation can be easily explained by using an example.
Take the following piece of WSDL

76
.....
< message name="requestMessage">
<part name="part1" type="xs:string"/>
<part name="part2" type="xs:int"/>
</message>
<message name="responseMessage">
<part name="part1" type="xs:string"/>
</message>
<portType name="echoPortType">
<operation name="echo">
<input message="y:requestMessage"/>
<output message="y:responseMessage"/>
</operation>
</portType>

<binding name="echoBinding" type="y:echoPortType">


<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="echo">
<soap:operation soapAction="echo"/>
<input> <soap:body use="literal"/> </input>
<output> <soap:body use="literal"/> </output>
</operation>
</binding>
.....

The binding says its got to be rpc/lit and in this case the message parts need wrapping in
the following order.
1. The first element needs to have the operation name as the local name and the
operation namespace. (This happens to be the namespace of the porttype - in this case
the targetnamespace of the WSDL.)
2. The children of this element are non namespace qualified elements with the part
names as local names (referred to as part element)
3. In case the part refers to a standard type like the example WSDL, the content of the
part element would be of that type. If the part refers to a complex type defined in the
schema, the content of the part element becomes of that type. Having an element
reference in the part when the binding is rpc is invalid.
For example, the input wire message for the echo operation mentioned in the above WSDL
fragment would look like this:

<op: xmlns:op="porttype namespace">


<>Hello World</part1>
<>123</part2>
</op:echo>

Note that the element name is in bold. The first one is the operation name, the second and
third are part names. It can be seen that it is possible to generate a schema representing this
structure, and then treat the whole service as a pure doc/lit service. In this case, the following
piece of schema is generated to make the rpc to doc conversion. Note that in this case the wire
message stays unchanged. It is only a different WSDL authoring style

77
<xs:element name="echo">
<xs:complexType>
<xs:sequence>
<xs:element name="part1" type="xs:string" />
<xs:element name="part2" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>

What the Axis2 code generator does is exactly this. By looking at the binding style, it
generates a wrapper schema in places required before handing over the Axis* hierarchy to the
code generator engine. In every case (even when the schema needs to be unwrapped) this
wrapping part will take place!

Step 2 - Unwrapping the Schema


If the schema needs to be unwrapped, it brings up a few issues. This is mainly because the
only thing that the emitters rely on when generating code is a mapping table.
1. When the schema is unwrapped, where will the unwrapping information remain?
There has to be a store to keep the information seperated. The Axis * hierarchy ca be
used for this. It has nicely separated information holders and a parameter store that
can hold an information bean.
2. How do we maintain uniqueness among message part names?
Part names are only unique across a message and not globally. However, due to the fact
that we have a global mapping table, we need a way to differentiate between parts of
different messages. The technique used here is to generate a QName that has the
operation name as a namespace and a suffix (like _input) appended to the local name.
Given these solutions, the first step in unwrapping is to walk the schema and figure out the
unwrappable items. The key player of the unwrapping process is the unwrapping extension. It
walks a given schema and figure out the unwrappable parts if there are any.
The current unwrapper looks for the following patterns and fails if it is not found!

<element>
<complexType>
<sequence>
<element/>
</sequence>
</complexType>
</element>

Once this pattern is detected, the unwrapper details will be added to the relevant
AxisMessage component.

Step 3 - Populate Type Information


The next step is to populate the Type information for the parts. This has to be explicitly
done by the data binding extensions, and currently the ADB and XMLbeans extensions
populate the relevant AxisMessage by looking up their generated type systems. This type
information goes into the AxisMessage inside a MessagePartInformationHolder instance.
The following code fragment from the ADB extension shows how the AxisMessages get
populated with the relevant type information. The code is almost the same for the XMLBeans
extension. Note the items in bold.

78
if (message.getParameter(Constants.UNWRAPPED_KEY) != null) {
XmlSchemaType schemaType = message.getSchemaElement().getSchemaType();
if (schemaType instanceof XmlSchemaComplexType) {
XmlSchemaComplexType cmplxType = (XmlSchemaComplexType) schemaType;
XmlSchemaParticle particle = cmplxType.getParticle();
if (particle instanceof XmlSchemaSequence) {
XmlSchemaObjectCollection items = ((XmlSchemaSequence)
particle).getItems();
for (Iterator i = items.getIterator(); i.hasNext();) {
Object item = i.next();
if (item instanceof XmlSchemaElement) {
XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) item;
XmlSchemaType eltSchemaType =
xmlSchemaElement.getSchemaType();
if (eltSchemaType != null) { }
else if (xmlSchemaElement.getSchemaTypeName() != null) {
eltSchemaType = findSchemaType(schemaMap,
xmlSchemaElement.getSchemaTypeName());
if (eltSchemaType!=null){
populateClassName(eltSchemaType,mapper,opName,xmlSchemaEle
ment.getName());
}
}
}
}
}
}
}

The populateClassName looks like this

private static void populateClassName(XmlSchemaType eltSchemaType,


TypeMapper typeMap, String opName, String partName) {
Map metaInfoMap = eltSchemaType.getMetaInfoMap();
if (metaInfoMap != null) {

if(Boolean.TRUE.equals(metaInfoMap.get(
SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_PRIMITVE_KEY))){
//this type is primitive - add that to the type mapper status
//for now lets add a boolean
typeMap.addTypeMappingStatus(partQName,Boolean.TRUE);
}
}
}

Step 4 - Generate Code with Unwrapped Parameters


The next step is generating the actual code. The AxisServiceBasedMultiLanguageEmitter has
a method that generates the XML model for the input parameters, and that method includes
the relevant part parameters inside the relavant top level input parameter element.
The relevant part of the XML model looks like this. Note that this intermediate XML model is
the one that is parsed against the Stylesheets to generate the code.

79
<input>
<param name="param4" type="com.example.www.ServiceNameStub.Echo"
shorttype="Echo" value="null" location="body" opname="echo">
<param name="param5" type="java.lang.String" shorttype="String"
value="null" location="body" opname="echo" partname="Part1"
primitive="yes"/>
<param name="param6" type="int" shorttype="int" value="0"
location="body" opname="echo" partname="Part2" primitive="yes"/>
</param>
</input>

The next part is handled by the template. Basically, the template looks after the generation
of multiple parameters into the method signatures, and then the generating of the relevant
serialization and deserialization code for the parameters.

Bringing the Parameters Together and Exploding Them


This is a somewhat controversial area. The current Axis2 code generator does the wrapping
and unwrapping at the object level and not the XML level. In short, the exploded parameters
are only a convenience and the explosion does not run down to the XML level. The following
example of generated source code makes this clear:

private org.apache.axiom.soap.SOAPEnvelope
toEnvelope(org.apache.axiom.soap.SOAPFactory factory, String param1, int
param2, boolean optimizeContent) {

rg.apache.axiom.soap.SOAPEnvelope emptyEnvelope =
factory.getDefaultEnvelope();
emptyEnvelope.getBody().addChild(wrappedType.getOMElement(com.example.
www.ServiceNameStub.Echo.MY_QNAME, factory));
return emptyEnvelope;
}

Note the lines in bold. The wrapped class will anyway be instantiated and used at the end,
but what the user sees is different. Exploding the parameters happens in a similar way!

Conclusion
Axis2 RPC support is sort of a misty area, but it is based on a well defined set of rules which
makes it not that misty after all!

80

Das könnte Ihnen auch gefallen