Tuesday, 29 March 2011

RESTful Web Service using JPA/EJB 3.0 Entities

In this example I created a more common use case of using JAX-RS Web Service based on a JPA/EJB 3.0 entity. I will only show the code here and what the project looks like in JDeveloper but in short you would have a setup as follows based on a DEPT table in the classic SCOTT schema.

JAX-RS Web Service -> SLSB ->  JPA/EJB 3.0 entity

1. Create the DEPT JPA/EJB 3.0 Entity using the"Entities from tables" EJB wizard.
2. Create a Statelesss Session bean which generates facade methods for the JPA Entity we created at step #1

Note: In this example we will just implement the default Dept.findAll named query created from the JPA Entity

package pas.au.jaxrs.jpa.dept;

import java.util.List;

import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless(name = "DeptSessionEJB", mappedName = "JAX-RS-DeptJPADemo-Demo-DeptSessionEJB")
public class DeptSessionEJBBean
  implements DeptSessionEJB, DeptSessionEJBLocal
{
  @PersistenceContext(unitName="Demo")
  private EntityManager em;

  public DeptSessionEJBBean()
  {
  }

  public Object queryByRange(String jpqlStmt, int firstResult,
                             int maxResults)
  {
    Query query = em.createQuery(jpqlStmt);
    if (firstResult > 0)
    {
      query = query.setFirstResult(firstResult);
    }
    if (maxResults > 0)
    {
      query = query.setMaxResults(maxResults);
    }
    return query.getResultList();
  }

  /** <code>select o from Dept o</code> */
  public List<Dept> getDeptFindAll()
  {
    return em.createNamedQuery("Dept.findAll").getResultList();
  }
}  

3. Create the JAX-RS Web Service as follows.
package pas.au.jaxrs.jpa.dept;

import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;


@Path ("/deptjpaservice")
public class DeptService
{
  private DeptSessionEJB deptBean;
  
  public DeptService()
  {
    Context context;
    try
    {
      context = getInitialContext();
      deptBean = (DeptSessionEJB)
        context.lookup
         ("JAX-RS-DeptJPADemo-Demo-DeptSessionEJB#pas.au.jaxrs.jpa.dept.DeptSessionEJB");
    }
    catch (NamingException e)
    {
      throw new RuntimeException (e.getMessage());
    }
  }

  @GET
  @Path("/departments")
  @Produces(MediaType.APPLICATION_XML)
  public List<Dept> listDepartments()
  {
    return deptBean.getDeptFindAll();
  }

  private static Context getInitialContext() throws NamingException
  {
    return new InitialContext();
  }
}

You could deploy this to Weblogic 10.3.4as per a previous post. In the example client above we just rujn it in the Integrated Server from JDeveloper to test it out.

4.  Run the JAX-RS Web Service when finished you should see the following in the log file.

[01:10:31 PM] ----  Deployment finished.  ----
Run startup time: 11380 ms.
[Application JAX-RS-DeptJPADemo deployed to Server Instance IntegratedWebLogicServer]

Target Application WADL -- http://localhost:7101/jaxrs-deptjpa/jersey/application.wadl

Target URL -- http://localhost:7101/jaxrs-deptjpa/jersey/deptjpaservice/departments

5. Using curl access it from a putty client as follows.

> curl http://paslap-au.au.oracle.com:7101/jaxrs-deptjpa/jersey/deptjpaservice/departments

Of course the example above just shows how easy it is to call a JAX-RS service from a simple UNIX command line , but to be honest the easiest way is from JDeveloper itself using the HTTP analzyer by clicking on the link in the log window as shown below. At least this way the output is nicely formatted for you.


Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><depts><department><deptno>10</deptno><dname>ACCOUNTING</dname><loc>NEW YORK</loc></department><department><deptno>20</deptno><dname>RESEARCH</dname><loc>DALLAS</loc></department><department><deptno>30</deptno><dname>SALES</dname><loc>CHICAGO</loc></department><department><deptno>40</deptno><dname>OPERATIONS</dname><loc>BOSTON</loc></department></depts>

The JDeveloper project would look as follows"

2 comments:

Gerard Davison said...

Hey Pas,

Why not show the REST support in the HTTP Analyzer in JDeveloper?

Gerard

Pas Apicella said...

I added that now. Previous posts on this did use the HTTP analyzer as well.