9.2. Web services as normal java classes

You could implement a web service as a simple java class (plain old java object or POJO). All you need is an additional deployment descriptor. To avoid maintaining this descriptor seperately from the java source code, I will use XDoclet comments to generate it.

Beside the actual java class you need two more things: an ant script and a XDoclet template.

Figure 9.1.  change the output folder

To force Eclipse to write the compiled class files to the right location, set the output directory in project preferences directly to the web containers WEB-INF/classes directory (see example project):

9.2.1. A web service

In the included sample project an easy web service is realized:

/**
 * @author sr
 * @axis.service name="MyTestService" scope="Request" enable-remote-admin="true"1
 * @axis.useHandler name="track"
 */
public class TestService {

    /**
     * calcs a sum.
     * @axis.method2
     * @param p1 first parameter
     * @param p2 second parameter
     * @return the sum of both parameters
     */
    public int sum( int p1, int p2 ) {
        return p1+p2;
    }
    
    /**
     * gets the address
     * @axis.method
     * @param id
     * @return the address
     */
    public String getAddress( int id){
        return null; 
    }

}
1 these XDoclet tags declare the class a web service.
2 @axis.method marks a method for export as web service method. This method is thereby callable „extermally“.

9.2.2. The XDoclet template

Included in the sample project is a special XDoclet template, which generates a deployment descriptor for Axis. It evaluates the tags described in chapter 10 and generates a „deploy.wsdd“ file.

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

<deployment
 xmlns="http://xml.apache.org/axis/wsdd/"
 xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
 xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">

<XDtClass:forAllClasses>

<!-- ... check for Handlers -->

</XDtClass:forAllClasses>

<XDtClass:forAllClasses>

<XDtClass:ifHasClassTag tagName="axis.service" paramName="name">

 <service name="<XDtClass:classTagValue tagName="axis.service" paramName="name"/>"

<!-- ... -->

     <XDtClass:ifDoesntHaveClassTag tagName="axis.service" paramName="provider">
       <XDtType:ifIsOfType type="javax.ejb.EntityBean,javax.ejb.SessionBean">
       provider="java:EJB"
       </XDtType:ifIsOfType>
       <XDtType:ifIsNotOfType type="javax.ejb.EntityBean,javax.ejb.SessionBean">
       provider="java:RPC"
       </XDtType:ifIsNotOfType>
       >
     </XDtClass:ifDoesntHaveClassTag>

     <XDtClass:ifHasClassTag tagName="axis.useHandler" paramName="name">
     <requestFlow>
         <handler type="<XDtClass:classTagValue tagName="axis.useHandler" paramName="name"/>"/>
     </requestFlow>
     </XDtClass:ifHasClassTag>

     <parameter name="className" value="<XDtClass:fullClassName/>" />

    <!-- check if remoteAdmin param is present -->
     <XDtClass:ifHasClassTag tagName="axis.service" paramName="enable-remote-admin">
       <parameter name="enableRemoteAdmin" value="<XDtClass:classTagValue tagName="axis.service" paramName="enable-remote-admin"/>" />
     </XDtClass:ifHasClassTag>

     <parameter name="allowedMethods"

     <XDtClass:ifDoesntHaveClassTag tagName="axis.service" paramName="include-all">
       <XDtEjbSession:ifStatelessSession>
                value="create"
       </XDtEjbSession:ifStatelessSession>

       <XdtEjbSession:ifStatefulSession>
                value="<XDtMethod:forAllMethods><XDtEjbHome:ifIsCreateMethod><XDtMethod:methodName/> </XdtEjbHome:ifIsCreateMethod></XDtMethod:forAllMethods>"
       </XDtEjbSession:ifStatefulSession>

       <XDtType:ifIsNotOfType type="javax.ejb.SessionBean">
                value="<XDtMethod:forAllMethods><XDtMethod:ifHasMethodTag tagName="axis.method"><XDtMethod:methodName/>
 </XDtMethod:ifHasMethodTag></XDtMethod:forAllMethods>"
       </XDtType:ifIsNotOfType>

     </XDtClass:ifDoesntHaveClassTag>

     <XDtClass:ifHasClassTag tagName="axis.service" paramName="include-all">
                value="*"
     </XDtClass:ifHasClassTag>
     />

     <parameter name="scope" value="<XDtClass:classTagValue tagName='axis.service' paramName='scope' value='request,session,application' default='request'/>"/>

 </service>

