Annotations

JEE Web Service with Annotations: SOAP Based

The evolution of WebServices technology, specially JAX-WS, has eased the implementation of JEE components as Services. The focus of the blog is to show how you can implement EJB’s as services. Many would argue about leaving services as POJO’s, but there are drawbacks to exposing your services as POJO’s. If you are running in a JEE Application Server, it’s to your benefit to leverage the container as much as possible, especially for transaction handling and security.

For those of you who have stayed away from EJB, don’t worry. Developing a EJB 3.0 service is the same as you would develop a POJO based service; except for the following Annotations (JSR-181):

  1. @Stateless – tells the container that the class is a Stateless Session Bean
  2. @WebService – tells the container that the class is also a WebService.

Let’s look at a simple “Greet Me Service” in order to illustrate. The GreetMeService implements a Service Endpoint Interface.  In order to create the service, first define the Interface.

The interface defines the methods that must be implemented by the class. From a Web Service perspective, it defines the web service operations. Let’s look at the Service Endpoint Interface.

import java.rmi.Remote;

import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import java.rmi.RemoteException;

@WebService(name = “GreetMeEJBBeanService”)
@SOAPBinding(style = Style.DOCUMENT)
public interface GreetMeEJBBeanService extends Remote {
@WebMethod(operationName = “greetMe”)
@WebResult(targetNamespace=”http://com.santisij.greetme/types”,
name=”greeting”)
public String greetMe(@WebParam(targetNamespace = “http://com.santisij.greetme/input”,name = “name”,mode = Mode.IN)String name) throws RemoteException;

//The RemoteException must be thrown by the EJB
}

I am assuming that you are familiar with the different types of WebService Bindings- Document or RPC and whether it’s Literal or Encoded. The JAX-WS specification defines the web service binding style as Document by default.   It does not hurt to define the Binding as DOCUMENT, but you can easily leave out the @SOAPBinding annotation.

The key difference between Document and RPC is that the Document style has full XML documents, while RPC indicates that the underlying SOAP message contains parameters in the request and response values in the response message.

Now that we defined our Interface let’s implement the method/operations:

import javax.ejb.Remote;
import javax.ejb.Stateless;

import javax.jws.WebService;

@Stateless(name = “GreetMeEJB”, mappedName = “GreetMe-GreetMeEJB”)
@Remote(GreetMeEJBBeanService.class)
@WebService(portName = “GreetMeEJBBeanServicePort”, endpointInterface = “com.santisij.greetme.GreetMeEJBBeanService”)
public class GreetMeEJBBean{

public String greetMe(String name){
StringBuilder sb = new StringBuilder();
sb.append(“This is the Greeting Service….”);
sb.append(“Hello “);
sb.append(name);

return sb.toString();
}
}

The advantage of using the JEE spec is that this EJB is both a web service and an EJB.  If you need to invoke this service from the same JVM, you don’t have to go through the SOAP stack in order to get your response.
Here’s a simple client that looks up the EJB from the JNDI tree and invokes the GreetMeService.
public class GreetMeEJBClient {

public static void main(String [] args) {
String name = “Juan”;
String result = null;
try {
final Context context = getInitialContext();
GreetMeEJBBeanService greetMeEJB = (GreetMeEJBBeanService)context.lookup(“GreetMe-GreetMeEJB#com.santisij.greetme.GreetMeEJBBeanService”);
System.out.println(“I got the Context: executing method”);
result = greetMeEJB.greetMe(name);
System.out.println(“result from RMI: “+result);
} catch (Exception ex) {
ex.printStackTrace();
}
}

private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// WebLogic Server 10.x connection details
env.put(Context.INITIAL_CONTEXT_FACTORY, “weblogic.jndi.WLInitialContextFactory” );
env.put(Context.PROVIDER_URL, “t3://localhost:7001″);
return new InitialContext( env );
}
}

I used JDeveloper to build and deploy the service to WebLogic, but you could easily build and deploy the service to Glassfish Server with Eclipse.  In addition, make sure that you generate/view the WSDL file. If your service location has a the value ” REPLACE …”, you will have to replace the service location with the URL of your service.

WebLogic – http://myhost:7001/GreetMeEJBBean/GreetMeEJBBeanService
Take a look at the WSDL: http://localhost:7001/GreetMeEJBBean/GreetMeEJBBeanService?wsdl

I  use soapUI – a great tool to test your services – this is the URL that you want to point to.  The following links provide great reference material …

http://java.sun.com/webservices/docs/1.6/tutorial/doc/

There are several books that dive into the JAX-WS and EJB 3.x specifications (Just search for your favorite publisher)

Advertisements