Java Web Services with simple types


In the previous post we created a simple Web Service in Java. Now we’ll build on it, by providing more methods with standard argument and return types.

  • String
  • Number
  • Boolean
  • Array
  • Variable arguments

Let’s recall the Web Service with a single available operation.

@WebService
@SOAPBinding(style=Style.RPC)
public interface SimpleService {
   @WebMethod
   String sayHello();
}

Strings

Apart from sayHello, we would like a new operation that says hello to a given name.

@WebService
@SOAPBinding(style=Style.RPC)
public interface SimpleService {
   @WebMethod
   String sayHello();

   @WebMethod
   String sayHelloTo(String name);
}

Let’s implement it.

@WebService(endpointInterface="simple.SimpleService")
public class SimpleServiceImpl implements SimpleService {
   public String sayHello() {
      return "Hello from Web Services!";
   }
   public String sayHelloTo(String name) {
      return String.format("Hello %s!", name);
   }
}

If we publish the Web Service and access its WSDL, we’ll notice some new lines.

...
<message name="sayHelloTo">
   <part name="arg0" type="xsd:string"/>
</message>
...

Booleans and Numbers

Here is another operation that determines whether an integer is even.

public interface SimpleService {
   ...
   @WebMethod
   boolean isEven(int input);
   ...
}

Its implementation is straight-forward.

public class SimpleServiceImpl implements SimpleService {
   ...
   public boolean isEven(int input) {
      return input % 2 == 0;
   }
   ...
}

When the service is published, notice that the following lines are added to the WSDL.

...
<message name="isEven">
   <part name="arg0" type="xsd:int"/>
</message>
<message name="isEvenResponse">
   <part name="return" type="xsd:boolean"/>
</message>
...

Arrays and var-args

The last operation of our Web Service is to reverse an array.

public interface SimpleService {
   ...
   @WebMethod
   String[] reverse(String... input);
   ...
}

The equivalent entries in the WSDL contract are the following.

...
<message name="reverse">
   <part name="arg0" type="ns1:stringArray"/>
</message>
<message name="reverseResponse">
<part name="return" type="ns2:stringArray"/>
</message>
...

The complete code follows.

The Web Service:

@WebService
@SOAPBinding(style=Style.RPC)
public interface SimpleService {
   @WebMethod
   String sayHello();

   @WebMethod
   String sayHelloTo(String name);

   @WebMethod
   boolean isEven(int input);

   @WebMethod
   String[] reverse(String... input);
}

API: WebService, WebMethod, SOAPBinding, SOAPBinding.Style

@WebService(endpointInterface="simple.SimpleService")
public class SimpleServiceImpl implements SimpleService {
   public String sayHello() {
      return "Hello from Web Services!";
   }
   public String sayHelloTo(String name) {
      return String.format("Hello %s!", name);
   }
   public boolean isEven(int input) {
      return input % 2 == 0;
   }
   public String[] reverse(String... input) {
      if (input == null) return null;
      final String[] result = new String[input.length];
      for (int index = 0; index < input.length; index++) {
         result[index] = input[input.length - 1 - index];
      }
      return result;
   }
}

The publisher:

public class SimpleServicePublisher {
   /**
    * Publishes the Web Service locally.
    */
   public static void main(String[] args) {
      Endpoint.publish("http://127.0.0.1:9000/simple", new SimpleServiceImpl());
   }
}

API: Endpoint

The client:

public class SimpleServiceClient {
   public static void main(String[] args) throws Exception {
      // Connect to the Web Service
      final URL url = new URL("http://127.0.0.1:9000/simple");
      final QName name = new QName("http://simple/", "SimpleServiceImplService");
      final Service service = Service.create(url, name);
      final SimpleService simple = service.getPort(SimpleService.class);
      // Call some operations
      System.out.println(simple.sayHello());
      System.out.println(simple.sayHelloTo("Nikos"));
      int number = 32;
      System.out.format("The number %d is %seven.\n", number, simple.isEven(number) ? "" : "not ");
      String[] result = simple.reverse("Nikos", "Sofia", "Eleni");
      for (String element : result) {
         System.out.println(element);
      }
   }
}

Summary

The Web Services remain really simple, when the methods use standard Java types.

Java type Schema type
String string
Integer int
Boolean boolean
String[] stringArray
String… stringArray

In the next post, we’ll use more complex types; this will require just a single extra configuration step.

Thanks.

5 Responses to Java Web Services with simple types

  1. this is a very very good article

  2. bill perlman says:

    Again, this is very informative and easy to implement. However, I’m not sure if you ever got around to doing that “next post”, in which you use more complex types.

    That post would be REALLY informative and useful.

    Any chance of that happening?

    Thanks again. This stuff is great.

  3. bill perlman says:

    Hi.

    I’ve noticed that when the client executes

    service.getPort(SimpleService.class);

    the server will log the following exception, but still return the proper response to the client when running locally:

    Jul 26, 2011 11:20:56 AM com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit handle
    SEVERE: Request doesnt have a Content-Type
    com.sun.xml.internal.ws.server.UnsupportedMediaException: Request doesnt have a Content-Type

    Is there some other specification that one needs to satisfy the server? I’ve also noticed that the first argument of the QName constructor seems to have to be the package backwards. For example, my package is com.billybyte.simplewebservice. The first argument in the QName constructor that works is “http://simplewebservice.billybyte.com”

    Does this make sense?

    Thanks much for your posts.

  4. Is there a way I can return a custom class?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: