Pages

Monday, March 26, 2007

Step by step tutorial of web service with axis2 and tomcat in java - part2

Given below is a tutorial to use axis2 in implementing web services(This shows Async/Non-Blocking call client). This tutorial extends the previous tutorial of blocking client call of web service. For more details regarding any aspect of the tutorial, the axis2 documents will assist you.
(Just for Information: The web service gives the Lucky number of a person based on date of birth, and lucky color based on lucky number of user.)

My Configuration:(same as previous)
a) AXIS2 1.1.1
b) JDK 1.5
c) ANT 1.7.0
d) TOMCAT 5.5

Before proceeding, please read the installation doc of axis2 to do a proper installation.

Step 0: Set the following paths in your system.(This step is very important)
a) AXIS2_HOME = "your axis2 installation(unzipped) directory"
b) JAVA_HOME = "your jdk installation path"
c) PATH = "add ant, axis2/bin to this"

Step 1: Create your service interface and class.

In my case:
--------------Interface-------------------
package axis2.adb.async;
import java.util.Date;
public interface MyNewService {
public String getLuckyColor(int luckNumber);
public int getLuckyNumber(Date birthDate);
}
--------------Implementation--------------
package axis2.adb.async;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class MyNewServiceImpl implements MyNewService {
static Map luckyColor = null;
static{
luckyColor = new HashMap();
luckyColor.put(new Integer(0), "Red");
luckyColor.put(new Integer(1), "Blue");
luckyColor.put(new Integer(2), "Yellow");
luckyColor.put(new Integer(3), "Pink");
luckyColor.put(new Integer(4), "Orange");
luckyColor.put(new Integer(5), "Black");
luckyColor.put(new Integer(6), "Green");
luckyColor.put(new Integer(7), "Brown");
luckyColor.put(new Integer(8), "White");
luckyColor.put(new Integer(9), "Grey");
}
public String getLuckyColor(int luckNumber) {
if(luckNumber < number =" birthDate.getDate()" lucknumber =" 0;"> 0){
luckNumber += number % 10;
number /= 10;
if(number == 0)
if(luckNumber > 9){
number = luckNumber;
luckNumber = 0;
}

}
return luckNumber;
}
}

Step 2: Generate the WSDL file using the command:
java2wsdl -cp ./bin -cn axis2.adb.async.MyNewService -of ./resource/MyNewService.wsdl
See the previous tutorial for more explanation.

Step 3: Generate the Skeleton and stub using the below command. I will be using the ADB(Axis data binding). You can use XMLBean or JiBx or AXIOM also.

wsdl2java -uri ./resource/MyNewService.wsdl -p axis2.adb.async -d adb -a -ss -sd -ssi -g -o . -S axis2ADBAsync
Here, the changes from the previous tutorial include:
a)-a switch instead of -s. -a is used for Async web Service.
b)-g switch generates the Client side stub along with the Skeleton.
c)-S switch allows you to provide the output folder

Step 4: Put the business logic inside the skeleton. The code is explained with appropriate comments.

package axis2.adb.async;
import java.util.Calendar;
import axis2.adb.async.MyNewService;
import axis2.adb.async.MyNewServiceImpl;
import axis2.adb.async.xsd.GetLuckyColorResponse;
import axis2.adb.async.xsd.GetLuckyNumberResponse;
/**
* MyNewServiceSkeleton java skeleton for the axisService
*/
public class MyNewServiceSkeleton implements MyNewServiceSkeletonInterface {
MyNewService myService = new MyNewServiceImpl();
/**
* Auto generated method signature
*
* @param param4
*
*/
public axis2.adb.async.xsd.GetLuckyColorResponse getLuckyColor(
axis2.adb.async.xsd.GetLuckyColor param4)
{
//create the response payload
GetLuckyColorResponse res = new GetLuckyColorResponse();
//get the parameter
int luckyNumber = param4.getParam0();
//businesslogic
String luckyColor = myService.getLuckyColor(luckyNumber);
//put result in payload
res.set_return(luckyColor);
//return payload
return res;
}

/**
* Auto generated method signature
*
* @param param6
*
*/
public axis2.adb.async.xsd.GetLuckyNumberResponse getLuckyNumber(
axis2.adb.async.xsd.GetLuckyNumber param6)

{
//create the response payload
GetLuckyNumberResponse res = new GetLuckyNumberResponse();
//get parameter
Calendar dOfB = param6.getParam0();
//businesslogic
int luckyNumber = myService.getLuckyNumber(dOfB.getTime());
//put result in response payload
res.set_return(luckyNumber);
//return the payload
return res;
}

}
Step 5: Create ".aar" file which has to be deployed inside axis2 using the below command.
The build.xml file is created in Step 3.

ant build.xml

Step 6: Deploy.

A new folder build is created inside the current directory. The MyNewService.aar file is present in \build\lib. Upload this using the axis2 admin page. Refer previous tutorial for more details.

