Thursday, April 18, 2013

Configuring EJB with Restful Web Service in ADF

In current JDeveloper we can expose EJB's as Web Service, however this will be a SOAP based web service. In this article will discuss on configuring EJB with restful web service using jersey support. This article provides an example of building a complete RESTful API using the different HTTP methods:
  • GET to retrieve data
  • POST to add data
  • PUT to update data
  • DELETE to delete data
You can download the sample workspace from here
[Runs with Oracle JDeveloper 11.1.2.3.0 + HR Schema]

Implementation Steps:-

Create a EJB project, then create the DEPARTMENT JPA/EJB 3.0 Entity using the"Entities from tables" EJB wizard, create a Stateless Session bean and select Departments JPA Entity to generates façade methods.

Open the Departments entity and annotate with @XmlRootElement, when a top level class or an enum type is annotated with the @XmlRootElement annotation, then its value is represented as XML element in an XML document. Basically this allow ADF to convert this object directly to XML.JSON.


Add a new project ('REST Web Service Project') in the application and mention the name as WebService. Go to 'Project properties' > 'Dependencies' and add the Model project as a dependency.

Next add the supporting libraries to the Rest Web Service project, go to 'Project properties' > 'Libraries and Classpath'. Libraries are listed in the below screen shot, you can find the libraries in EJBRestService/libs folder.


Create and open EJBRestService java class, annotate with @Path("EJBRESTService") on class level. Click on the @Path notice on the left side yellow bulb will be appeared and click on the bulb to "Configure web.xml for jersey JAX-RS web services" as shown in below.


Now web.xml is created under WEB-INF folder. Open the file and replace with the below xml code.
<?xml version = '1.0' encoding = 'windows-1252'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <filter>
        <filter-name>JpsFilter</filter-name>
        <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
        <init-param>
            <param-name>enable.anonymous</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>JpsFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <servlet>
        <servlet-name>jersey</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
            <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>webservice</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--load-on-startup>1</load-on-startup-->
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey</servlet-name>
        <url-pattern>/jersey/*</url-pattern>
    </servlet-mapping>
    <ejb-local-ref>
        <ejb-ref-name>ejb/SessionEJBBean</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local>model.SessionEJBLocal</local>
        <ejb-link>SessionEJB</ejb-link>
    </ejb-local-ref>
</web-app>
Points to be noticed from the above xml code are :
  1. param-value under com.sun.jersey.config.property.packages tag - change the package name by your own package name used in the application.
  2. Add the Ejb References 
Open the EJBRestService.java file and add the below code.
@Path("EJBRESTService")
public class EJBRestService {
    public EJBRestService() {
        super();
    }

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public List getAllDepts() {
        List list = new ArrayList();
        try {
            Context ic = getInitialContext();
            SessionEJBLocal sessionEJB = (SessionEJBLocal)ic.lookup("java:comp/env/ejb/SessionEJBBean");
            for (Departments departments : (List)sessionEJB.getDepartmentsFindAll()) {
                list.add(departments);
            }
            ic.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return list;
    }

    @POST
    @Consumes(MediaType.APPLICATION_XML)
    public void persistDept(Departments departments) {
        try {
            Context ic = getInitialContext();
            SessionEJBLocal sessionEJB = (SessionEJBLocal)ic.lookup("java:comp/env/ejb/SessionEJBBean");
            sessionEJB.persistDepartments(departments);
            ic.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    @PUT
    @Consumes(MediaType.APPLICATION_XML)
    public void mergeDept(Departments departments) {
        try {
            Context ic = getInitialContext();
            SessionEJBLocal sessionEJB = (SessionEJBLocal)ic.lookup("java:comp/env/ejb/SessionEJBBean");
            sessionEJB.mergeDepartments(departments);
            ic.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    @DELETE
    @Path("{departmentId}")
    public void removeDept(@PathParam("departmentId")
        BigDecimal departmentId) {
        try {
            Context ic = getInitialContext();
            SessionEJBLocal sessionEJB = (SessionEJBLocal)ic.lookup("java:comp/env/ejb/SessionEJBBean");
            Departments departments = new Departments();
            departments.setDepartmentId(departmentId);
            sessionEJB.removeDepartments(departments);
            ic.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    private static Context getInitialContext() throws NamingException {
        InitialContext ic = new InitialContext(); // WebLogic Server 10.x connection details
        return ic;
    }
}
Now deploy/run the EJBRestService.java client in the Integrated Weblogic Server to test. Once client runs it will provide the Target Application WADL/Target URL in JDeveloper console, click on any link to run the service in HTTP Analyzer. Below screen shows the GET method accessed in HTTP Analyzer with result.


Note:- Put and Post method are not working with HTTP Analyzer, you might need to create java client/ADF application to test these methods.

2 comments:

  1. wonderfull Bolg, really helpfull.Thanks a lot .

    ReplyDelete
  2. Tutorial detail, easy understand, very nice post and thank you very much for share..

    ReplyDelete