Expose EJB as a Web Service
With this example we are going to demonstrate how to expose an EJB as a web service. Enterprise beans are Java EE components that implement Enterprise JavaBeans (EJB) technology. Enterprise beans run in the EJB container, a runtime environment within the Application Server (see Container Types). Although transparent to the application developer, the EJB container provides system-level services such as transactions and security to its enterprise beans. These services enable you to quickly build and deploy enterprise beans, which form the core of transactional Java EE applications. A client can access a session bean only through the methods defined in the bean’s business interface. The business interface defines the client’s view of a bean. All other aspects of the bean (method implementations and deployment settings) are hidden from the client. When you design a Java EE application, one of the first decisions you make is the type of client access allowed by the enterprise beans: remote, local, or web service. Here, we shall show you how to expose an EJB as a web service. The steps are described below:
Create the EJB implementation class.
The CalculatorService
is an EJB implementation class that is a stateless session bean that implements four methods. It is annotated with the javax.jws.WebService annotation and the javax.ejb.Stateless
annotation. The javax.jws.soap.SOAPBinding annotation is also used to specify the mapping of the Web Service onto the SOAP message protocol. The class must have a default public constructor. Business methods that are exposed to web service clients must be annotated with javax.jws.WebMethod. The javax.jws.WebParam annotation is used to customize the mapping of an individual parameter to a Web Service message part and XML element.
package com.javacodegeeks.snippets.enterprise; import javax.ejb.Stateless; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; @Stateless @WebService(serviceName = "CalculatorService", targetNamespace = "urn:CalculatorService") @SOAPBinding(style = SOAPBinding.Style.DOCUMENT) public class CalculatorService implements CalculatorServiceLocal, CalculatorServiceRemote { public CalculatorService() { } @Override @WebMethod @WebResult(name = "additionResult") public long add(@WebParam(name = "firstAddend")long i, @WebParam(name = "secondAddend")long j) { return (i + j); } @Override public double divide(long i, long j) { return ((double)i / j); } @Override public long multiply(long i, long j) { return (i * j); } @Override public long subtract(long i, long j) { return (i - j); } }
The EJB local interface (suitable for in VM communication)
The local interface defines the bean’s business and life cycle methods. To build an enterprise bean that allows only local access, you must annotate the business interface of the enterprise bean as a @Local
interface.
package com.javacodegeeks.snippets.enterprise; import javax.ejb.Local; @Local public interface CalculatorServiceLocal { public long add(long i, long j); public long subtract(long i, long j); public long multiply(long i, long j); public double divide(long i, long j); }
The EJB remote interface (suitable for intra VM communication)
A remote client of an enterprise bean can run on a different machine and a different Java virtual machine (JVM) than the enterprise bean it accesses. (It is not required to run on a different JVM.) To create an enterprise bean that allows remote access, you must decorate the business interface of the enterprise bean with the @Remote
annotation:
package com.javacodegeeks.snippets.enterprise; import javax.ejb.Remote; @Remote public interface CalculatorServiceRemote { public long add(long i, long j); public long subtract(long i, long j); public long multiply(long i, long j); public double divide(long i, long j); }
The application.xml file describing the modules in the .ear archive
<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" version="1.4"> <display-name>Calculator Application</display-name> <module> <ejb>calculatorServiceEJB3.jar</ejb> </module> </application>
The structure of the .ear archive
calculatorApp.ear | |_calculatorServiceEJB3.jar | |_com | | |_javacodegeeks | | |_snippets | | |_enterprise | | |_CalculatorService.class | | |_CalculatorServiceLocal.class | | |_CalculatorServiceRemote.class | |_META-INF | |_META-INF |_application.xml
Run the application using a client
In CalculatorServiceClient
we connect to JBoss naming service running on local host and on default port 1099. We use the Context to set the configuration for the JBoss server, such as Context.INITIAL_CONTEXT_FACTORY
, Context.PROVIDER_URL
and Context.URL_PKG_PREFIXES
. We get the bean using the lookup(Name name)
method of Context to invoke its methods.
package com.javacodegeeks.snippets.enterprise; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; public class CalculatorServiceClient { public static void main(String[] a) throws Exception { /* * Connecting to JBoss naming service running on local host and on * default port 1099 the environment that should be created is like the * one shown below : */ Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); env.put(Context.PROVIDER_URL, "jnp://localhost:1099"); env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); Context ctx = new InitialContext(env); CalculatorServiceRemote calculatorService = (CalculatorServiceRemote) ctx.lookup("calculatorApp/CalculatorService/remote"); long i = 10; long j = 3; System.out.println(i+"+"+j+"="+calculatorService.add(i, j)); System.out.println(i+"-"+j+"="+calculatorService.subtract(i, j)); System.out.println(i+"*"+j+"="+calculatorService.multiply(i, j)); System.out.println(i+"/"+j+"="+calculatorService.divide(i, j)); } }
Output:
10+3=13
10-3=7
10*3=30
10/3=3.3333333333333335
This was an example of how to expose an EJB as a web service in Java.