http://www.developer.com/

Back to article

Working with Axis2: Making a Java Class into a Service


February 7, 2008

What Are Code First and Contract First?

In the case of the contract-first approach, you start with a Web services contact called WSDL (Web Service Description Language) and then write server-side and client-side code based on the contact. To start with, the contact-first approach having an understanding about WSDL is very useful; however, even though you do not have enough knowledge on WSDL, there are many tools available for you to create a skeleton on the server side and a proxy of client-side code. If you take Axis2 as an example, you have a number of ways in which you can create a service or a client for a given WSDL document, command-line tools, and IDE Plugins can be considered as some examples of them.

It is true that not everyone will from WSDL to write services and clients; most of the time, developers like to convert a bit of code they have as a Web service. That is called the code-first approach, where you start with code rather than a contract. This approach is the most commonly used approach in the industry. With the code-first approach, you can write a Web service without knowing anything about WSDL, SOAP, and other related terminologies. And, most importantly, if you have a very old system and if you want to expose that as a Web service, the code-first approach will be a good candidate as well. In the meantime, the code-first approach can be used in a situation where a prototype is being developed. Although you start with code, you can get the WSDL document for your service because most Web service frameworks do support WSDL auto generation.

What Is the Better Approach?

It is very hard to determine which one is better because each has its own advantages and disadvantages. So, the best thing is to choose the one that matches your requirement. It is not mandatory to start with code first or contract first just because someone else is using that.

However, the article will discuss how to write a POJO application and the problems, limitations, and so forth.

Creating a Web Service from a Java Class

POJO stand for Plain Old Java Objects, so when it come to Web services world, what you do is we write a Java class and expose that as a Web service. And, of course, in writing such an application there are some limitation in Axis2. These will be fixed in an upcoming release, and I'll discuss that later in the article.

Once you have written the application, there are a number of ways that you can expose it as a Web service:

  • POJO deployment (drop the .class file or .jar file into the pojo directory in the repository)
  • As a service archive, where you bundle compiled class(es) along with the configuration file
  • Using a programmetric way of deploying services.
Note: All the above methods support JSR 181 annotations, so you can write your application using annotations and expect Axis2 to do the right thing.

The Axis2 POJO has the following features. These features will be discussed in detail:

  • Support for primitive types (int, boolean, long, String, and so on)
  • Support for method excludes
  • Support for any kind of "Java Beans"
  • Support for Object Arrays
  • Binary support using byte[] and DataHandlers
  • Support of Axiom
  • Serialization support for List
  • Namespaces handling
  • Inheritances support
  • Support for Bean property excludes
  • Method overloading support using annotations

What Are the Java Types Axis2 Support?

You can write a simple applications or a complex application using primitive types. However, when writing a complex application, it is much cleaner to use Java beans, but that is not compulsory. So, a very simple POJO with primitive types is shown below.

package sample;

public class SampleService {

   public String echo(String value) {
      return value;
   }

   public int add(int a, int b) {
      return a + b;
   }

   public void update(int c) {

   }
}

You easily can make this into a Web service by using one of the methods that I discussed earlier. Once you do so, all the public methods will be exposed as Web operations. And, once we use a POJO service, it is recommended that you use RPCMessageReceiver; one reason for that is that it has been tested enough to handle any kind of complex scenario.

If you are using archived-based deployment, the corresponding services.xml would be look like this:

<service name="SampleService">
   <description>This is my Sample Service</description>
   <messageReceivers>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
         class="org.apache.axis2.rpc.receivers.
                RPCInOnlyMessageReceiver"/>
      <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
         class="org.apache.axis2.rpc.receivers.
                RPCMessageReceiver"/>
   </messageReceivers>
   <parameter name="ServiceClass">sample.SampleService</parameter>
</service>

As you can see, you have not listed any of the operations that you need to expose; it happens automatically and publishes all the public operations. To understand what's happening, create a service archive file and deploy and see. Once you click on ?wsdl for that service, you can can see the auto-generated file with three methods. Once you deploy the service, you can invoke the service as you want: You either can generate a client or you can invoke the service in REST manner.

For the purposes of easy deployment, you can use the one-line deployment mechanisms and see how it looks.

public static void main(String[] args) throws Exception{
   new AxisServer().deployService(SampleService.class.getName());
}

Now, go to http://localhost:6060/.

Then, once you click the SampleService link, you can clearly see three methods.

How to Exclude Some of a POJO's Methods

As you know by default, Axis2 exposes all the public methods; howeverv there are instances where you need to exclude or not need to expose all of them. So now, let's look at how to control the behavior. And, say you need to expose only the "echo" and "add" methods and you do not want to expose the "update" method, you can do that by adding the following entry to services.xml. It should be noted here that you cannot exclude operations when you use a one-line deployment mechanism; however, even when you deploy a service programatically, you can exclude operations.

