Monday, April 15, 2013

Web Service with JAX-WS 2.2.4

(I have a post that supersedes this one here)

In this message I will create a very simple web service and respective client using the JAX-WS technology. I will deploy the web service on JBoss AS 7.1.1 and use Eclipse. NetBeans instead of Eclipse and other application server might do the trick equally well. First, let us start JBoss. Just cd to the bin directory and run it as follows:

./standalone.sh (standalone.bat if you are using Windows)

We must create a new dynamic web project:


Give it a name. Let us call it WSAgenda (you should not get any warning over the name repetition) and press the Finish button.



I will first create the PhoneBookServer class (File-> New -> and look for class).


Notice that we selected the package ws:
package ws;

import java.util.Hashtable;
import java.util.Map;

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

@WebService
public class PhoneBookServer {
static private Map<String, String> phonebook = new Hashtable<>();
public PhoneBookServer() {
}
@WebMethod
public String getNumero(String nome) throws NoSuchPersonException {
if (!phonebook.containsKey(nome))
throw new NoSuchPersonException();
return phonebook.get(nome);
}
@WebMethod
public void setNumero(String nome, String numero) {
phonebook.put(nome, numero);
}
}



We will also create an exception class, for the case where the person looked for is not registered:

package ws;

public class NoSuchPersonException extends Exception {

private static final long serialVersionUID = 1L;

}

Note that we use a static hash table to keep the phone, because multiple objects of type PhoneBookServer may coexist for performance reasons. It would not make sense to have multiple server objects seeing different phone books and giving different replies to clients. One should also notice that the server has no numbers and that the client needs to add them.

To deploy the server, select the name of the project (WSPhoneBook on the left side) and do as follows with the right button of the mouse:


Then we set the name of the war file:


If things went well you should see the following trace in the JBoss window:


You should check the address in the 6th line, add "?wsdl" to it and put it in the browser:

http://localhost:8080/PhoneBook/PhoneBookServer?wsdl

You should see this:


The server is ready, let us write the client.

We first need to have stubs, to invoke the web services. But before we can do that we need to create a regular Java project. Let us call it WSClient. Now, find the directory where Eclipse writes the source files of this project. In my case it is long-path-to-workspace/WSClient/src/. Do

cd long-path-to-workspace/WSClient/src/

with the necessary differences in the Windows operating system. We must run the wsimport command with an option to keep java files and with a package that might be "artifact". Note that this command may not exist in your path. Two typical problems: 1) you installed a JRE instead of a JDK; 2) the bin directory of the JDK is not in your path. You may overcome problem 2 by indicating the complete path to the wsimport command.


We will now go to Eclipse to create Client and Client2 java classes, to write and read numbers to/from the phone book. Press F5 or use the right button to refresh. You should see your own classes and the stubs, as well.



Client should be like this:
import artifact.PhoneBookServer;
import artifact.PhoneBookServerService;


public class Client {

/**
* @param args
*/
public static void main(String[] args) {
PhoneBookServerService as = new PhoneBookServerService();
PhoneBookServer asp = as.getPhoneBookServerPort();
asp.setNumero("Paula", "234523452345");
asp.setNumero("Heloisa", "111111111111");
}

}


Run it. Client2 should be like this:

import artifact.NoSuchPersonException_Exception;
import artifact.PhoneBookServer;
import artifact.PhoneBookServerService;


public class Client2 {

/**
* @param args
* @throws NoSuchPersonException_Exception 
*/
public static void main(String[] args) throws NoSuchPersonException_Exception {
PhoneBookServerService as = new PhoneBookServerService();
PhoneBookServer asp = as.getPhoneBookServerPort();
System.out.println("Numero da Paula " + asp.getNumero("Paula"));
System.out.println("Numero da Heloisa " + asp.getNumero("Heloisa"));
System.out.println("Numero da Carla " + asp.getNumero("Carla"));
}

}



What a pity! The server does not really have the number of Carla, so we will get an exception when we try this program. So, these red letters are a god sign in our case. Everything went as expected: