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.

  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.

  2. 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.

  3. 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":

Netbeans REST Tester

Finally, the HTTP GET method can also be tested easily by typing resource URI in the browser:

HTP GET test

0

(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

cdshinde 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

rnaufal replied on Wed, 2009/12/02 - 10:51am

Good introduction to combine REST services with EJB! BTW, I think is the @EJB annotation which enables bean dependency injection by the container instead of the @Stateless annotation.

mkuchtiak replied on Wed, 2009/12/02 - 12:20pm in response to: cdshinde

> Is there some specific API that we need to use?

In java code, you can use Jersey Client API.

See: Consuming REST

mkuchtiak replied on Wed, 2009/12/02 - 12:28pm in response to: rnaufal

> 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.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.