<excludeOperations>
   <operation>update</operation>
</excludeOperations>

Add the above entry to services.xml and redeploy the service. Then, when you click on ?wsdl, you would see only two methods, and you will not see the "update" operation in the WSDL.

What Type of Bean Can You Write?

As discussed above, Axis2 POJO has support for any kind of JavaBeans, but you need to make sure you use the JavaBeans standard when you use JavaBeans as an example:

  • Need to have getter and setter methods.
  • Need to have default constructor.
  • Cannot have properties that start with upper-case letters. As an example, it is not allowed to have a property such as "private String Age" in a bean but you can have "private String age."
  • A bean's properties can be some other bean, primitive types, any kind of object arrays, DataHandlers, and the like.

Now, write a simple JavaBean and try to use that inside the service class. Your bean look like the following.

public class Address {
   private String street;
   private String number;

   public String getStreet() {
      return street;
   }

   public void setStreet(String street) {
      this.street = street;
   }

   public String getNumber() {
      return number;
   }

   public void setNumber(String number) {
      this.number = number;
   }
}

Now, you can change your service implementation class and use Address bean as follows;

package sample;

public class SampleService {

   public String echo(String value) {
      return value;
   }

   public int add(int a, int b) {
      return a + b;
   }

   public void update(int c) {

   }
   public Address get(String name) {
      Address address = new Address();
      address.setNumber("Number");
      address.setStreet("Streat");
      return address;
   }
}

Compile the code again, create another service archive file, and redeploy the service. Then, look at the WSDL file carefully; you will see new operations as well as a new schema element for Address in the types section.

Does It Have Support for Object Arrays?

It is possible to write POJO applications with object arrays, and you can have an object array as a field of a bean and as a method in a Service class as shown below. It should be noted here that an object array can be any kind.

public Address[] getAddress(String [] names){

}

Or it is possible to have something like this.

public Address[] getAddress(String [] names ,
   Address[] address ,
   int [] values){
}

How to Write a POJO with Binary Support

You can write your POJO to accept or return Binary data, and there you can use either byte[] or DataHandler. Irrespective of what you use depending on an Axis2 configuration, Axis2 will serialize and de-serialize into Base64 or MTOM. To have binary support, you can write your Service class as shown below.

Sending binary data

public DataHandler getImage(String fileName) {
   File file = new File(fileName);
   DataHandler dh = new DataHandler(new FileDataSource(file));
   return dh;
}

public byte[] getImage(String fileName) {
   //Logic of creating byte array
   return byteArray;
}

Receiving binary data

public void upload(DataHandler dh) {
   //Logic of saving the file
}

or

public void upload(byte [] byteArray) {
   //Logic of saving the file
}

It is also valid to have binary fields in JavaBeans as well. Axis2 will handle them correctly.

How to Access XML Inside a Service Class

As you know, Axis2 is the native XML support in Axis2, so even POJO Axis2 does support AXIOM. You can write POJO with AXIOM either to send or receive, as well as to write with AXIOM object arrays.

public OMElement echo(OMElement element) {
   return element;
}

Or

public OMElement echo(OMElement [] element) {
   return element;
}

Do You Have Support for Inheritance?

Axis2 POJO supports inheritance, so you can write your service class to extend some other class and publish parent(s) method(s) automatically. In this case, all the public methods of both the parent and child will be published, and of course you can exclude the methods that you do not need to expose, as I discussed earlier.

Say you have a class like this:

package sample;

public class ParentService {
   public String getName() {
      return null;
   }
}

And, say your service class is as follows:

package sample;

public class SampleService extends ParentService {
   public int add(int a, int b) {
      return a + b;
   }
}

Once you deploy the service again, you can see both the parent operation as well as the child operation.

Axis2 has inheritance support for Bean as well, so as an example your Address bean can extend from some other bean. Then, Axis2 will automatically generate WSDL as well. Say you have a bean like this:

package sample;

public class AddressParent {
   private String city;
   private int zipCode;
   public String getCity() {
      return city;
   }
   public void setCity(String city) {
      this.city = city;
   }
   public int getZipCode() {
      return zipCode;
   }

   public void setZipCode(int zipCode) {
      this.zipCode = zipCode;
   }
}

Then you can have your Address bean as follows;

package sample;

public class Address extends AddressParent {
   private String street;
   private String number;

   [Rest of the code goes here]
}

JSR 181 or Annotations Support

Axis2 POJO supports annotations, so you can use any kind of available options in JSR 181. The following is a simple example of a service written using annotations.

package sample;

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService (name = "MyService" ,serviceName="MyService")
public class SampleService extends ParentService {
   @WebMethod (action = "action:add")
   public int add(int a, int b) {
      return a + b;
   }
}

Conclusion

You have learned about Axis2, creating a Web Service from a Java class, and POJO. Now, it's time to open an IDE and start writing an application of your own.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date