Tuesday 4 December 2012

How to write a web service using Apache Axis2 Web Server, create .aar file, engaging a module to capture SOAP messages (raw)

<!--[if !mso]> <![endif]

How to write a web service using Apache Axis2 Web Server, create .aar file, engaging a module to capture SOAP messages (raw)


Tools: Apache Tomcat 6.x, Axis2 WebServer, Eclipse IDE, Java 7

What is Apache Axis2?

 

How to write an Apache Axis2 Web Service in Eclipse:

 It explains all the steps about how to create a web service in Apache Axis2 and create an .aar. Please read it to have the understanding about Axis2.

For more understanding please refer the book.


Explanation of the web service created by me:

packagecom.cantext.sayhello;
public class SayHello {
public String sayHelloMethod(String val){
return "Hello "+val+" !";
}
}

My services.xml file:
<service name="SayHello" >
<Description>
Please Type your service description here
</Description>
<messageReceivers>
<messageReceivermep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceivermep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">com.cantext.sayhello.SayHello</parameter>
</service>

My Folder Stricture:




How to Create .aar (Axis Archive) file and how to Deploy a Service is explained in the link given below:


After that we can start the development of the Axis2 Module. For that purpose I use the Eclipse IDE. Create a new java project in Eclipse and have the following structure in your project. 






 Here you can see that Axis2 has been added as a library to the project. To do it, right click on the project and got to Build Path > Configure Build Path. There you can find a button called Add Library, click on it and select User Library in the appearing screen. There go to new and add all the jar files in the lib folder in the axis2 home folder. 
Then the definition of the TestModule.java is this,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
packageorg.wso2.testa2m;

importorg.apache.axis2.AxisFault;
importorg.apache.axis2.context.ConfigurationContext;
importorg.apache.axis2.description.AxisDescription;
importorg.apache.axis2.description.AxisModule;
importorg.apache.axis2.modules.Module;
importorg.apache.neethi.Assertion;
importorg.apache.neethi.Policy;

publicclassTestModule implementsModule{

    publicvoidinit(ConfigurationContextconfigContext, AxisModule module) throwsAxisFault {
    }

    publicvoidengageNotify(AxisDescriptionaxisDescription) throwsAxisFault {
    }

    publicvoidshutdown(ConfigurationContextconfigurationContext) throwsAxisFault {
    }
     
    publicString[] getPolicyNamespaces() {
        returnnull;   
    }

    publicvoidapplyPolicy(Policy policy, AxisDescriptionaxisDescription) throwsAxisFault {
    }
            
    publicbooleancanSupportAssertion(Assertion assertion) {
        returntrue;
    }
}

The definition of the TestHandler.java is this,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
packageorg.wso2.testa2m;

importorg.apache.axis2.AxisFault;
importorg.apache.axis2.context.MessageContext;
importorg.apache.axis2.engine.Handler;
importorg.apache.axis2.handlers.AbstractHandler;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;

publicclassTestHandler extendsAbstractHandler implementsHandler{
    privatestaticfinalLog log = LogFactory.getLog(TestHandler.class);
    privateString name;

    publicString getName() {
        returnname;
    }

    publicInvocationResponse invoke(MessageContextmsgContext) throwsAxisFault {
        log.info("The web service "+msgContext.getAxisService().toString()+".");
        log.info("The operation is "+msgContext.getAxisOperation().toString()+".");
        log.info("This is the SOAP envelop : "+msgContext.getEnvelope().toString());
        returnInvocationResponse.CONTINUE;       
    }

    publicvoidrevoke(MessageContextmsgContext) {
        log.info("The web service "+msgContext.getAxisService().toString()+".");
        log.info("The operation is "+msgContext.getAxisOperation().toString()+".");
        log.info("This is the SOAP envelop : "+msgContext.getEnvelope().toString());
    }

    publicvoidsetName(String name) {
        this.name = name;
    }
}
After doing these, go the eclipse project folder in your machine, then in the MyModule folder you can find a folder called bin(D:\Projects\MyModule\bin) which has the generated class files of the project. Go inside it and create a folder called META-INF. In side it create the module.xml file. This is the definition of that file,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<modulename="TestModule"class="org.wso2.testa2m.TestModule">
    <InFlow>
        <handlername="InFlowLogHandler"class="org.wso2.testa2m.TestHandler">
            <orderphase="TestPhase"/>
        </handler>
    </InFlow>

    <OutFlow>
        <handlername="OutFlowLogHandler"class="org.wso2.testa2m.TestHandler">
            <orderphase="TestPhase"/>
        </handler>
    </OutFlow>

    <OutFaultFlow>
        <handlername="FaultOutFlowLogHandler"class="org.wso2.testa2m.TestHandler">
            <orderphase="TestPhase"/>
        </handler>
    </OutFaultFlow>

    <InFaultFlow>
        <handlername="FaultInFlowLogHandler"class="org.wso2.testa2m.TestHandler">
            <orderphase="TestPhase"/>
        </handler>
    </InFaultFlow>