Step 7: Test the service.

type http://localhost:8080/axis2/services/MyNewService?wsdl in address bar. you should get the WSDL file.

Step 8: Code the Client using the generated Stub. The code is explained with appropriate comments.

package axis2.adb.async.client;
import java.rmi.RemoteException;
import java.util.Calendar;
import java.util.Date;
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import axis2.adb.async.MyNewServiceStub;
import axis2.adb.async.MyNewServiceCallbackHandler;
import axis2.adb.async.xsd.GetLuckyColor;
import axis2.adb.async.xsd.GetLuckyNumber;

public class MyNewServiceClient {
private static int luckyNumber = 100; //assume some large number
private static String luckyColor = null;
private static boolean twoWayListnerEnabled = false; //When true a asynchronous dual channel non-blocking service will be used

public static void main(String[] args) {
MyNewServiceStub stub = null;
ConfigurationContext configContext = null;
try {
if(twoWayListnerEnabled){
//Since this is the client, addressing module has to be engaged. Copy the "repository" directory, present in %AXIS2_HOME%, to a convenient place and give its path as first argument to the below method. Copy the axis2.xml from %AXIS2_HOME%/conf into convenient location, and give its path as second argument. Edit the axis2.xml to change the port to say, 8082.
configContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repository", "repository/modules/axis2.xml");
stub = new MyNewServiceStub(configContext,"http://localhost:8080/axis2/services/MyNewService");
}else{
stub = new MyNewServiceStub(null,"http://localhost:8080/axis2/services/MyNewService");
}
// set the call back handler. Note that call back methods given override the ones in CallBackhandler abstract class.
MyNewServiceCallbackHandler myNewServiceCallBackHandle = new MyNewServiceCallbackHandler(){
public void receiveResultgetLuckyNumber(
axis2.adb.async.xsd.GetLuckyNumberResponse param43) {
luckyNumber = param43.get_return();
}
public void receiveResultgetLuckyColor(
axis2.adb.async.xsd.GetLuckyColorResponse param41) {
luckyColor = param41.get_return();
}
};
if(twoWayListnerEnabled){
//engage the module, and setUseSeparateListner to true.
stub._getServiceClient().engageModule(new QName("addressing"));
stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(1000);
stub._getServiceClient().getOptions().setUseSeparateListener(true);
}
//call the service
getLuckyNumberFromService(stub,myNewServiceCallBackHandle,new Date(1987,12,21));
// Since async call, poll the luckyNumber to see if a value is populated. This is just an example, in practice, should not poll this way. Here it is required cas' the number is an input to the next service all.
do{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if(luckyNumber != 100){
break;
}
}
}while(luckyNumber == 100);
//call the next service
getLuckyColorFromService(stub,myNewServiceCallBackHandle,luckyNumber);
// again poll to see if lucky color has been populated.
do{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
if(luckyColor != null){
break;
}
}
}while(luckyColor == null);
//print them
System.out.println("Lucky Number: " + luckyNumber);
System.out.println("Lucky Color: " + luckyColor);

} catch (AxisFault e) {
e.printStackTrace();
} catch (RemoteException re){
re.printStackTrace();
}finally{
//do the clean up.
try {
if(twoWayListnerEnabled){
stub._getServiceClient().disengageModule(new QName("addressing"));
stub._getServiceClient().cleanup();
}
stub.cleanup();
if(twoWayListnerEnabled){
System.exit(0);
}
} catch (AxisFault e) {
//ignore this
}
}

}
private static void getLuckyColorFromService(MyNewServiceStub stub, MyNewServiceCallbackHandler myNewServiceCallBackHandle, int luckyNumber) throws RemoteException {
//create request payload
GetLuckyColor req = new GetLuckyColor();
//set the parameter
req.setParam0(luckyNumber);
// do an async call
stub.startgetLuckyColor(req, myNewServiceCallBackHandle);
}
private static void getLuckyNumberFromService(MyNewServiceStub stub, MyNewServiceCallbackHandler callBackForGetLuckyNumber, Date date) throws RemoteException {
//create request payload
GetLuckyNumber req = new GetLuckyNumber();

Calendar dOb = Calendar.getInstance();
dOb.setTime(date);
//set the parameter
req.setParam0(dOb);
//do an async call
stub.startgetLuckyNumber(req, callBackForGetLuckyNumber);

}

}



Step 9: Execute the client.

java MyNewServiceClient

output :
Lucky Number: 2
Lucky Color: Yellow


Hope, this tutorial was use full enough. Here, ADB databinding was used and no security implemented. Next will try to get an Webservice up with security implementation.
Adios!!

1 comment:

  1. Thanks for the step by step tutorial of web service with axis2 and tomcat in java part2 and this will help me to understand all thing. Keep up the good work.

    ReplyDelete