<?xml version="1.0" encoding="UTF-8"?>

<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements. See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership. The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License. You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied. See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
  -->

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 14 June 2007), see www.w3.org" />
<meta http-equiv="content-type" content="" />
<title>Introducing Axis2</title>
</head>
<body>
<a name="buildservices" id="buildservices"></a>
<h1>Apache Axis2 User's Guide -Building Services</h1>
<p>Now that you know how to use Axis2 to generate clients from
WSDL, this section digs a little deeper showing you how to create
services, and also how to create services and clients "from
scratch", so to speak.</p>
<ul>
<li><a href="userguide.html#intro">Introducing Axis2</a><br />
<ul>
<li><a href="userguide.html#whatis">What is Axis2?</a></li>
<li><a href="userguide.html#underhood">What's Under the
Hood?</a></li>
<li><a href="userguide.html#handlessoap">How Axis2 Handles SOAP
Messages</a></li>
<li><a href="userguide.html#distributions">Axis2
Distributions</a></li>
<li><a href="userguide.html#sbd">The Axis2 Standard Binary
Distribution</a></li>
<li><a href="userguide.html#hierarchy">Axis2.war Directory
Hierarchy</a></li>
<li><a href="userguide.html#docs">Axis2 Documents
Distribution</a></li>
<li><a href="userguide.html#clients">Axis2 and Clients</a></li>
</ul>
</li>
<li><a href=
"userguide-installingtesting.html#installingtesting">Installing and
Testing Client Code</a></li>
<li><a href=
"userguide-introtoservices.html#introservices">Introduction to
Services</a><br />
<ul>
<li><a href=
"userguide-introtoservices.html#messageexchange">Message Exchange
Patterns</a></li>
</ul>
</li>
<li><a href="userguide-creatingclients.html#createclients">Creating
Clients</a><br />
<ul>
<li><a href=
"userguide-creatingclients.html#choosingclient">Choosing a Client
Generation Method</a></li>
<li><a href="userguide-creatingclients.html#generating">Generating
Clients</a></li>
<li><a href="userguide-creatingclients.html#adb">Axis Data Binding
(ADB)</a></li>
</ul>
</li>
<li><a href=
"userguide-buildingservices.html#buildservices"><strong>Building
Services</strong></a><br />
<ul>
<li><a href=
"userguide-buildingservices.html#getcomfortable"><strong>Getting
Comfortable with Available Options</strong></a></li>
<li><a href=
"userguide-buildingservices.html#createscratch"><strong>Creating a
Service from Scratch</strong></a></li>
<li><a href=
"userguide-buildingservices.html#deploypojo"><strong>Deploying
Plain Old Java Objects</strong></a></li>
<li><a href=
"userguide-buildingservices.html#deployrun"><strong>Deploying and
Running an Axis2 Service Created from WSDL</strong></a></li>
</ul>
</li>
<li><a href="userguide-samples.html">Samples</a></li>
<li><a href="userguide-forfurtherstudy.html">For Further
Study</a></li>
</ul>
<p><a name="getcomfortable" id="getcomfortable"></a></p>
<h2>Getting Comfortable with the Available Options</h2>
<p>Axis2 provides a number of ways to create a service, such
as:</p>
<ul>
<li>Create a service and build it from scratch. In this case, you
build your service class to specifically access AXIOM OMElement
objects, then create the services.xml file and package it for
deployment.</li>
<li>Deploy Plain Old Java Objects (POJOs) as a service.</li>
<li>Generate the service from WSDL. Just as you can generate
clients with WSDL, you can also generate the skeleton of a
service.</li>
</ul>
<p>Let's look at these three options.</p>
<a name="createscratch" id="createscratch"></a>
<h2>Creating a Service from Scratch</h2>
<p>Creating a service from scratch is not the most convenient way
to do it, but it does give you the most control. The process
involves several steps.</p>
<p><b>The short story:</b></p>
<ol>
<li>Create the service class with each operation that is
represented by a method that takes an org.apache.axiom.om.OMElement
object as its argument. (An OMElement is how the AXIs2 Object Model
(AXIOM) represents an XML element.)</li>
<li>Create the service descriptor, services.xml, which defines the
class to be used by the service and the appropriate message
receivers.</li>
<li>Create the .aar file, with the classes in their proper
locations based on the package and the services.xml file in the
META-INF directory.</li>
<li>Deploy the .aar file by using the <a href=
"webadminguide.html">Web Administration application</a> or by
copying it to the Axis2 services directory.</li>
</ol>
<p><b>The long story:</b></p>
<p>Start by creating the service class, a plain Java class that
uses classes from the Axis2 libraries (see Code Listing 8).</p>
<h3>Code Listing 8-Creating the Service Class</h3>
<pre>
package org.apache.axis2.axis2userguide;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;

public class SampleService {

    public OMElement sayHello(OMElement element) 
                             throws XMLStreamException {
            element.build();
            element.detach();

            String rootName = element.getLocalName();
            System.out.println("Reading "+rootName+" element");
            
            OMElement childElement = element.getFirstElement();
            String personToGreet = childElement.getText();

            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = fac.createOMNamespace(
                    "http://example1.org/example1", "example1");
            OMElement method = fac.createOMElement("sayHelloResponse", 
omNs);
            OMElement value = fac.createOMElement("greeting", omNs);
            value.addChild(fac.createOMText(value, "Hello, 
"+personToGreet));
            method.addChild(value);

            return method;
        }

     private void ping(){
     }
    
}
</pre>
<p>Make sure to include Axis2 libraries in your class path when
compiling the source.</p>
<p>Axis2 uses AXIOM, or the AXIs Object Model, a DOM (Document
Object Model) -like structure that is based on the StAX API (
Streaming API for XML). Methods that act as services must take an
OMElement as their argument, which represents the payload of the
incoming SOAP message. (An OMElement is just AXIOM's way of
representing an XML element, like a DOM Element object.) In this
case, you're extracting the contents of the first child of the
payload element, adding text to it, and using it as content for the
return OMElement. Unless this is an "in only" service, these
methods must return an OMElement, because that becomes the payload
of the return SOAP message.</p>
<p>To turn this class into a service, create the service
description file, services.xml, as in Code Listing 9.</p>
<h3>Code Listing 9 - Create the Service Description</h3>
<pre>
&lt;service name="UserGuideSampleService"&gt;
    &lt;description&gt;
        This is a sample service created in the Axis2 User's Guide
    &lt;/description&gt;

    &lt;parameter name="ServiceClass" 
&gt;org.apache.axis2.axis2userguide.SampleService
&lt;/parameter&gt;

    &lt;operation name="sayHello"&gt;
        &lt;messageReceiver 
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/&gt;
    &lt;/operation&gt;
    &lt;operation name="ping"&gt;
        &lt;messageReceiver 
class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/&gt;
    &lt;/operation&gt;
&lt;/service&gt;
</pre>
<p>This document defines the service, called by the <a href=
"webadminguide.html">Web Administration Application</a>, and the
class used to serve requests. For each operation, it defines the
appropriate message receiver class.</p>
<p>Create a new directory, META-INF, in the main directory for the
class. (In this case, that's the same directory that contains the
org directory) and place the services.xml file in it.</p>
<p>Create the .aar file by typing: jar cvf SampleService.aar
./*</p>
<p>Deploy the SampleService.aar file by using the <a href=
"webadminguide.html">Web Administration application</a> or by
copying it to the Axis2 services directory.</p>
<p>Now you can create a client class that accesses the service
directly (see Code Listing 10).</p>
<h3>Code Listing 10 - Create a Client Class that Accesses the
Service Directly</h3>
<pre>
package org.apache.axis2.axis2userguide;

import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;

public class SampleClient {

       private static EndpointReference targetEPR = 
             new EndpointReference(
               "http://localhost:8080/axis2/services/UserGuideSampleService");

        public static OMElement greetUserPayload(String personToGreet) {
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = fac.createOMNamespace(
                    "http://example1.org/example1", "example1");
            OMElement method = fac.createOMElement("sayHello", omNs);
            OMElement value = fac.createOMElement("personToGreet", 
omNs);
            value.addChild(fac.createOMText(value, personToGreet));
            method.addChild(value);
            return method;
        }

        public static void main(String[] args) {
            try {
                OMElement payload = 
SampleClient.greetUserPayload("John");
                Options options = new Options();
                options.setTo(targetEPR);
                
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

                ServiceClient sender = new ServiceClient();
                sender.setOptions(options);
                OMElement result = sender.sendReceive(payload);

                String response = result.getFirstElement().getText();
                System.out.println(response);

            } catch (Exception e) { //(XMLStreamException e) {
                System.out.println(e.toString());
            }
        }
    
}
</pre>
<p>This class uses the same technique of sending and receiving
OMElements, but it's also important to note the use of the Options
class. This class enables you to determine properties such as the
transport used for the return message (the transport used for the
outgoing message can be inferred from the URL of the destination)
and the SOAP version to use. In addition to providing setter and
getter methods of specific properties that affect how the client
interacts with the service, the Options class enables you to create
inheritance relationships between Options objects. So if a property
is not found in the current Options object used, the client can
check the parent Options object of the current Options object.</p>
<p>Compile and run the above SampleClient.java. Make sure to have
all axis2 libraries in your class path. If all has gone well,
'Hello, John' will be shown as the output in the console.</p>
<a name="deploypojo" id="deploypojo"></a>
<h2>Deploying Plain Old Java Objects (POJOs)</h2>
<p>One very easy way to create a Web service is simply to deploy
the Java objects that represent the service. Start with the class,
shown in Code Listing 11.</p>
<h3><b>Code Listing 11 - Creating the Class SampleService</b></h3>
<pre>
package org.apache.axis2.axis2userguide;

public class SampleService {

    public void doInOnly(){
     return; 
    } 
     
    public String noParameters(){
      return "Hello";
    } 
    
    public String twoWayOneParameterEcho(String toEcho){
      return toEcho;
    } 
    
    public boolean multipleParametersAdd(float price, int itemId, 
                             String description, String itemName){
      //Code to handle the logic
                return true;
    } 
 
}
</pre>
<p>Next, you'll need to tell Axis2 what class corresponds with what
Web service calls. Do this by creating a file called services.xml
and adding the following shown in Code Listing 12.</p>
<h3><b>Code Listing 12 - Creating services.xml</b></h3>
<pre>
&lt;service name="SampleService" scope="application"&gt;
    &lt;description&gt;
        Sample Service
    &lt;/description&gt;
    &lt;messageReceivers&gt;
        &lt;messageReceiver 
            mep="http://www.w3.org/ns/wsdl/in-only"
    class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/&gt;
        &lt;messageReceiver
            mep="http://www.w3.org/ns/wsdl/in-out"
    class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/&gt;
    &lt;/messageReceivers&gt;
    &lt;parameter name="ServiceClass"&gt;
        org.apache.axis2.axis2userguide.SampleService
    &lt;/parameter&gt;
&lt;/service&gt;
</pre>
<p>This file makes the InOnly and InOut MEPs available to the
service and tells Axis2 which class to call; operations must match
method names. In other words, Axis2 automatically sends a call to
the multipleParametersAdd operation to the
org.apache.axis2.axis2userguide.SampleService.multipleParametersAdd()
method.</p>
<p>Now it's time to create the distribution. Arrange your files in
the following directory structure (see Code Listing 13).</p>
<h3><b>Code Listing 13- Create the Directory Structure for the
Distribution</b></h3>
<pre>
 - SampleService
   - META-INF
     - services.xml
   - org
     - apache
       - axis2
         - axis2userguide
           - SampleService.class
</pre>
<p>Finally, deploy the service by copying the SampleService
directory to the webapps/axis2/WEB-INF/services directory on the
servlet engine. You can check to make sure that it's been properly
deployed by checking http://&lt;host&gt;:&lt;port&gt;/axis2/services/listServices.</p>
<a name="deployrun" id="deployrun"></a>
<h2>Deploying and Running an Axis2 Service Created from WSDL</h2>
<p>If you have a WSDL file, you can easily create and deploy a
service based on that description. For example, to create a service
based on the same WSDL file used in the <a href=
"userguide-creatingclients.html">clients section</a> of this
document, you will follow the steps below.</p>
<p><b>The short story:</b></p>
<ol>
<li><a href="../download.cgi">
Download</a> the Axis2 standard distribution, if you have not done
so already.</li>
<li>Generate the skeleton using the WSDL2Java utility, as in:<br />
<pre>
java org.apache.axis2.wsdl.WSDL2Java -uri file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p org.apache.axis2.axis2userguide -d adb -s -wv 1.1 -ss -sd -ssi
</pre></li>
<li>Open the *Skeleton.java file and add the functionality of your
service to the generated methods.</li>
<li>Build a service using Ant by typing ant jar.server</li>
<li>Deploy the service by copying the build/lib/*.aar file to
&lt;J2EE_HOME&gt;/webapps/axis2/WEB-INF/services</li>
<li>Check
http://&lt;server&gt;:&lt;port&gt;/axis2/services/listServices to
make sure the service has been properly deployed.</li>
</ol>
<p><b>The long story:</b></p>
<p>As with generating clients, you will need the <a href="../download.cgi">
Axis2 Standard Distribution</a>, because the <a href="../download.cgi">
Axis2 WAR Distribution</a> does not include the WSDL2Java utility.
Once you've got it downloaded and unpacked, make sure that you set
the AXIS2_HOME variable to point to the location in which you've
unpacked it.</p>
<p>Now you are ready to generate the actual service. To keep things
neat, create a new directory and change to it. The WSDL file is the
same one referenced in <a href=
"userguide-creatingclients.html#generating.xhtml">Generating Clients</a>
and includes four operations: NoParameters, TwoWayOneParameterEcho,
MultipleParametersAddItem, and DoInOnly. To generate the service,
use the WSDL2Java utility, as in Code Listing 14.</p>
<h3>Code Listing 14 - Using the WSDL2Java Utility to Generate the
Service</h3>
<p><strong>Code Listing 14.1:</strong></p>
<pre>
java org.apache.axis2.wsdl.WSDL2Java -uri 
file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p 
org.apache.axis2.axis2userguide -d adb -s -wv ${axis2_version} -ss -sd
</pre>
<p>Note: Make sure all the .jar files in the Axis2 lib directory is
set to the CLASSPATH before you run the above code.</p>
<p>This statement tells the utility you want to create a service
out of the operations in the file <a href=
"userguide-codelisting5.html">Axis2UserGuide.wsdl</a>, and that the
Java classes generated should be in the
org.apache.axis2.axis2userguide package (-p). (You can view the
appropriate directories created.) It also indicates that you want
to use the Axis2 DataBinding Framework, or ADB (-d), to generate
only synchronous or blocking code (-s), and to generate server-side
code (-ss) as opposed to a client, including the services.xml
service descriptor file (-sd). It also specifies version
${axis2_version} for the WSDL file (-wv)<strong>.</strong></p>
<p><strong>Code Listing 14.2:</strong></p>
<p>You can also use the following script files to achieve the same.
In this case you do not have the set the CLASSPATH manually.</p>
<p>For Linux:</p>
<pre>
$AXIS2_HOME/bin/wsdl2java.sh -uri file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl
-p org.apache.axis2.axis2userguide -o target_directory_name -d adb -s -wv ${axis2_version} -ss -sd
</pre>
<p>For MS Windows:</p>
<pre>
%AXIS2_HOME%\bin\wsdl2java.bat -uri file:\\\C:\apps\axis2\samples\zSample\Axis2UserGuide.wsdl
-p org.apache.axis2.axis2userguide -o target_directory_name -d adb -s -wv ${axis2_version} -ss -sd
</pre>
<p>In both instances, at this point, you should see four new items
in your chosen directory: the build.xml file, which includes
instructions for Ant, the src directory, which includes all the
generated classes and stubs, the resources directory, which
includes a regenerated version of the WSDL, and the services.xml
file, which ultimately controls the service's behavior.</p>
<p>You can compile the service at this point, but it doesn't
actually do anything yet. You can solve that problem by opening the
src\org\apache\axis2\axis2userguide\Axis2UserGuideServiceSkeleton.java
file and either editing the code in bold -- make sure you manage
parameter numbers -- or replacing all the code with the following
in Code Listing 15.</p>
<h3>Code Listing 15 - Compiling the Service</h3>
<pre>
/**
 * Axis2UserGuideServiceSkeleton.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: SNAPSHOT Oct 15, 2006 (11:23:18 
GMT+00:00)
 */
package org.apache.axis2.axis2userguide;
/**
 *  Axis2UserGuideServiceSkeleton java skeleton for the axisService
 */
public class Axis2UserGuideServiceSkeleton {
     
         
    /**
     * Auto generated method signature
         
     * @param param7
         
    */
    public  org.apache.axis2.axis2userguide.NoParametersResponse 
NoParameters
        (org.apache.axis2.axis2userguide.NoParametersRequest param7)
         
    {
        <b>System.out.println(param7);

        NoParametersResponse res =
            new NoParametersResponse();

        return res;</b>
    }
     
         
    /**
     * Auto generated method signature
         
     * @param param9
         
    */
    public  
org.apache.axis2.axis2userguide.TwoWayOneParameterEchoResponse 
TwoWayOneParameterEcho
        (
         org.apache.axis2.axis2userguide.TwoWayOneParameterEchoRequest 
param9
         )
         
    {
        <b>System.out.println(param9.getEchoString());

        TwoWayOneParameterEchoResponse res =
            new TwoWayOneParameterEchoResponse();
        
        res.setEchoString(param9.getEchoString());

        return res;</b>
    }
     
         
    /**
     * Auto generated method signature
         
     * @param param11
         
    */
    public  void DoInOnly
        (
         org.apache.axis2.axis2userguide.DoInOnlyRequest param11
         )
         
    {
        <b>System.out.println(param11.getMessageString());</b>
    }
     
         
    /**
     * Auto generated method signature
         
     * @param param12
         
    */
    public  
org.apache.axis2.axis2userguide.MultipleParametersAddItemResponse 
MultipleParametersAddItem
        (
         
org.apache.axis2.axis2userguide.MultipleParametersAddItemRequest 
param12
         )
         
    {
        <b>System.out.println(param12.getPrice());
        System.out.println(param12.getItemId());
        System.out.println(param12.getDescription());
        System.out.println(param12.getItemName());

        MultipleParametersAddItemResponse res =
            new MultipleParametersAddItemResponse();
        
        res.setSuccessfulAdd(true);
        res.setItemId(param12.getItemId());

        return res;</b>
    }
     
}
</pre>
<p>As with generating clients, all these classes, such as
MultipleParametersAddItemRequest and
TwoWayOneParameterEchoResponse, are generated by the utility, and
can be found in the same directory as the skeleton file. They
include methods such as setSuccessfulAdd(), which sets the value of
the content of an element in the response, and getItemName(), which
retrieves the content of elements in the request.</p>
<p>Save the file and compile it by typing: ant jar.server</p>
<p>If all goes well, you should see the BUILD SUCCESSFUL message in
your window, and the Axis2UserGuideService.aar file in the newly
created build/lib directory.</p>
<p><img alt="The BUILD SUCCESSFUL message in your window" src=
"images/fig05.jpg" /></p>
<p>Now you need to deploy the service to the server. To do that,
copy the Axis2UserGuideService.aar file to the WEB-INF/services
directory of the application server. (You also have the option to
use the administration tools. See the <a href=
"webadminguide.html">Web Administrator's Guide</a> for more
information.)</p>
<p>To verify that the service has been properly deployed, check the
list of services at http://&lt;host&gt;:&lt;port&gt;/axis2/services/listServices.</p>
<p><img alt="Checking the list of services" src=
"images/fig06.jpg" /></p>
<p>Now you should be able to access the service using any of the
clients built in the <a href=
"userguide-creatingclients.html#generating">Generating Clients</a>
document.</p>
<p><strong>See Next Section</strong>- <a href=
"userguide-samples.html">Samples</a></p>
</body>
</html>
