How to Combine REST Services with EJB 3.1
REST services (JAX-RS) technology became a part of the Java EE 6 platform, which is great news for REST developers.
In a very simple web application, I'll demonstrate how REST services can be combined with other Java EE technologies, specifically EJB 3.1.
- First of all, we need to specify a REST resources path. Previously, in Java EE 5, the only way to do this was to register a specific servlet adaptor in web.xml:
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>JAX-RS API (from version 1.1.4) introduced a specific annotation ( @javax.ws.rs.ApplicationPath ), that provides an alternative to web.xml configuration:
package org.netbeans.rest.application.config;
/**
* This class is generated by the Netbeans IDE,
* and registers all REST root resources created in the project.
* Please, DO NOT EDIT this class !
*/
@javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends javax.ws.rs.core.Application {
}Note: The ApplicationConfig class extends javax.ws.rs.core.Application. There are 2 methods that may be implemented from the super class:
public Set<Class<?>> getClasses();
public Set<Object> getSingletons();These methods specify a set of root resources and providers accessible from this application path. This way users may specify several groups of REST resources (not necessarily disjunctive), in a single web application.
NetBeans IDE 6.8 provides a default implementation of javax.ws.rs.core.Application containing all REST root resources and providers specified in a web application. Users can specify a URL string (e.g. "resources") that will be used to access these resources. Users can also implement a custom subclass(es) of javax.ws.rs.core.Application.
- Secondly, we create a Singleton EJB class that will be used to persist the state of REST resource (created in next stem). This is the class:
package name;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
@Singleton
public class NameBean {
private String name;
|
@PostConstruct
private void init() {
name="Robin Hood";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}Note: The singleton EJB is a new feature in Java EE 6. The container is guaranteed to maintain a single shared instance of an EJB 3.1 Singleton. This means that Singletons can cache state across the application tier. The @PostContruct annotation is used to annotate a method performing any initialization stuff, and it's called by container just after a single instance is created.
- The last step is to create a simple REST root resource, using the singleton NameBean to persist its state:
package name;
import javax.ejb.*;
import javax.ws.rs.*;
@Path("name")
@Stateless
public class NameService {
@EJB
private NameBean nameBean;
@GET
@Produces("text/html")
public String getHtml() {
return "<h2>Hello "+nameBean.getName()+"</h2>";
}
@PUT
@Consumes("text/plain")
public void put(String content) {
nameBean.setName(content);
}
}Note: Dependency Injection is used to inject the NameBean into the resource. The EJB 3.0 @Stateless annotation is a convenient way to enable dependency injection. If this annotation is missing, the nameBean field won't be initialized by the container. The other annotations come from the JAX-RS (JSR311) specification.
NetBeans IDE provides a RESTful, JavaScript based, tester capability that can be used to test HTTP GET, POST, PUT or DELETE methods. This is an example of invoking HTTP PUT on REST resource located at "http://localhost:8080/RestApplication/resources/name":
Finally, the HTTP GET method can also be tested easily by typing resource URI in the browser:
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Reza Rahman replied on Tue, 2009/12/01 - 11:33am
Milan,
Great coverage of EJB 3.1 and JAX-RS!
Cheers,
Reza
Chetan Shinde replied on Wed, 2009/12/02 - 5:46am
Hello Milan,
That was a good introduction to REST Web Service and NetBeans.
Could you also tell how you can implement the Client for this example?
Is there some specific API that we need to use?
Regards,
Chetan
Rafael Naufal replied on Wed, 2009/12/02 - 10:51am
Milan Kuchtiak replied on Wed, 2009/12/02 - 12:20pm
in response to:
Chetan Shinde
> Is there some specific API that we need to use?
In java code, you can use Jersey Client API.
See: Consuming REST
Milan Kuchtiak replied on Wed, 2009/12/02 - 12:28pm
in response to:
Rafael Naufal
> I think is the @EJB annotation which enables bean dependency injection by the container instead of the @Stateless annotation.
Sorry, I didn't express that properly. @EJB annotation, of course, provides an injection, but the class should be manageable by the container (e.g. EJB). If the class annotation @Stateless were missing it wouldn't work.
Stephan Kliche replied on Wed, 2010/02/10 - 11:48am
Hey Guys,
I really like the article because right now I am trying to get my rest service working and I prefer the @EJB annotation over the initial context blah. Anyways if I am annotating my class with @Sateless and if I use an @EJB annotation, my annotated variable is still null... I tried this out with jboss and with JOnAS... Any Ideas?
@Path("/user")
@Stateless
public class UserService {
private static Logger log = Logger.getLogger(UserService.class.getName());
@EJB(beanInterface=UserFacadeLocal.class, mappedName="myPlace/UserFacade/local") private UserFacadeLocal bean;
@GET
@Produces("text/xml")
public ServiceResult getUser() {
ServiceResult result = new ServiceResult();
bean.getUser(3); //fails
return result;
}
}
Ido Ran replied on Tue, 2010/02/23 - 2:50am
Milan Kuchtiak replied on Thu, 2010/06/10 - 7:42am
in response to:
Ido Ran
Sorry for replying so late.
It's available using:
RESTful Web Services node -> REST Resources Configuration
Daniil Kasyanov replied on Tue, 2011/06/14 - 2:06am
Daniil Kasyanov replied on Tue, 2011/06/14 - 2:08am
in response to:
Daniil Kasyanov
Andries Schutte replied on Fri, 2011/08/05 - 12:25pm
Hi,
thanks for the useful example. Just one note: If the @Stateless EJB implements an interface, the container throws an exception (in the case of Glassfish) or doesn't inject any dependencies (in the case of JBoss). If the @Stateless EJB doesn't implement an interface, it works fine on both containers.
Cheers,
Andries.
Andries Schutte replied on Fri, 2011/08/05 - 12:46pm
in response to:
Andries Schutte
..or, if one wants to keep the interface implementation, one could annotate the @Stateless EJB with @LocalBean. That also works on both containers I tried.
Rajesh Viswanad... replied on Wed, 2012/03/07 - 1:37am
in response to:
Reza Rahman
Hi Milan,
Thanks for the article !!
I have few queries regarding EJb to ResT.
I have created an EJB 3.0 application and converted it to ReST service. I'm able to invoke methods on this ReST service using the url some thing like this: http://localhost:9080/EJB2TOReSTWeb/rest/customers
Now I'm trying to invoke the methods on my EJB by getting the EJB object through JNDI lookup.
but when I do initialConetext.lookup("jndiName");
I'm getting NameNotFoundException on client side. I have checked for this jndi name on my server, but i dont see any ejb registered with that name.
My Question here is : If we convert an EJB either 2.1 or 3.0 into ReST service, can we still do the lookup of that EJB the way we do it in normal way using initialContext.lookUp();
I'm using JBoss 4.2.3 server, i tried on WAS6.1 also.
Any help would be really appreciated.
Thanks,
Rajesh V
Matt Coleman replied on Wed, 2012/03/21 - 12:45pm
Milan,what a great program..this is awesome! web designer buffalo
Mateo Gomez replied on Thu, 2012/08/16 - 1:12am
what a great combination i must say
mexican dessert recipes
Morkel Abie replied on Thu, 2013/05/02 - 5:09am
Reeti Rajput replied on Fri, 2013/05/03 - 6:00am
in response to:
Morkel Abie
www.travelviews.co Before you search the information in the internet, you need to think what your need for the holiday is. Do you want budget holiday? Or do you want holiday with high standard of accommodation? Per the information provided, you can then select and use the camping holiday smartly.