</module>
After doing that your now in a position to create your module archive file. Go to bin(D:\Projects\MyModule\bin) folder of your project using terminal and execute foll wing command,
jar -cvf TestModule.mar *

It will create the archive file needed. Copy it to the repository/modules folder of your axis2 home folder. Now your module is ready to be deployed. Now you have to do some configuration to execute your module. Conceptually Apache Axis2 modules can be executed in two ways,
·                     Globally for all the services hosted in Axis2. To do this you have to edit the axis2.xml file
·                     Per Service. To do this you have to edit the services.xml file also.
You can find axis2.xml file in the conf folder of axis2 home folder. Edit it like this to add your custom phases to the configuration. In the phases section add the entries which are highlighted to add your definition of custom phase called "TestPhase",

<!-- ================================================= -->
<!-- Phases -->
<!-- ================================================= -->
<phaseOrder type="InFlow">
<!-- System predefined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher">
<order phase="Transport"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher">
<order phase="Transport"/>
</handler>
</phase>
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<!-- +++++++CutomePahse I have Added+++++++ -->
<phase name="TestPhase"/>
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- System predefined phases -->
<!-- After Postdispatch phase module author or service author can add any phase he want -->
<phase name="OperationInPhase">
<handler name="MustUnderstandChecker"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker">
<order phase="OperationInPhase"/>
</handler>
</phase>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
<!-- +++++++CutomePahse I have Added+++++++ -->
<phase name="TestPhase"/>
<!-- +++++++++++++++++++++++++++++++++++++++ -->
</phaseOrder>
<phaseOrder type="InFaultFlow">
<phase name="Addressing">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.dispatchers.AddressingBasedDispatcher">
<order phase="Addressing"/>
</handler>
</phase>
<phase name="Security"/>
<!-- +++++++CutomePahse I have Added+++++++ -->
<phase name="TestPhase"/>
<!-- +++++++++++++++++++++++++++++++++++++++ -->
<phase name="PreDispatch"/>
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/>
<handler name="RequestURIOperationDispatcher"
class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/>
<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/>
<handler name="HTTPLocationBasedDispatcher"
class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/>
<handler name="GenericProviderDispatcher"
class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/>
<handler name="MustUnderstandValidationDispatcher"
class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/>
</phase>
<phase name="RMPhase"/>
<!-- user can add his own phases to this area -->
<phase name="OperationInFaultPhase"/>
<phase name="soapmonitorPhase"/>
</phaseOrder>
<phaseOrder type="OutFaultFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutFaultPhase"/>
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
<!-- +++++++CutomePahse I have Added+++++++ -->
<phase name="TestPhase"/>
<!-- +++++++++++++++++++++++++++++++++++++++ -->
</phaseOrder>
After doing that you are successfully introduced the phase you have created manually, Now it is time to define the execution type of your module,
To excute it globally, add the <module ref="TestModule"/> entry to to the Global section of the axis2.xml.
1
2
3
4
5
6
7
8
9
10
    <!-- ================================================= -->
    <!-- Global Modules  -->
    <!-- ================================================= -->
    <!-- Comment this to disable Addressing -->
    <moduleref="addressing"/>
    <moduleref="TestModule"/>
    <!--Configuring module , providing parameters for modules whether they refer or not-->
    <!--<moduleConfig name="addressing">-->
    <!--<parameter name="addressingPara">N/A</parameter>-->
    <!--</moduleConfig>-->

How to Engage a Module

1: go to http://localhost:8080/axis2/ and then click on Administration





2: then you are go to Available Modules and checks which modules are available.




Now you can see list of available modules: and also you are looking my TestModule that I create:


3: now steep is engaged to module:
Goto Tools/Engage Module/For all Services and then select a module that you want to engaged module.



If you want to add a module specially for a service, add <module ref="TestModule"/> to the service.xml file. Then it will only executed only for that service.
Now your custom module is sucessfully deployed. Now you can start your axis2server again. It will show following log message if your module is successfully loaded.

After that to check it's functionality use the soapUI. Copy your web service's WSDL files link and create a soapUI project using that

Also you can take a help that link:

-->