You are on page 1of 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 WSAddressing 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 WEBINF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2soapmonitor-*.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/wsreliablemessaging200502.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 OutflowSecurity Parameter InflowSecurity Parameter

Rampart-1.0 Configuration
• •

• •

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 WSSecurityPolicy. 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 invoked more than once in the outflow one can provide configuration for invocations. The 'action' element describes one of these configurations. 'OutflowSecurity' parameter can contain more than one 'action' elements. The 'action' element is available here:

handler can be each of these Therefore the schema of this

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 items Description Example

Add a Timestamp, Sign the SOAP body and Encrypt the SOAP body Security actions for the inflow <items> Timestamp Signature Encrypt</items> The user's name Set alias of the key to be used to sign <user> bob</user>

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 signature parameters such as signaturePropFile crypto provider, keystore and its password Key identifier to be used in signatureKeyIdent referring the key in the ifier signature Key identifier to be used in encryptionKeyIde referring the key in ntifier encryption encryptionUser The user's name for encryption. Set example.properties file as the signature property file <signaturePropFile> example.properties</signaturePropFile> Use the serial number of the certificate <signatureKeyIdentifier> IssuerSerial</signatureKeyIdentifier> Use the serial number of the certificate <encryptionKeyIdentifier>IssuerSerial</enc ryptionKeyIdentifier> <encryptionUser>alice</encryptionUser> Use AES-128 <encryptionSymAlgorithm> http://www.w3.org/2001/04/xmlenc#aes12 8-cbc</encryptionSymAlgorithm> Use RSA-OAEP <parameter name="encryptionSymAlgorithm"> http://www.w3.org/2001/04/xmlenc#rsaoaep-mgf1p</parameter> Sign Foo and Bar elements qualified by "http://app.ns/ns" <signatureParts> {Element}{http://app.ns/ns}Foo;{Element} {http://app.ns/ns}Bar </signatureParts>

encryptionSymAlg Symmetric algorithm to be orithm used for encryption

encryptionKeyTran Key encryption algorithm sportAlgorithm

signatureParts

Sign multiple parts in the SOAP message

optimizeParts

Optimize the CipherValue MTOM Optimize the elements <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 Security actions for the inflow availability of the Timestamp <items> Timestamp Signature Encrypt</items> <passwordCallbackClass> org.apache.axis2.security.PWCallback</pass wordCallbackClass> <signaturePropFile> sig.properties</signaturePropFile>

items

Callback class used to obtain passwordCallback password for decryption and Class UsernameToken verification signaturePropFile Property file used for signature verification

9

decryptionPropFile

Property file used for decryption

<decryptionPropFile> 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-458fabf5-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 http://specs.xmlsoap.org/ws/2005/07/securitypolicy/ws-securitypolicy.pdf

2. 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 machinereadable 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> <a:Foo/> <b:Bar/> </wsp:Policy> <wsp:Policy> => <a:Foo/> </wsp:Policy> <wsp:Policy> <b:Foo/> </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 http://wso2.org/library/23 http://svn.apache.org/viewvc/webservices/commons/trunk/modules/neethi/ http://specs.xmlsoap.org/ws/2004/09/policy/ws-policy.pdf

Sanka Samaranayake, March 2006. Web services Policy - Why, What & How:

WS-commons/policy SVN:

Web Services Policy Framework (WS-Policy):

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

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

catch (XMLStreamException e) { e.printStackTrace(); } catch (FactoryConfigurationError e) { e.printStackTrace(); }

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 http://www.xfront.com/REST-Web-Services.html http://www-128.ibm.com/developerworks/webservices/library/ws-restvsoap/

Building Web Services the REST Way, By Roger L. Costello:

Resource-oriented vs. activity-oriented Web services, By James Snell:

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 text/javascript?? are using the ?Badgerfish?? convention with the content type ?

