Monday, February 10, 2014

Deploying Java Class as a Web Service in Axis2




We assume that we want to publish the following HolaWorld class as a Web serviceHelloService.

public class HolaWorld {
   public String sayHello(String name) {
      return "Hello " + name;
   }
}
Our HelloService will provide one operation, sayHello, that takes name as the input and returns the "Hello ..." string as the output.
There are two main steps involved in publishing a Web service from your Java code:
  1. Write a service description file (services.xml).
  2. Create a service archive file.

Writing the services.xml file

Once Axis2 receives a request to a Web service, it has to figure out which Java class can handle the Web service request. This "mapping" between a Web service and a Java class is described inservices.xml file. Writing the services.xml file for our HelloService is quite simple. Essentially, the file should contain the following information:
  • Fully qualified class name that handles the published Web service
  • Message receiver used by the Web service
For now, do not worry about the message receiver part, and look at the following services.xml file for our HelloService:

   This is the HolaWorld service
   HolaWorld
   
      
   

The second line in the above file provides a text description of the Web service and may be omitted.
Service implementation class: The third line indicates that this Web service is handled by the HolaWorld class. Since our HolaWorld class does not belong to any package namespace, the class name is specified simply as HolaWorld here, but in general the class name should be the fully qualified class name (like edu.ucla.cs.cs144.DemoService).
Message receiver: The fourth through sixth lines specify that the operation sayHello of this service should use the Axis2 Java class org.apache.axis2.rpc.receivers.RPCMessageReceiver as its message receiver class. A message receiver is the Axis2 Java class that processes the inputs to and outputs from the Web service, and pass them to/from our Java class. Axis2 provides a set of built-in message receiver classes depending on the message exchange pattern (MEP) of the Web service (e.g., input only? output only? input and output?) and the input/output encoding scheme used by the service; in our example, we are using org.apache.axis2.rpc.receivers.RPCMessageReceiver which is a common message receiver used for publishing an existing Java class.

Different way of specifying message receivers

In the above services.html file, we specified the Axis2 message receiver class at the operation level, associating a message receiver for every operation of our service. Axis2 also allows us to specify the message receivers at the service level, so that we can specify the message receiver once for the entire service as follows:

   This is the HolaWorld service
   HolaWorld
   
       
       
   
   

Note that Axis2 has built-in support for all the eight MEPs (Message Exchange Pattern) defined in WSDL 2.0. In the services.xml file, we can specify the MEP and the corresponding message receiver, and then, Axis2 automatically picks up and uses the appropriate message receiver for each service operation. In the above file, we specify RPCInOnlyMessageReceiver as the message receiver for all input-only operations and RPCMessageReceiver as the message receiver for all input-and-output operations.
In the second last line, the operation element for sayHello shows this operation will be available by the service. This line is optional; by default, Axis2 exposes all public methods in the service implementation class whether we specify them in services.xml or not. For all public methods in the implemenation class, Axis2 calculates the MEP of the operation by checking the return value of the Java method. If the method is void, the MEP will be in-only; else, it will be in-out, depending on which the appropriate MEP message receiver will be set.

Creating a service archive file

Once we create our service description file services.xml, the final step before deployment is to create a service archive file by putting together (1) our service implementation class, (2) all libraries that it depends on, and (3) the services.xml file. These files should be placed in the appropriate directories within the archive file. For example, the directory structure of our HelloService archive file should be as follows:
HelloService.aar
 +- META-INF
 |    +- services.xml
 |
 +- HolaWorld.class
First note that the name of the archive file is HelloService.aar, which is the same as the name of the Web service that the archive file provides, followed by the extension .aar. If the name of our service were MyService, the file name would have been MyService.aar.
The services.xml file that we created in the previous step should be placed in the META-INF subdirectory of the archive file.
Depending on the namespace the class belongs to, the service impelementation class should be placed in the appropriate subdirectory of the archive file. In our example, the HolaWorld class does not belong to any package namespace, so it is simply placed at the root directory. All other classes that the implementation class depends on should also be placed at the appropriate directory.
Finally, if the implementation class uses any external Java libraries, they should be placed in the lib subdirectory of the archive file.
Here is a bit more complex example of the structure of an archive file:
AnotherService.aar
 +- META-INF
 |   +- services.xml
 |
 +- lib
 |   +- xxx.jar
 |
 +- edu
     +- ucla
         +- cs
            +- cs144
                +- AnotherClass.class
Here, the archive file handles the Web service named AnotherService and the service is implemented by the Java class edu.ucla.cs.cs144.AnotherClass. Assuming the class depends on the xxx.jarlibrary, we placed it in the lib subdirectory of the archive file.
An archive file can be created using the jar command in the stadard Java Development Kit. For example, to create the above HolaWorld.aar file, first (1) create a temporary directory, (2) create the appropriate subdirectories within the temporary directory (like META-INFlib, etc.), (3) place your class and library files at the appropriate subdirectories. Then inside the temporary directory, execute the following command:
jar cvf HelloService.aar *
The above command will create the HelloService.aar file and add all files below the current directory to the file. Once the archive file is created, deploying the service is just a matter of dropping the service archive file into the services directory in our Axis2 server repository. We can also easily upload the service archive file by using axis2 Web administration console.


No comments:

Post a Comment