Miles to go …

February 18, 2010

TOTD #124: Using CDI + JPA with JAX-RS and JAX-WS

Filed under: General — arungupta @ 10:36 am

This is a follow up blog to TOTD #120 and TOTD #123. These two blogs together have created a simple Java EE 6 application and showed the following features so far:

  • No-interface view for EJB
  • EJBs packaged in a WAR file
  • Optional "faces-config.xml" for Java Server Faces
  • FacesServlet registered using Servlet 3.0 programmatic registration APIs
  • Java Server Faces navigation rules using convention-over-configuration
  • Optional "web.xml" for Servlets 3.0
  • Add database access using Java Persistence API 2.0
  • Show type-safe Criteria API from JPA 2.0
  • Use Context & Dependency Injection for JSF managed beans
  • Add Ajax effects from Java Server Faces 2.0
  • Add Bean Validation to the JSF managed bean

GlassFish v3 is the Java EE 6 Reference Implementation and comes bundled with a complete SOAP Web services stack (Metro/JAX-WS) and a RESTful stack (JAX-RS/Jersey). This blog will update the previously created Maven project with:

  • A SOAP Web service using JAX-WS
  • A RESTful Web service using JAX-RS
  • Use Context & Dependency Injection with JAX-WS and JAX-RS
  • Query the database using JPA 2 based upon criteria from the Web service invocation

Lets get started!

  1. Use the Maven project from TOTD #123 and update the directory structure as follows:

    The changes are:

    • "" is added for the RESTful representation of Actor table.
    • "" is added to invoke the SOAP-based Web service.
    • "" is updated to query the database for an Actor identified by "id".
  2. The updated files are explained below.
    • A new method is added to as shown below:
      public Actor findActorById(int id) {
      EntityManager em = emf.createEntityManager();
      CriteriaBuilder cb = emf.getCriteriaBuilder();
      CriteriaQuery<Actor> criteria = cb.createQuery(Actor.class);
      // FROM clause
      Root<Actor> actor = criteria.from(Actor.class);
      // SELECT clause
      // WHERE clause
      criteria.where(cb.equal(actor.<Short>get("actorId"), id));
      Query q = em.createQuery(criteria);
      return (Actor)q.getResultList().get(0);

      This method queries the database for an actor by his id and uses the typesafe Criteria API to achieve the purpose. The FROM, SELECT, and WHERE clause are highlighted in the code. A cast to EclipseLink specific class is required because of the bug #303205.

      package org.glassfish.samples;
      import javax.inject.Inject;
      import javax.jws.WebService;
      import sakila.Actor;
      public class SOAPService {
      @Inject SakilaBean bean;
      public String sayHello(int id) {
      Actor a = bean.findActorById(id);
      return "Hello " + a.getFirstName();

      The key points in the code are:

      • Standard JAX-WS annotations from "javax.jws.*" package are used to represent the Web service.
      • The Web service has only one method "sayHello" that concatenates the string "Hello" with the first name of "Actor" identified by "id".
      • No deployment descriptor modifications are required to publish this Web service.
      • "SakilaBean" is injected using @Inject annotation and used to query the database. This allows to encapsulate all the database details in one class and injected in a typesafe manner.
      package org.glassfish.samples;
      public class RESTApplication extends Application {

      This is a marker class to inform Jersey of the root resource to be registered. By default, all classes with @Path and @Provider annotations are included. It also specifies the base path at which all resources are accessible.

      An alternative to this class is to specify the required information in "web.xml" as:

           <servlet-name>Jersey Web Application</servlet-name>
           <servlet-name>Jersey Web Application</servlet-name>

      So only one of or changes in "web.xml" are required.

      package org.glassfish.samples;
      import javax.enterprise.context.RequestScoped;
      import javax.inject.Inject;
      import sakila.Actor;
      public class ActorResource {
      @Inject SakilaBean sakila;
      public Actor getActor(@PathParam("id") int id) {
      return sakila.findActorById(id);

      The key points in the code are:

      • Standard JAX-RS annotations from "" package are used to represent the RESTful resource.
      • "getActor" method is invoked when the resource is accessed using HTTP GET.
      • The resource is accessible at "/actor/{id}" URL where "{id}" is mapped to the "id" parameter of "getActor" method.
      • SakilaBean is injected in a typesafe manner using @Inject annotation. This bean is then used to query the database using the "id" parameter.
      • "getActor" method produces JSON representation, as defined by the "@Produces" annotation. This is easily achieved by updating our Persistence Unit (PU) created in TOTD #122 and adding "@javax.xml.bind.annotation.XmlRootElement" as the class level annotation on "sakila.Actor" class. Make sure to install the updated PU to your local Maven repository.

Package and deploy the application as:

mvn clean package
./bin/asadmin deploy --force=true ~/samples/javaee6/simplewebapp/target/simplewebapp-1.0-SNAPSHOT.war

Now the SOAP web service is accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/SOAPServiceService" and looks like:

Notice, the URL in your case may be different if the Web service class name was different. The default URL is "http://<HOST>:<PORT>/<CONTEXT ROOT><WEB SERVICE CLASS NAME>Service".

This Web service can be easily tested by using the in-built tester accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/SOAPServiceService?tester" and looks like:

The WSDL describing the Web service can be seen by clicking on the "WSDL File" link. The Web service method can be invoked by entering a value ("id" of the Actor) in the text box and clicking on "sayHello" button. Here is a sample run:

Clicking on "Submit" invokes the Web service which then uses the injected "SakilaBean" to query the database using the parameter specified. The first name from the response from the database is then extracted, concatenated with the string "Hello" and returned as Web service response.

The RESTful resource is accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/sakila/actor/5" and looks like:

As in the SOAP-based Web service, the "5" in the URL is mapped to a parameter in the "", the injected "SakilaBean" is then used to query the database and returns the JSON representation. Specifying a different number in the URL will show the RESTful JSON representation for that particular actor.

More Java EE 6 features will be covered in subsequent blogs. Are you interested in any particular ones ?

Technorati: jaxws metro webservices jaxrs rest jersey glassfish v3 cdi jsr299 weld

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot
Related posts:
  1. TOTD #123: f:ajax, Bean Validation for JSF, CDI for JSF and JPA 2.0 Criteria API – all in one Java EE 6 sample application
  2. TOTD #99: Creating a Java EE 6 application using MySQL, JPA 2.0 and Servlet 3.0 with GlassFish Tools Bundle for Eclipse
  3. TOTD #151: Transactional Interceptors using CDI – Extensible Java EE 6
  4. TOTD #121: JDBC resource for MySQL and Oracle sample database in GlassFish v3
  5. TOTD #122: Creating a JPA Persistence Unit using NetBeans 6.8


  1. [Trackback] This post was mentioned on Twitter by arungupta: New Blog: TOTD #124: Using CDI + JPA with JAX-RS and JAX-WS: This is a follow up blog to TOTD #120 and TOTD #123. …

    Comment by uberVU - social comments — February 19, 2010 @ 8:55 pm

  2. Are the sources available as a ZIP? I don’t use Maven. Thanks!


    Comment by NBW — February 22, 2010 @ 2:42 pm

  3. NBW,

    All sources are posted on:

    and above blog. You’ll need Maven to run the project anyway. Will post the Maven project in next blog entry.

    Comment by Arun Gupta — February 23, 2010 @ 4:23 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.
Powered by WordPress