<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 (openejbjar.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 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

For JBoss add the following jar files.
• • • • • • • • •

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 WEBINF/lib/axis2-soapmonitor-*.jar which is inside the extracted axis2.war. To extract the axis2soapmonitor-*.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 wsdl2java.sh wsdl2java.sh ../samples -p -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -uri ../samples/wsdl/Axis2SampleDocLit.wsdl -ss -sd -d xmlbeans -o 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 Wizard IntelliJ IDEA Plug-in Maven2 AAR Plug-in Maven2 Java2WSDL Plug-in Maven2 WSDL2Code Plug-in Using this tool one can create service archives that can be deployed as a Web services to the Axis2, and also generate a java class file from a WSDL file (WSDL2Java). This plugin generates an Axis2 service file (AAR file). This plugin takes as input a Java class and generates a WSDL, which describes a Web service for invoking the classes methods. This plugin takes as input a WSDL and generates client and server stubs for calling or implementing a Web service matching the WSDL.

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 Reference Example Build File Using the Custom Ant Task Invoking the Code Generator From Ant

Ant Task
• • •

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 WSDL file location. This should point to a WSDL file in the local file system. Output file location. This is where the files would be copied once the code generation is done. If this option is omitted the generated files would be copied to the working directory. Output language. Currently the code generator can generate code in Java but it has the ability to be extended to support other languages. -uri <Location of None WSDL> -o <output Location> --output <output Location> --language <language>

-l <language> -p <package name>

The target package name. If omitted, a default package --package (formed using the target namespace of the WSDL) will <package name> be used.

29

-a

--async

Generate code only for async style. When this option is used the generated stubs will have only the 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 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 JUnit test case. Generates server side code (i.e. skeletons). Default is off. Generates the service descriptor (i.e. server.xml). Default is off. Only valid with -ss, the server side code generation option. Specifies the Databinding framework. Valid values are xmlbeans, adb, jibx, and none. Default is adb. Generates all the classes. This option is valid only with the -ss (server side code generation) option. When on, the client code (stubs) will also be generated along with the skeleton. Unpack classes. This option specifies whether to unpack the classes and generate separate classes for the databinders. Specifies the service name to be code generated. If the service name is not specified, then the first service will be picked.

-s

--sync

-t -ss -sd -d <databinding>

--test-case --server-side --servicedescription --databindingmethod <databinding> --generate-all

-g

-u -sn <service name> -pn <port name>

--unpack-classes --service-name <service name>

Specifies the port name to be code generated. If the --port-name <port port name is not specified, then the first port (of the name> selected service) will be picked. Specifies a comma separated list of namespaces and -packages where the given package will be used in the namespace2packa place of the auto generated package for the relevant ge namespace. The list will be the format of ns1=pkg1,ns2=pkg2. --serversideinterface Generate an interface for the service skeleton.

-ns2p

-ssi

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
wsdlfilename WSDL file location. Maps to the -uri option of the command line tool.

30

output

Output file location. This is where the files would be copied once the code generation is done. If this option is omitted the 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 code in Java. Maps to the -l option of the command line tool. The target package name. If omitted, a default package (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 command line tool. Possible values include "adb", "xmlbeans", "jibx". The name of the service in the case of multiple services. Maps to -sn options of the command line tool. The name of the port in the presence of multiple ports. Maps 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 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 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 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 to the -t options of the command line tool. Generates server side code (i.e. skeletons). Only true and false 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 classes to be generated separately, which otherwise would have been generated as inner classes. Generates all the classes including client and server side code. Maps to the -g option of the command line tool. A list of namespace to package mappings. Flag stating whether to generate an interface for the server side skeleton. Sets the repository path to be used. Maps to the -r option of 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, 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 -em option of the command line tool. Rather than dumping all the code in the same location, one has the option to make the sources to be generated in a

language packageName

databindingName serviceName portName

asyncOnly

syncOnly

serverSide testcase generateServiceXml

unpackClasses generateAllClasses namespaceToPackages serverSideInterface repositoryPath

wsdlVersion

externalMapping targetSourceFolderLocation

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. unwrap This will select between wrapped and unwrapped during code 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 WEBINF/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:soap11enc="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 import import import import import org.apache.axis2.AxisFault; login.types.ReturnWebLoginElementDocument; login.types.ReturnWebLoginElementDocument.*; login.types.WebLoginElementDocument; login.types.WebLoginElementDocument.*; 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] [java] [java] [java] [java] [java] [java]

running the webLogin client webLogin, firing... validate: true Client returned WebUserName: joe sixpack SOAPSessionId: some_random_string 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 Name aarDirectory Default Value ${project.build.directory}/aar Description Directory where the aar file is built Directory with compiled classes and resources Additional file sets, which are being added 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 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 classesDirectory/META-INF and no special processing is required service.wsdl Name, to which the WSDL file should be mapped

classesDirectory ${project.build.outputDirectory} fileSets

servicesXmlFile

wsdlFile

wsdlFileName

The aar Goal
The aar goal allows the following additional parameters: Parameter Name aarName Default Value Description

outputDirectory ${project.build.directory} Directory where to generate the AAR file ${project.build.finalName} The generated AAR files name

59

archive

A Maven archive configuration. This allows, for example, to configure the MANIFEST.MF file A classifier, which should be added to the generated AAR files name. Setting this parameter 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 or deployment of the artifact as the projects primary artifact

classifier

primaryArtifact true

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 directory outputDirectory includes excludes Description 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 directory Configures the set of files, which shall be included into the AAR file. Defaults to **/* Configures a set of files, which shall be excluded from the file set. 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/generatedresources/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. Parameter name Command line property Description Fully qualified name of the class, which is being read and transformed into a WSDL Default value

className

${axis2.java2wsdl.className}

outputFileName

${axis2.java2wsdl.outputFileName Path of the generated } 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 of the service. input class. Default namespac e

serviceName

${axis2.java2wsdl.serviceName}

targetNamespace

${axis2.java2wsdl.targetNamespa Target namespace of the ce} generated WSDL

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/generatedsources/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. Parameter Name databindingName Command Line Property Description Default Value

Data binding framework, which is ${axis2.wsdl2code.data being used by the generated adb bindingName} sources. Whether to generate simply all ${axis2.wsdl2code.gene classes. This is only valid in rateAllClasses} conjunction with "generateServerSide". ${axis2.wsdl2code.gene Whether server side sources are rateServerSide} being generated. false

generateAllClasses

generateServerSide

false false false false java

${axis2.wsdl2code.gene generateServerSideInte Whether to generate the server rateServerSideInterface rface side interface. } generateServicesXml generateTestcase language ${axis2.wsdl2code.gene Whether a "services.xml" file is rateServicesXml} being generated. ${axis2.wsdl2code.gene Whether a test case is being rateTestCase} generated. ${axis2.wsdl2code.lang Programming language of the uage} generated sources. Map of namespace URI to packages in the format uri1=package1,uri2=package2,... Using this parameter is ${axis2.wsdl2code.nam 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> <uri>uri1</uri> <package>package1</package> </namespaceURI> ........ </namespaceURI> Target directory, where sources ${axis2.wsdl2code.targe are being target/generatedt} sources/axis2/wsdl2code

namespaceToPackages

namespaceURIs

outputDirectory

63

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

portName

serviceName

syncMode unpackClasses

wsdlFile

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 public class SOAPMonitorHandler extends AbstractHandler

Axis 2 the SOAPMonitorHandler has the class signature as:

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 commonshttpclient. 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 deserialization 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 WEBINF/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