You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ch...@apache.org on 2006/05/15 07:51:47 UTC
svn commit: r406543 [4/6] - in /webservices/axis2/trunk/java/xdocs/latest:
./ adb/ adb/images/ images/ images/archi-guide/ images/userguide/ jibx/
resources/ resources/schemas/
Added: webservices/axis2/trunk/java/xdocs/latest/migration.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/migration.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/migration.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/migration.html Sun May 14 22:51:17 2006
@@ -0,0 +1,673 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta http-equiv="content-type" content="">
+ <title>Migrating from Axis 1.x</title>
+</head>
+
+<body lang="en">
+<h1>Migrating from Apache Axis 1.x to Axis 2</h1>
+
+<p>For all those users who are familiar with Axis2 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.</p>
+
+<p><i>Send your feedback or questions to: <a
+href="mailto:axis-dev@ws.apache.org">axis-dev@ws.apache.org</a></i>. Prefix
+subject with [Axis2]. To subscribe to mailing list see <a
+href="http://ws.apache.org/axis2/mail-lists.html">here.</a></p>
+
+<h2>Content</h2>
+<ul>
+ <li><a href="#comp">Compatibility</a></li>
+ <li><a href="#start">Getting Started</a></li>
+ <li><a href="#custom_deployment">Custom Deployment of Services, Handlers
+ and Modules</a></li>
+ <li><a href="#transports">Transports for HTTP Connection</a></li>
+ <li><a href="#data_binding">Data Binding Support</a></li>
+ <li><a href="#best">Best Usage</a></li>
+</ul>
+<a name="comp"></a>
+
+<h2>Compatibility</h2>
+
+<p>Axis1.x and Axis2 have been evolved from different architectures.</p>
+
+<p><strong>Speed</strong> - Axis2 is based on StAX API, which gives greater
+speed than SAX event based parsing that has been used in Axis1.x.</p>
+
+<p><strong>Stability</strong> - Axis2 has fixed phases and for extensions an
+area of user defined phases. This allows far more stability and flexibility
+than Axis1.x.</p>
+
+<p><strong>Transport framework</strong> - 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.</p>
+
+<p><strong>WSDL support</strong> - Axis2 supports version 1.1 and 2.0, which
+allows creating stubs and skeletons, to manipulate the web services arena.</p>
+
+<p><strong>Component - oriented architecture</strong> - This is merely
+through archives (.mar and .aar) . Easily reusable components such as
+handlers, modules allow patterns processing for your applications, or to
+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).</p>
+<a name="start"></a>
+
+<h2>Getting Started</h2>
+
+<p>Lets look at a simple example of echoing at client API.</p>
+
+<p><b>Axis 1.x</b></p>
+<pre>import ...
+public class TestClient {
+ public static void main(String [] args) {
+ try {
+ String endpoint = ... ;
+ Service axisService = new Service();
+ Call call = (Call) axisService.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());
+ }
+ }
+}</pre>
+
+<p><b>Axis 2</b></p>
+<pre>import ...
+public class EchoBlockingClient {
+ private static EndpointReference targetEPR = new EndpointReference(
+ AddressingConstants.WSA_TO,
+ "http://127.0.0.1:8080/axis2/services/MyService");
+ public static void main(String[] args) {
+ try {
+ OMElement payload = ClientUtil.getEchoOMElement();
+ Options options = new Options();
+ ServiceClient client = new ServiceClient();
+ options.setTo(targetEPR);
+ //Blocking invocation
+ OMElement result = client.sendReceive(payload);
+ ...
+ } catch (AxisFault axisFault) {
+ axisFault.printStackTrace();
+ } catch (XMLStreamException e) {
+ e.printStackTrace();
+ }
+ }
+}</pre>
+
+<p>It has been clearly depicted that the invocation in Axis2 is dealt with
+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.</p>
+
+<p>Once the service is called through the stub in Axis2, "payload" is
+according to the data binding framework that will be used. So the extra work
+of "payload" will be vanished.</p>
+
+<p>Apart from synchronous invocation, Axis2 supports asynchronous invocation
+through sendReceiveNonblocking(). Synchronous/Asynchronous invocations can
+handle both single/double HTTP connections.</p>
+
+<p>With this advanced architecture, Axis2 is capable of handling megabytes of
+requests and responses, which is far from what Axis1.x was capable of.</p>
+<a name="custom_deployment"></a>
+
+<h2>Custom Deployment of Services, Handlers and Modules</h2>
+
+<p>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 detail regarding this is given in the Axis2 user
+guide.</p>
+
+<p>Axis2 is far from the "Handler concept" and is more into the "Module
+concept". Abstractly speaking, the module concept is a collection of handlers
+with rules of governing which modules are created as .mar files. It has
+module.xml, which is the brain behind manipulating the handlers.</p>
+
+<p>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/>").</p>
+
+<p>Services are hot deployable in Axis2, but modules are not. This is one
+feature which is unique to Axis2.</p>
+
+<p>Lets 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.</p>
+
+<p><b>Axis 1.x required two WSDD's to use the SOAP Monitor. First, the SOAP
+Monitor Handler itself:</b></p>
+<pre><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></pre>
+
+<p><b>Axis 1.x requires a reference to the handler in the user's WSDD that
+defines their Web Service:</b></p>
+<pre><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></pre>
+
+<p><b>Axis 2 requires a module.xml, placed inside a jar with a .mar extension
+under WEB-INF/modules, to define a Handler:</b></p>
+<pre><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></pre>
+
+<p>The SOAPMonitorModule referenced above simply implements
+org.apache.axis2.modules.Module and is used for any additional tasks needed
+to initialize the module and shutdown the module. In this case nothing is
+needed and the implemented interface methods have blank bodies. Furthermore,
+the 'soapmonitorPhase' will be used later below in the axis2.xml .</p>
+
+<p><b>Axis 1.x the SOAPMonitorHandler has the class signature as:</b></p>
+<pre>public class SOAPMonitorHandler extends BasicHandler</pre>
+
+<p><b>Axis 2 the SOAPMonitorHandler has the class signature as:</b></p>
+<pre>public class SOAPMonitorHandler extends AbstractHandler </pre>
+
+<p><b>In axis2, you need to reference the module that contains the handler
+chain that you want to use inside your services.xml:</b></p>
+<pre><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></pre>
+
+<p><b>Finally, axis2 requires you to make some changes to axis2.xml. Start by
+adding a global module:</b></p>
+<pre> <module ref="soapmonitor"/></pre>
+
+<p><b>Then define your phase orders for 'soapmonitorPhase' referenced in the
+module.xml :</b></p>
+<pre> <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>
+ <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></pre>
+
+<p>See the user guide for more info on axis2 modules.</p>
+<a name="transports"></a>
+
+<h2>Transports for HTTP Connection</h2>
+
+<p>Axis2 comes with two CommonsHTTPTransportSender which is based on
+commons-httpclient.</p>
+
+<p>It should be noted that axis2.xml should be configured to call the commons
+transports, with the statement,</p>
+<pre>...
+<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>
+...</pre>
+<a name="data_binding"></a>
+
+<h2>Data Binding Support</h2>
+
+<p>ADB is used to provide data binding support. In Axis2, xml is manipulated
+via AXIOM, which is based on the StAX API. XML gives full schema support.
+Thus, serialization and de-serialization of XML is handled in Axis2 via the
+xml-data binding framework.</p>
+
+<p>Below is an example of migrating an WSDL based Axis 1.x Web Service to
+Axis2.</p>
+
+<p>First, lets take a look at a simple document / literal style WSDL used in
+an Axis 1.x Web Service. This example assumes the name of simple.wsdl for the
+wsdl below:</p>
+<pre><?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>
+ <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></pre>
+
+<p>The next step is run WSDL2Java on the wsdl. For axis 1.x, this example
+uses the following ant task:</p>
+<pre><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></pre>
+
+<p>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:</p>
+<pre>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</pre>
+
+<p>Now lets run WSDL2Java with Axis2. In this example, the only change to
+simple.wsdl required for axis2 is that 'soap:address location' be changed
+to:</p>
+<pre><soap:address location="http://localhost:8080/axis2/services/SimpleEndpoint"/></port></service></definitions></pre>
+
+<p>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:</p>
+<pre><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></pre>
+
+<p>For an explanation of the Axis2 WSDL2Java ant task and its options, see
+the CodegenToolReference guide.</p>
+
+<p>A feature of xmlbeans is that there is one class file created with
+WSDL2java, and a series of xsb files. These must be referenced when
+compiling, and as the example shows these files are moved to a build
+directory</p>
+
+<p>The Axis2 WSDL2Java example also takes the simple.wsdl under the directory
+'wsdl' , and from that creates files under the directory 'output'. The
+relevant non-xmlbean files created are shown below:</p>
+<pre>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</pre>
+
+<p>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,
+comming from different architectures. There is no direct parallel between
+them. See the Axis2 user guide for an explanation about services.xml</p>
+
+<p>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:</p>
+<pre class="code">package simpleNS;
+
+public class SimpleEndpointBindingImpl implements simpleNS.SimpleEndpoint{
+ public simpleNS.types.SimpleLoginResponse simpleLogin(simpleNS.types.SimpleLogin parameters)
+ throws java.rmi.RemoteException {
+ return null;
+ }
+
+}</pre>
+
+<p>To:</p>
+<pre class="code">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");
+ }
+
+}</pre>
+
+<p>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'll then look at the happy axis page to verify the service is installed
+correctly.</p>
+
+<p>Now lets 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 Axis2 we work with the skeleton directly. To
+implement the business logic in the Axis2 generated classes we'll change
+org/simple/endpoint/SimpleEndpointSkeleton.java from:</p>
+<pre class="code">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();
+ }
+}</pre>
+
+<p>To:</p>
+<pre class="code">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;
+ }
+}</pre>
+
+<p>In Axis2, the next step is to compile the classes, put them along with the
+generated services.xml in an AAR, and then hot deploy the AAR by placing it
+in the Axis2.war under WEB-INF/services . Point a browser to
+http://localhost:8080/axis2/listServices , and you should see the service
+'SimpleService' ready for action. See the Axis2 user guide for more info.</p>
+
+<p>The last step is the client. Our Axis 1.x client for this example is:</p>
+<pre>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);
+ }
+}</pre>
+
+<p>Finally, our Axis2 client for this example is:</p>
+<pre>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);
+
+ 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);
+
+ }
+}</pre>
+
+<p>Axis2 clients also have asynchronous options via a Callback and
+alternatively 'Fire and forget'. See the user guide for more details.</p>
+<a name="best"></a>
+
+<h2>Best Usage</h2>
+
+<p>Axis1.x and Axis2 have different ways of seeing the SOAP stack. So the
+best way to migrate is to follow the User guide and the Architecture guide of
+Axis2 properly. Axis2 is very much straight forward and friendly to use than
+it's successor.</p>
+</body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/mtom-guide.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/mtom-guide.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/mtom-guide.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/mtom-guide.html Sun May 14 22:51:17 2006
@@ -0,0 +1,476 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="">
+ <title>MTOM Guide-Sending Binary data with SOAP</title>
+</head>
+
+<body>
+<h1>MTOM Guide -Sending Binary Data with SOAP</h1>
+
+<p>This document will describe the problems occuring in sending binary data
+with SOAP and how Axis2 has overcome those problems using MTOM or SOAP
+Message Transmission Optimization Mechanism.</p>
+
+<h2>Content</h2>
+<ul>
+ <li><a href="#1">Introduction</a>
+ <ul>
+ <li><a href="#11">Where Does MTOM Come In?</a></li>
+ </ul>
+ </li>
+ <li><a href="#2">MTOM with Axis2 </a>
+ <ul>
+ <li><a href="#21">Programming Model</a></li>
+ <li><a href="#22">Enabling MTOM Optimization at Client Side</a></li>
+ <li><a href="#23">Enabling MTOM Optimization at Server Side</a></li>
+ <li><a href="#24">Accessing Received Binary Data (Sample Code) </a>
+ <ul>
+ <li><a href="#241">Service</a></li>
+ <li><a href="#242">Client</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li><a href="#3">SOAP with Attachments with Axis2</a></li>
+ <li><a href="#4">Advanced Topics </a>
+ <ul>
+ <li><a href="#41">File Caching for Attachments</a></li>
+ </ul>
+ </li>
+</ul>
+<a name="1"></a>
+
+<h2>Introduction</h2>
+
+<p>Despite the flexibility, interoperability and global acceptance of XML,
+there are times when serializing data into XML does not make sense. Web
+services users may need to transmit binary attachments of various sorts like
+images, drawings, xml docs, etc together with SOAP message. Such data are
+often in a particular binary format.<br>
+</p>
+
+<p>Traditionally, two techniques have been used in dealing with opaque data
+in XML;</p>
+<ol>
+ <li><strong>"By value"</strong></li>
+
+ <blockquote>
+ <p>Sending binary data by value is achieved by embedding opaque data (of
+ course after some form of encoding) as element or attribute content of
+ the XML component of data. The main advantage of this technique is that
+ it gives applications the ability to process and describe data based and
+ looking only on XML component of the data.</p>
+
+ <p>XML supports opaque data as content through the use of either base64
+ or hexadecimal text encoding. Both these techniques bloat the size of the
+ data. For UTF-8 underlying text encoding, base64 encoding increases the
+ size of the binary data by a factor of 1.33x of the original size, while
+ hexadecimal encoding expands data by a factor of 2x. Above factors will
+ be doubled if UTF-16 text encoding is used. Also of concern is the
+ overhead in processing costs (both real and perceived) for these formats,
+ especially when decoding back into raw binary.</p>
+ </blockquote>
+ <li><strong>"By reference"</strong>
+
+ <blockquote>
+ <p>Sending binary data by reference is achieved by attaching pure
+ binary data as external unparsed general entities outside of the XML
+ document and then embedding reference URI's to those entities as
+ elements or attribute values. This prevents the unnecessary bloating of
+ data and wasting of processing power. The primary obstacle for using
+ these unparsed entities is their heavy reliance on DTDs, which impedes
+ modularity as well as use of XML namespaces.</p>
+ <p>There were several specifications introduced in the Web services
+ world to deal with this binary attachment problem using the "by
+ reference" technique. <a
+ href="http://www.w3.org/TR/SOAP-attachments">SOAP with Attachments</a>
+ is one such example. Since SOAP prohibits document type declarations
+ (DTD) in messages, this leads to the problem of not representing data
+ as part of the message infoset, creating two data models. This scenario
+ is like sending attachments with an e-mail message. Even though those
+ attachments are related to the message content they are not inside the
+ message. This causes the technologies for processing and description
+ of data based on XML component of the data, to malfunction. One example
+ is WS-Security.</p>
+ </blockquote>
+ </li>
+</ol>
+<a name="11"></a>
+
+<h3>Where Does MTOM Come In?</h3>
+
+<p><a href="http://www.w3.org/TR/2004/PR-soap12-mtom-20041116/">MTOM (SOAP
+Message Transmission Optimization Mechanism)</a> is another specification
+which focuses on solving the "Attachments" problem. MTOM tries to leverage
+the advantages of above two techniques by trying to merge the two techniques.
+MTOM is actually a "by reference" method. Wire format of a MTOM optimized
+message is same as the Soap with Attachments message, which also makes it
+backward compatible with SwA endpoints. The most notable feature of MTOM is
+the use of XOP:Include element, which is defined in <a
+href="http://www.w3.org/TR/2004/PR-xop10-20041116/">XML Binary Optimized
+Packaging (XOP)</a> specification to reference the binary attachments
+(external unparsed general entities) of the message. With the use of this
+exclusive element the attached binary content logically become inline (by
+value) with the SOAP document even though actually it is attached separately.
+This merges the two realms by making it possible to work only with one data
+model. This allows the applications to process and describe by only looking
+at XML part making reliance on DTDs obsolete. On a lighter note MTOM has
+standardized the referencing mechanism of SwA. Following is an extract from
+the <a href="http://www.w3.org/TR/2004/PR-xop10-20041116/">XOP</a>
+specification.</p>
+
+<p><em>At the conceptual level, this binary data can be thought of as being
+base64-encoded in the XML Document. As this conceptual form might be needed
+during some processing of the XML Document (e.g., for signing the XML
+document), it is necessary to have a one to one correspondence between XML
+Infosets and XOP Packages. Therefore, the conceptual representation of such
+binary data is as if it were base64-encoded, using the canonical lexical form
+of XML Schema base64Binary datatype (see <a href="#XMLSchemaP2">[XML Schema
+Part 2: Datatypes Second Edition] </a><a
+href="http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#base64Binary">3.2.16
+base64Binary</a>). In the reverse direction, XOP is capable of optimizing
+only base64-encoded Infoset data that is in the canonical lexical
+form.</em></p>
+
+<p>Apache Axis2 supports <strong>Base64 encoding</strong>, <strong>SOAP with
+Attachments</strong> & <strong>MTOM (SOAP Message Transmission
+Optimization Mechanism).</strong></p>
+<a name="2"></a>
+
+<h2>MTOM with Axis2</h2>
+<a name="21"></a>
+
+<h3>Programming Model</h3>
+
+<p>AXIOM is (and may be the first) Object Model which has the ability to hold
+binary data. It has been given this ability by allowing OMText to hold raw
+binary content in the form of javax.activation.DataHandler. OMText has been
+chosen for this purpose with two reasons. One is that XOP (MTOM) is capable
+of optimizing only base64-encoded Infoset data that is in the canonical
+lexical form of XML Schema base64Binary datatype. Other one is to preserve
+the infoset in both sender and receiver (To store the binary content in the
+same kind of object regardless of whether it is optimized or not).</p>
+
+<p>MTOM allows to selectively encode portions of the message, which allows us
+to send base64encoded data as well as externally attached raw binary data
+referenced by "XOP" element (optimized content) to be send in a SOAP message.
+User can specify whether an OMText node which contains raw binary data or
+base64encoded binary data is qualified to be optimized or not at the
+construction time of that node or later. To take the optimum efficiency of
+MTOM a user is advised to send smaller binary attachments using
+base64encoding (None optimized) and larger attachments as optimized
+content.</p>
+<source><pre> OMElement imageElement = fac.createOMElement("image", omNs);
+
+ // Creating the Data Handler for the image.
+ // User has the option to use a FileDataSource or a ImageDataSource
+ // in this scenario...
+ Image image;
+ image = new ImageIO()
+ .loadImage(new FileInputStream(inputImageFileName));
+ ImageDataSource dataSource = new ImageDataSource("test.jpg",image);
+ DataHandler dataHandler = new DataHandler(dataSource);
+
+ //create an OMText node with the above DataHandler and set optimized to true
+ OMText textData = fac.createOMText(dataHandler, true);
+ imageElement.addChild(textData);
+
+ //User can set optimized to false by using the following
+ //textData.doOptimize(false);</pre>
+</source>
+<p>Also a user can create an optimizable binary content node using a base64
+encoded string, which contains encoded binary content, given with the mime
+type of the actual binary representation.</p>
+<source><pre> String base64String = "some_string";
+ OMText binaryNode = fac.createOMText(base64String,"image/jpg",true);</pre>
+</source>
+<p>Axis2 uses javax.activation.DataHandler to handle the binary data. All
+optimized binary content nodes will be serialized as Base64 Strings if "MTOM
+is not enabled". One can also create binary content nodes which will not be
+optimized at any case. They will be serialized and send as Base64 Strings.</p>
+<source><pre> //create an OMText node with the above DataHandler and set "optimized" to false
+ //This data will be send as Base64 encoded string regardless of MTOM is enabled or not
+ javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataHandler("someLocation"));
+ OMText textData = fac.createOMText(dataHandler, false);
+ image.addChild(textData);</pre>
+</source><a name="22"></a>
+
+<h3>Enabling MTOM Optimization at Client Side</h3>
+
+<p>Set the "enableMTOM" property in the Options to true, when sending
+messages.</p>
+<source><pre> ServiceClient serviceClient = new ServiceClient ();
+ Options options = new Options();
+ options.setTo(targetEPR);
+ options.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);
+ serviceClient .setOptions(options);</pre>
+</source>
+<p>When this property is set to true any SOAP envelope which contains
+optimizable content (OMText nodes containing binary content with optimizable
+flag "true") will be serialized as a MTOM optimized message. Messages will
+not be packaged as MTOM if they did not contain any optimizable content even
+though MTOM is enabled. But due considering the policy assertions, there may
+be a policy saying, all the request should be optimized eventhough there are
+any optimized contents. To support this phenomenon there is an entry called
+"forced mime" which has to be set as</p>
+<source><pre> ServiceClient serviceClient = new ServiceClient ();
+ Options options = new Options();
+ options.setTo(targetEPR);
+ options.setProperty(Constants.Configuration.FORCE_MIME, Constants.VALUE_TRUE);
+ serviceClient.setOptions(options);</pre>
+</source>
+<p>Axis2 serializes all binary content nodes as Base64 encoded strings
+regardless of they are qualified to be optimize or not, if,</p>
+<ul>
+ <li>"enableMTOM" property is set to false.</li>
+ <li>If envelope contains any element information items of name xop:Include
+ (see <a href="#XOP">[XML-binary Optimized Packaging] </a><a
+ href="http://www.w3.org/TR/2005/REC-xop10-20050125/#xop_infosets">3. XOP
+ Infosets Constructs </a>).</li>
+</ul>
+
+<p>MTOM is *always enabled* in Axis2 when it comes to receiving messages.
+Axis2 will automatically identify and de-serialize any MTOM message it
+receives.</p>
+
+<p><a name="23"></a></p>
+
+<h3>Enabling MTOM Optimization at Server Side</h3>
+
+<p>Axis 2 server automatically identifies incoming MTOM optimized messages
+based on the content-type and de-serializes accordingly. User can enableMTOM
+in the server side for outgoing messages,</p>
+<ul>
+ <li>Globally for all services
+
+ <blockquote>
+ <p>add and set the "enableMTOM" parameter to true in the Axis2.xml.
+ When it is set, *outgoing* messages *which contains optimizable
+ content* will be serialized and send as MTOM optimized messages. If it
+ is not set all the binary data in binary content nodes will be
+ serialized as Base64 encoded strings.</p>
+ </blockquote>
+ </li>
+</ul>
+
+<p><source></p>
+<pre><parameter name="enableMTOM" locked="false">true</parameter></pre>
+</source><ul>
+ <ul>
+ <p>User must restart the server after setting this parameter.</p>
+ </ul>
+</ul>
+<a name="24"></a>
+
+<h3>Accessing Received Binary Data (Sample Code)</h3>
+<ul>
+ <li><strong><a name="241"></a>Service</strong></li>
+</ul>
+<source><pre>public class MTOMService {
+ public OMElement mtomSample(OMElement element) throws Exception {
+ OMElement _fileNameEle = null;
+ OMElement _imageElement = null;
+
+ for (Iterator _iterator = element.getChildElements(); _iterator.hasNext();) {
+ OMElement _ele = (OMElement) _iterator.next();
+ if (_ele.getLocalName().equalsIgnoreCase("fileName")) {
+ _fileNameEle = _ele;
+ }
+ if (_ele.getLocalName().equalsIgnoreCase("image")) {
+ _imageElement = _ele;
+ }
+ }
+
+ if (_fileNameEle == null || _imageElement == null ) {
+ throw new AxisFault("Either Image or FileName is null");
+ }
+
+ OMText binaryNode = (OMText) _imageElement.getFirstOMChild();
+
+ String fileName = _fileNameEle.getText();
+
+ //Extracting the data and saving
+ DataHandler actualDH;
+ actualDH = (DataHandler) binaryNode.getDataHandler();
+ Image actualObject = new ImageIO().loadImage(actualDH.getDataSource()
+ .getInputStream());
+ FileOutputStream imageOutStream = new FileOutputStream(fileName);
+ new ImageIO().saveImage("image/jpeg", actualObject, imageOutStream);
+ //setting response
+ OMFactory fac = OMAbstractFactory.getOMFactory();
+ OMNamespace ns = fac.createOMNamespace("urn://fakenamespace", "ns");
+ OMElement ele = fac.createOMElement("response", ns);
+ ele.setText("Image Saved");
+ return ele;
+ }
+}</pre>
+</source><ul>
+ <ul>
+ <li><a name="242"><strong>Client</strong></a></li>
+ </ul>
+</ul>
+<source><pre>
+ ServiceClient sender = new ServiceClient();
+ Options options = new Options();
+ options.setTo(targetEPR);
+ // enabling MTOM
+ options.set(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);
+ options.setTransportInfo(Constants.TRANSPORT_HTTP,
+ Constants.TRANSPORT_HTTP, false);
+ options.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
+
+ OMElement result = sender.sendReceive(payload);
+ OMElement ele = result.getFirstElement();
+ OMText binaryNode = (OMText) ele.getFirstOMChild();
+
+ // Retrieving the DataHandler & then do whatever the processing to the data
+ DataHandler actualDH;
+ actualDH = binaryNode.getDataHandler();
+ Image actualObject = new ImageIO().loadImage(actualDH.getDataSource()
+ .getInputStream());</pre>
+</source><a name="3"></a>
+
+<h2>SOAP with Attachments (SwA) with Axis2</h2>
+
+<p>Axis2 Handles SwA messages at the inflow only. When Axis2 receives a SwA
+message it extracts the binary attachment parts and puts a reference to those
+parts in the Message Context. Users can access binary attachments using the
+content-id. Care should be taken to rip off the "cid" prefix when content-id
+is taken from the "Href" attributes. When accessing the message context from
+a service users need to get hold of the message context from "setOperationContext()"
+method from the service class.(see the following service
+example)</p>
+
+<p>Note: Axis2 supports content-id referencing only. Axis2 does not support
+Content Location referencing of MIME parts.</p>
+<ul>
+ <li><strong>Sample service which accepts a SwA message</strong></li>
+</ul>
+<source><pre>
+public class EchoSwA {
+ private MessageContext msgcts;
+
+ public EchoSwA() {
+ }
+
+ public void setOperationContext(OperationContext oc) throws AxisFault {
+ msgcts = oc.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
+ }
+
+ public OMElement echoAttachment(OMElement omEle) {
+ OMElement child = (OMElement) omEle.getFirstOMChild();
+ OMAttribute attr = child.getAttribute(new QName("href"));
+ String contentID = attr.getAttributeValue();
+ Attachments attachment = (Attachments) msgcts.getProperty(MTOMConstants.ATTACHMENTS);
+ contentID = contentID.trim();
+
+ if (contentID.substring(0, 3).equalsIgnoreCase("cid")) {
+ contentID = contentID.substring(4);
+ }
+ DataHandler dataHandler = attachment.getDataHandler(contentID);
+ OMText textNode = new OMTextImpl(dataHandler, omEle.getOMFactory());
+ omEle.build();
+ child.detach();
+ omEle.addChild(textNode);
+ return omEle;
+ }
+}
+</pre>
+</source>
+<p>MTOM specification is designed to be backward compatible with the SOAP
+with Attachments specification. Even though the representation is different,
+both technologies have the same wire format. We can safely assume that any
+SOAP with Attachments endpoint can accept a MTOM optimized messages and treat
+them as SOAP with Attachment messages - Any MTOM optimized message is a valid
+SwA message. Because of that Axis2 does not define a separate programming
+model or serialization for SwA. Users can use the MTOM programming model and
+serialization to send messages to SwA endpoints.</p>
+
+<p>Note : Above is tested with Axis 1.x</p>
+<ul>
+ <li><strong>A sample SwA message from Axis 1.x</strong></li>
+</ul>
+<source><pre>Content-Type: multipart/related; type="text/xml";
+ start="<9D645C8EBB837CE54ABD027A3659535D>";
+ boundary="----=_Part_0_1977511.1123163571138"
+
+------=_Part_0_1977511.1123163571138
+Content-Type: text/xml; charset=UTF-8
+Content-Transfer-Encoding: binary
+Content-Id: <9D645C8EBB837CE54ABD027A3659535D>
+
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope xmlns:soapenv="...."....>
+ ........
+ <source href="cid:3936AE19FBED55AE4620B81C73BDD76E" xmlns="/>
+ ........
+</soapenv:Envelope>
+------=_Part_0_1977511.1123163571138
+Content-Type: text/plain
+Content-Transfer-Encoding: binary
+Content-Id: <3936AE19FBED55AE4620B81C73BDD76E>
+
+<em>Binary Data.....</em>
+------=_Part_0_1977511.1123163571138--</pre>
+</source><ul>
+ <li><strong>Corresponding MTOM message from Axis2</strong></li>
+</ul>
+<source><pre>Content-Type: multipart/related; boundary=MIMEBoundary4A7AE55984E7438034;
+ type="application/xop+xml"; start="<0....@apache.org>";
+ start-info="text/xml; charset=utf-8"
+
+--MIMEBoundary4A7AE55984E7438034
+content-type: application/xop+xml; charset=utf-8; type="application/soap+xml;"
+content-transfer-encoding: binary
+content-id: <0.09BC7F4BE2E4D3EF1B@apache.org>
+
+<?xml version='1.0' encoding='utf-8'?>
+<soapenv:Envelope xmlns:soapenv="...."....>
+ ........
+ <xop:Include href="cid:1.A91D6D2E3D7AC4D580@apache.org"
+ xmlns:xop="http://www.w3.org/2004/08/xop/include">
+ </xop:Include>
+ ........
+</soapenv:Envelope>
+--MIMEBoundary4A7AE55984E7438034
+content-type: application/octet-stream
+content-transfer-encoding: binary
+content-id: <1....@apache.org>
+
+<em>Binary Data.....</em>
+--MIMEBoundary4A7AE55984E7438034--</pre>
+</source><a name="4"></a>
+
+<h2>Advanced Topics</h2>
+<a name="41"></a>
+
+<h3>File Caching for Attachments</h3>
+
+<p>Axis2 comes handy with a file caching mechanism for incoming attachments,
+which gives Axis2 the ability to handle very large attachments without
+buffering them in memory at any time. Axis2 file caching streams the incoming
+MIME parts directly in to files, after reading the MIME part headers.</p>
+
+<p>Also a user can specify a size threshold for the File caching. When this
+threshold value is specified, only the attachments whose size is bigger than
+the threshold value will get cached in files. Smaller attachments will remain
+in Memory.</p>
+
+<p>NOTE : It is a must to specify a directory to temporary store the
+attachments. Also care should be taken to *clean that directory* from time to
+time.</p>
+
+<p>The following parameters need to be set in Axis2.xml in order to enable
+file caching.</p>
+<source><pre><em><axisconfig name="AxisJava2.0">
+ <!-- ================================================= -->
+ <!-- Parameters -->
+ <!-- ================================================= --></em>
+ <parameter name="cacheAttachments" locked="false">true</parameter>
+ <parameter name="attachmentDIR" locked="false"><em>temp directory</em></parameter>
+ <parameter name="sizeThreshold" locked="false">4000</parameter>
+ .........
+ .........
+</axisconfig></pre>
+</source></body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/resources/schemas/module.xsd
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/resources/schemas/module.xsd?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/resources/schemas/module.xsd (added)
+++ webservices/axis2/trunk/java/xdocs/latest/resources/schemas/module.xsd Sun May 14 22:51:17 2006
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Created by Eran Chinthaka -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <xs:element name="module">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Description" minOccurs="0"/>
+ <xs:element name="inflow" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="handler" type="handlerType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="outflow" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="handler" type="handlerType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="operation" minOccurs="0"/>
+ <xs:element name="Outfaultflow" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="handler" type="handlerType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="INfaultflow" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="handler" type="handlerType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="optional"/>
+ <xs:attribute name="class" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="order">
+ <xs:complexType>
+ <xs:attribute name="phase" type="xs:string" use="optional"/>
+ <xs:attribute name="after" type="xs:string" use="optional"/>
+ <xs:attribute name="before" type="xs:string" use="optional"/>
+ <xs:attribute name="phaseFirst" type="xs:string" use="optional"/>
+ <xs:attribute name="phaseLast" type="xs:string" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:complexType name="handlerType">
+ <xs:sequence>
+ <xs:element ref="order" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="class" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:element name="parameter">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="locked" type="xs:boolean" use="optional" default="false"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="operation">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="messageReceiver" minOccurs="0">
+ <xs:complexType>
+ <xs:attribute name="class"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element ref="parameter"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="mep" type="xs:anyURI" use="required"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
Added: webservices/axis2/trunk/java/xdocs/latest/resources/schemas/services.xsd
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/resources/schemas/services.xsd?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/resources/schemas/services.xsd (added)
+++ webservices/axis2/trunk/java/xdocs/latest/resources/schemas/services.xsd Sun May 14 22:51:17 2006
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Created by Eran Chinthaka -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <xs:element name="operation">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="messageReceiver" minOccurs="0">
+ <xs:complexType>
+ <xs:attribute name="class"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element ref="parameter" minOccurs="0"/>
+ <xs:element name="module" minOccurs="0">
+ <xs:complexType>
+ <xs:attribute name="ref"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="mep" type="xs:anyURI" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="parameter">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="locked" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="service">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Description" minOccurs="0"/>
+ <xs:element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="operation" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
Added: webservices/axis2/trunk/java/xdocs/latest/rest-ws.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/rest-ws.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/rest-ws.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/rest-ws.html Sun May 14 22:51:17 2006
@@ -0,0 +1,140 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="">
+ <title>RESTful Web Services Support</title>
+</head>
+
+<body lang="en">
+<h1>RESTful Web services Support</h1>
+
+<p>This document presents introduction on REST and REST with HTTP POST &
+GET. </p>
+
+<h2>Content</h2>
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#rest_with_post">Doing REST Web Services with HTTP POST</a>
+ <ul>
+ <li><a href="#sample">Sample REST - HTTP POST Client</a></li>
+ </ul>
+ </li>
+ <li><a href="#rest_with_get">Access a REST Web Service via HTTP GET</a></li>
+</ul>
+<a name="intro"></a>
+
+<h2>Introduction</h2>
+
+<p>REST (Representational State Transfer) provides access to resources
+through the two methods GET and POST. REST Web services are a reduced subset
+of the usual Web service stack.</p>
+
+<p>The Axis2 REST implementation assumes the following properties:</p>
+<ol>
+ <li>REST Web services are Synchronous and Request Response in nature.</li>
+ <li>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 service. In this case the GET based REST Web
+ services supports only simple types as arguments.</li>
+ <li>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.</li>
+</ol>
+
+<p>Axis2 can be configured as a REST Container and can be used to send and
+receive RESTful Web services requests and responses. REST Web services can be
+accessed in two ways, i.e. using HTTP GET and POST.</p>
+<a name="rest_with_post"></a>
+
+<h2>Doing REST Web Services with HTTP POST</h2>
+
+<p>Axis will acts as both a REST endpoint and SOAP endpoint. When a Message
+is received, if the content type is text/xml and if the SOAP Action Headers
+are missing, then the Message is treated as a RESTful Message. Else it is
+treated as a usual SOAP Message.</p>
+
+<p>On sending a message out, the fact that the message is RESTful or not, can
+be decided from the client API.<br>
+ Set a property in the client api.<br>
+ <source>
+ <pre>...
+Options options = new Options();
+options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);
+...</pre>
+ </source>
+</p>
+
+<a name="sample"></a>
+
+<h3>Sample REST - HTTP POST Client</h3>
+
+<p>There is an example named, userguide.clients.RESTClient.java which
+demonstrates the usage of the above, using the "echo"operation of the</p>
+<pre>userguide.example1.MyService </pre>
+
+<p>of the samples.The class source will be as follows:</p>
+<source><pre>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.setTransportInProtocol(Constants.TRANSPORT_HTTP);
+
+ 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();
+ } catch (XMLStreamException e) {
+ e.printStackTrace();
+ } catch (FactoryConfigurationError e) {
+ e.printStackTrace();
+ }
+ }
+ private static OMElement getPayload() {
+ OMFactory fac = OMAbstractFactory.getOMFactory();
+ OMNamespace omNs = fac.createOMNamespace(
+ "http://example1.org/example1", "example1");
+ OMElement method = fac.createOMElement("echo", omNs);
+ OMElement value = fac.createOMElement("Text", omNs);
+ value.addChild(fac.createText(value, "Axis2 Echo String "));
+ method.addChild(value);
+
+ return method;
+ }
+}</pre>
+</source><a name="rest_with_get"></a>
+
+<h2>Access a REST Web Service via HTTP GET</h2>
+
+<p>Axis2 allow 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. But the Web service arriving via GET assumes REST. Other parameters
+are converted in to XML and put in to the SOAP Body.</p>
+<source><pre>http://127.0.0.1:8080/axis2/services/version/getVersion</pre>
+</source>
+<p>Result can be shown in the browser as follows:</p>
+<img src="images/userguide/http-get-ws.jpg" alt="">
+
+<p>For example, the following request,</p>
+<source><pre>http://127.0.0.1:8080/axis2/services/version/getVersion</pre>
+</source>will be converted to the following SOAP Message for processing by
+Axis2.<source>
+<pre>
+ <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>
+ </pre>
+</source></body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/soapmonitor-module.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/soapmonitor-module.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/soapmonitor-module.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/soapmonitor-module.html Sun May 14 22:51:17 2006
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="content-type" content="">
+ <title>The SOAP Monitor Module</title>
+</head>
+
+<body>
+<h1>Using the SOAP Monitor</h1>
+
+<p>Web service developers often have the need to see the SOAP messages being
+used to invoke Web services along with the results of those messages. The
+goal of the SOAP Monitor utility is to provide a way for these developers to
+monitor the SOAP messages being used without requiring any special
+configuration or restarting of the server. </p>
+
+<p>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 with
+a Web browser by going to http://localhost:<port>/axis2/SOAPMonitor (where
+<port>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 should prompt you to install one.
+The port used by the SOAP monitor service to comminicate with applets is
+configurable. Edit the web.xml file for the Axis Web application to change
+the port to be used.</p>
+
+<p>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.</p>
+
+<p>The SOAP Monitor can be engaged by inserting the following in the
+axis2.xml file.</p>
+<source><pre> <module ref="soapmonitor"/></pre>
+</source>
+<p>Then in the axis2.xml file define your phase orders for 'soapmonitorPhase'
+referenced in the module.xml of soapmonitor.mar:</p>
+<pre> <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>
+ <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></pre>
+
+<p>To configure the servlet to communicate with the applet, add the following
+to web.xml (the SOAPMonitorPort is configurable) :</p>
+<pre><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>100</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>SOAPMonitorService</servlet-name>
+ <url-pattern>/SOAPMonitor</url-pattern>
+ </servlet-mapping></pre>
+
+<p>Finally, compile the applet classes and place them at the root of the war
+- for example axis2/SOAPMonitorApplet*.class/WEB-INF :</p>
+<pre>javac -classpath axis2-soapmonitor.jar SOAPMonitorApplet.java</pre>
+
+<p>With 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 for viewing
+service requests and responses. Any requests to services that have been
+configured and deployed correctly should show up in the applet.</p>
+</body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/tcp-transport.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/tcp-transport.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/tcp-transport.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/tcp-transport.html Sun May 14 22:51:17 2006
@@ -0,0 +1,119 @@
+<html>
+<head>
+ <meta content="">
+ <meta content="">
+ <meta content="">
+ <meta http-equiv="content-type" content="">
+ <title>TCP transport</title>
+</head>
+
+<body lang="en">
+<h1>TCP Transport</h1>
+This document will explain how to send and receive SOAP Messages via TCP in
+Axis2. Sample with be used for more clarity
+
+<p><i>Send your feedback or questions to: <a
+href="mailto:axis-dev@ws.apache.org">axis-dev@ws.apache.org</a></i>. Prefix
+subject with [Axis2]. To subscribe to mailing list see <a
+href="http://ws.apache.org/axis2/mail-lists.html">here.</a></p>
+
+<h2>Content</h2>
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#start">How to Start the TCPServer</a></li>
+ <li><a href="#send">How to Send SOAP Messages Using TCP Transport</a></li>
+ <li><a href="#samples">Samples</a></li>
+ <li><a href="#components">Transport Components</a></li>
+</ul>
+<a name="intro"></a>
+
+<h2>Introduction</h2>
+
+<p>Axis2 supports TCP as a transport. Axis2 has support for both send and
+receive SOAP Messages via TCP. TCP transport does not have any application
+level headers and the SOAP Message that is send should be self contained.
+This makes the interaction fast and simple. Since there are no application
+headers, it does not have the privilege of having request URI, and Service
+dispatching should be done with a alternative method. Thus,
+RequestURIBasedDispatcher can not be used. Following are the two main
+alternatives available in dispatching in Axis2 Environment.</p>
+<ol>
+ <li>Use the name space URI of the first child element of SOAPBody.
+ (SOAPMessageBodyBasedDispatcher)</li>
+ <li>Enable the WS-Addressing. In the case of 1.0 release addressing is
+ default (SOAPActionBasedDispatcher)</li>
+</ol>
+
+<p>When TCP request is sent it's user's responsibility to use either
+addressing or SOAP body base mechanism.</p>
+<a name="start"></a>
+
+<h2>How to Start the TCPServer</h2>
+
+<p>The TCP server can be started by running the class
+org.apache.axis2.transport.tcp.TCPServer with two parameters <a
+href="../faq.html#c5">repository</a> and port number as argument. This class
+needs all the axis dependency jars in the classpath. New Services can be
+added in the usual way by dropping the archives to repository (See <a
+href="userguide.html">User's Guide</a> for more information)</p>
+
+<p>Alternatively the TCP Server can run with tcp-server.bat/ tcp-server.sh
+file in the bin directory of the Binary distribution of TCP Server.</p>
+<a name="send"></a>
+
+<h2>How to Send SOAP Messages Using TCP Transport</h2>
+
+<p>The TCP transport can be enabled easily from the call API. Following code
+segment demonstrate how it can be done.</p>
+<source><pre>OMElement payload = ...
+
+ServiceClient serviceClient = new ServiceClient();
+Options options = new Options();
+options.setTo(targetEPR);
+options.useSeperateListener(false);
+serviceClient.setOptions(options);
+
+OMElement response =
+ serviceClient.sendReceive(payload);</pre>
+</source>
+<p>The transport that should be invoked is inferred from the targetEPR
+(tcp://...). In this case it is TCP and the listener, also TCP . SOAP Message
+has to be self contained in order to use addressing. Only other option one
+can think of is to use the URI of the first child of the SOAP Body to
+dispatch the service. The Parameter is of the type <a
+href="../faq.html#a2">OMElement</a>, the XML representation of Axis2.</p>
+<a name="sample"></a>
+
+<h2>Sample</h2>
+
+<p>Sample for a TCP Client can be found from the
+samples/userguide/src/userguide/clients/TCPClient.java in the binary
+distribution. This access the same web service explained in the <a
+href="userguide.html">Axis2 User's Guide</a>. The client first starts the
+TCPServer with the same repository used for the <a
+href="userguide.html">Axis2 User's Guide</a> samples. Since sample is already
+deployed in the repository while trying the userguide it will be
+automatically available.</p>
+<a name="components"></a>
+
+<h2>Transport Components</h2>
+
+<p>Axis2 TCP transport has two components, a transport Listener for receiving
+the Messages and transport Sender to send the SOAP Messages. Axis2
+installation has both the components built in to itself by default. In the
+axis2.xml configuration file the two TCP transport components would look like
+as follows.</p>
+
+<p>If the TCP server is started manually this configuration does not take
+effect. In return this effects the transport Listener's start by Axis2. (e.g.
+Listener started by the Complete Async interaction)</p>
+
+<p>Following xml lines initializes the TCPTransport Receiver:</p>
+<source><pre><transportReceiver name="tcp" class="org.apache.axis2.transport.tcp.TCPServer">
+ <parameter name="port" locked="false">6060</parameter>
+</transportReceiver></pre>
+</source>
+<p>Following xml lines adds the TCPTransport Sender:</p>
+<source><pre><transportSender name="tcp" class="org.apache.axis2.transport.tcp.TCPTransportSender"/></pre>
+</source></body>
+</html>
Added: webservices/axis2/trunk/java/xdocs/latest/transport_howto.html
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/xdocs/latest/transport_howto.html?rev=406543&view=auto
==============================================================================
--- webservices/axis2/trunk/java/xdocs/latest/transport_howto.html (added)
+++ webservices/axis2/trunk/java/xdocs/latest/transport_howto.html Sun May 14 22:51:17 2006
@@ -0,0 +1,218 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="">
+ <title></title>
+</head>
+
+<body>
+<h1>How to write your own Axis2 transport</h1>
+
+<h2>Prologue</h2>
+
+<p>To stop you from reinventing the wheel I will quickly list the transports
+that are already supported in Axis2 with a small description before we get
+started.</p>
+
+<p></p>
+<ul>
+ <li><b>HTTP</b> - In the HTTP transport, the transport Listener is a
+ Servlet or a Simple HTTP server provided by Axis2. The transport Sender
+ uses sockets to connect and send the SOAP Message. Currently we have the
+ commons-httpclient based HTTP Transport sender as the default
+ transport.</li>
+ <li><b>TCP</b> This is the most simple transport, but needs addressing
+ support to be functional.</li>
+ <li><b>SMTP</b> This can work off a single email account or a mailserver.
+ The Mail Transport Receiver is a tread that checks for emails in fixed
+ time intervals.</li>
+</ul>
+
+<p>To understand the rest of this document you will need some understanding
+of the Architecture of Axis2. Therefor if you are not familiar with the
+Architecture of Axis2 you will have to first read the <a
+href="Axis2ArchitectureGuide.html">Axis2 Architecture Guide</a> before you
+read any further.</p>
+
+<h2>Introduction</h2>
+
+<p>Broadly speaking a transport inside Axis2 can be classified as a way of
+getting a messages that arrive though some channel into the Axis2 engine. The
+core of Axis2 is transport independent. All data that is transport specific
+is striped out of the incoming message and inserted into the MessageContext
+and on the outgoing message all transport specific information like headers
+are added and sent.</p>
+
+<p>To write your own transport you will need to primarily write two classes,
+one is the TransportSender and the other is the TransportReceiver. To
+register a transport with Axis2 you will need to put two entries in the
+axis2.xml file. One for the transport receiver and the other for the
+transport sender. We will walk though the process of adding the entries in
+the relevent sections.</p>
+
+<h2>Transport Receiver</h2>
+
+<p>Any message that is comming into Axis2 needs to go though a transport
+receiver. All information about how the message is received at the Axis2
+server from the wire [or by snail mail for that matter:)] is isolated inside
+the transport receiver. It extracts the data that is coming on the wire and
+transforms it into a state that the Axis2 server understands.</p>
+
+<p>So now that we have some background information about how transports work
+inside Axis2 with out further delay why don't we dive into some coding and
+start building out own transport.</p>
+
+<p></p>
+
+<p>To get things stared you will first need to extend from the
+org.apache.Axis2.transport.TransportListener class and write you own
+transport listener. To create an engine to process the MessageContext we need
+a configuration context. The following code fragment will do this. This
+should ideally be only done once for the lifetime of the Transport
+receiver.</p>
+
+<p><source></p>
+<pre>try {
+ //Create a factory
+ ConfigurationContextFactory factory = new ConfigurationContextFactory();
+ //Use the factory and an Axis2 repository to create a new Configuration Context
+ configurationContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem(repository_directory,
+axis2xmllocation);
+} catch (Exception e) {
+ log.info(e.getMessage());
+}</pre>
+</source>
+<p>Now we need some kind of a listener to listen to the requests that come
+in. This you will need to implement according to the transport that you are
+trying to build. After a message is received at the receiver you can use the
+following code to process the request and then forward the message context to
+the engine using thing the engine.receive(msgContext) method.{Following code
+snippet extracted from MailListener as an example}</p>
+<source><pre>AxisEngine engine = new AxisEngine(configurationContext);
+MessageContext msgContext = null;
+// create and initialize a message context
+try {
+ TransportInDescription transportIn =
+ reg.getAxisConfiguration().getTransportIn(new QName(Constants.TRANSPORT_NAME));
+ TransportOutDescription transportOut =
+ reg.getAxisConfiguration().getTransportOut(new QName(Constants.TRANSPORT_NAME));
+ if (transportIn != null && transportOut != null) {
+ //create Message Context
+ msgContext = new MessageContext(configurationContext, transportIn, transportOut);
+ msgContext.setServerSide(true);
+ msgContext.setProperty(MailSrvConstants.CONTENT_TYPE, message.getContentType());
+ msgContext.setProperty(MessageContext.CHARACTER_SET_ENCODING, message.getEncoding());
+
+ String soapAction = message.getSOAPActionHeader();
+ msgContext.setWSAAction(soapAction);
+ msgContext.setSoapAction(soapAction);
+
+ // Here we are trying to set the reply to if it is present in the transport information.
+ msgContext.setReplyTo(new EndpointReference(message.getReplyTo());
+
+ //Create the SOAP Message -- This code in from the mail transport and will change depending
+ //on how the data is handled in each transport.
+ ByteArrayInputStream bais = new ByteArrayInputStream(message.getContent().toString().getBytes());
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(bais);
+
+ String soapNamespaceURI = "";
+ if(message.getContentType().indexOf(SOAP12Constants.SOAP_12_CONTENT_TYPE) > -1){
+ soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
+ }else if(message.getContentType().indexOf(SOAP11Constants.SOAP_11_CONTENT_TYPE) > -1){
+ soapNamespaceURI = SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
+ }
+
+ StAXBuilder builder = new StAXSOAPModelBuilder(reader, soapNamespaceURI);
+
+ SOAPEnvelope envelope = (SOAPEnvelope) builder.getDocumentElement();
+ msgContext.setEnvelope(envelope);
+ if (envelope.getBody().hasFault()) {
+ engine.receiveFault(msgContext);
+ } else {
+ engine.receive(msgContext);
+ }
+ } else {
+ throw new AxisFault(Messages.getMessage("unknownTransport",Constants.TRANSPORT_NAME));
+ }
+
+} catch (Exception e) {
+ try {
+ if (msgContext != null) {
+ MessageContext faultContext = engine.createFaultMessageContext(msgContext, e);
+ engine.sendFault(faultContext);
+ } else {
+ log.error(e);
+ }
+ } catch (AxisFault e1) {
+ log.error(e);
+ }
+}</pre>
+</source>
+<p>Now we have the coding in place and we need to let Axis2 know about our
+new transport receiver. How we do this is by addind an entry into the
+axis2.xml file. If you need to pass any properties for the transport to
+operate it can also be done through the axis2.xml file.</p>
+<source><pre> <transportReceiver name="TRANSPORT_NAME" class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_LISTNER_CLASS">
+ <parameter name="PROPERTY_NAME" locked="false">PROPERTY_VALUE</parameter>
+ <parameter name="PROPERTY_NAME_2" locked="false">PROPERTY_VALUE_2</parameter>
+ </transportReceiver>
+ </pre>
+</source>
+<p>Using a code fragment like
+Utils.getParameterValue(transportOut.getParameter(MailSrvConstants.SMTP_USER))
+we can extract the parameters that we insert into the axis2.xml file.</p>
+
+<p>So as you can see getting a new transport receiver up and running is a
+task that requires very little effort.</p>
+
+<h2>Transport Sender</h2>
+
+<p>Any message that is to be sent out from Axis2 is sent through the
+Transport Sender. The Transport Sender needs to be extended from the
+org.apache.Axis2.transport.AbstractTransportSender class.</p>
+
+<p>The following bit of code from the abstract transport sender will call the
+Transport Sender that you wrote.</p>
+<source><pre>// If an EPR is present then the message is going on a diffrent channel.
+if (epr != null) {
+ out = openTheConnection(epr, msgContext);
+ OutputStream newOut = startSendWithToAddress(msgContext, out);
+ if (newOut != null) {
+ out = newOut;
+ }
+ writeMessage(msgContext, out);
+ finalizeSendWithToAddress(msgContext, out);
+ } else {
+ out = (OutputStream) msgContext.getProperty(MessageContext.TRANSPORT_OUT);
+ if (out != null) {
+ startSendWithOutputStreamFromIncomingConnection(msgContext, out);
+ writeMessage(msgContext, out);
+ finalizeSendWithOutputStreamFromIncomingConnection(msgContext, out);
+ } else {
+ throw new AxisFault(
+ "Both the TO and Property MessageContext.TRANSPORT_WRITER is Null, No way to send response.");
+ }
+}</pre>
+</source>
+<p>So depending on whether your transport is using the same channel to send
+the responce or using a different channel you will need to implement a
+sub-set of the methods from the abstract class.</p>
+
+<p>After implementing the necessary methods you can let Axis2 know about your
+new transport sender by adding an entry to the axis2.xml file like you did
+for the Transport Receiver.</p>
+<source><pre> <transportSender name="TRANSPORT_NAME" class="org.apache.Axis2.transport.TRANSPORT_NAME.TRANSPORT_SENDER_CLASS">
+ <parameter name="PROPERTY_NAME" locked="false">PROPERTY_VALUE</parameter>
+ <parameter name="PROPERTY_NAME_2" locked="false">PROPERTY_VALUE_2</parameter>
+ </transportSender>
+ </pre>
+</source>
+<p>Have a look at org.apache.Axis2.transport.mail.MailTransportSender for a
+very simple Transport Sender. Also have a look at
+org.apache.Axis2.transport.http.CommonsHTTPTransportSender which is used to
+send HTTP responses.</p>
+
+<p>Once we have written our transport receiver and our transport sender, and
+inserted the needed entries into the axis2.xml file we are done. It is as
+simple as that. :-)</p>
+</body>
+</html>