</XDtClass:ifHasClassTag>

</XDtClass:forAllClasses>

</deployment>

9.2.3. The build script

The ant script controls the generation of the deployment descriptor with XDoclet and can afterwards deploy the web service into the running Axis. To achieve this, include Axis ant tasks contained in axis-ant.jar and deploy the web service with the „admin task“. The script is configured in build.properties, which contains all local pathes and settings.

<project name="webmodulebuilder" default="axis-deploy" basedir=".">

 <!-- set global properties for this build -->
 <property file="build.properties"/>
 <property name="dist" value="../../dist" />
 <property name="web" value="../" />

 <property name="src" value="../../src/" />
 <property name="output" value="${basedir}" />

 <path id="XDoclet.class.path">1
    <fileset dir="${XDocletlib.dir}">
        <include name="*.jar"/>
    </fileset>
 </path>

 <path id="axis.classpath">2
     <!-- use the webapps lib path, where all axis jars are present -->
     <fileset dir="${basedir}/lib">
         <include name="**/*.jar" />
     </fileset>
 </path>

 <target name="axisdoclet">
         <taskdef3
             name="templatedoclet"
             classname="XDoclet.DocletTask"
             classpathref="XDoclet.class.path"
         />

         <tstamp>
             <format property="TODAY" pattern="d-MM-yy"/>
         </tstamp>

         <templatedoclet destdir="${output}" verbose="1">4
            <fileset dir="${src}">
                <include name="**/*.java" />5
            </fileset>

            <template templateFile="axis-wsdd.xdt.xml" destinationFile="deploy.wsdd">
                <configParam name="Xmlencoding" value="utf-8" />
            </template>

         </templatedoclet>
 </target>

 <target name="axis-deploy" depends="axisdoclet">6

     <taskdef resource="axis-tasks.properties" classpathref="axis.classpath" />7

     <axis-admin8
         port="${target.port}"
         hostname="${target.server}"
         failonerror="true"
         servletpath="${target.appname}/services/AdminService"
        debug="true"
         xmlfile="deploy.wsdd"
     />

 </target>
</project>
1 This path definition sets the classpath for XDoclet. To use XDoclet tasks in ant the XDoclet libraries must be available. Thus build.property „XDocletlib.dir“ sets the directory where to find the libraries.
2 This path definition sets the classpath for Axis. To use Axis tasks the Axis libraries must be available. In this example I will use a reference to the WEB-INF/lib directory, because all Axis libraries are already installed in lib.
3 This taskdef tag defines the template task for XDoclet.
4 The „templatedoclet“ tag excutes the XDoclet template to generate the deployment descriptor.
5 The fileset specifies that all java source files in the src folder are taken into account.
6 The „axis-deploy“ target executes the deployment. It depends on the axisdoclet target, so the deployment descriptor is generated if nessesary. Note: the axis application must run inside Tomcat to deploy a new web service.
7 This taskdef tag defines all ant tasks supported by ant (see Axis documentation).
8 The „axis-admin“ task actually deploys the web service. For this all parameters in the build.property file must sets to their correct values (especially target.port, target.server and so on). In addition the server must run and the AdminServlet must be activated (see web.xml in the example project).

You can see the active web services by rerequesting the Axis page /axis/servlet/AxisServlet. By the way the servlet itself uses the xml file „server-config.wsdd“ to list all active web services. When a new service is deployed Axis will adjust this file accordingly.