Monday, June 27, 2011

Weblogic 10.3.4+ Jersey JAX-RS + JSON + SlickGrid

I want to try some RESTful services returning JSON response and use response in JS widgets as part of POC to propose them as an alternative to SOAP based services. Many developers have implemented similar functionality before and we can find many examples on the web (google). But I wanted to try it out myself before I agree with other developers who advocate for REST bases services and to be honest I am convinced after building a simple example application in less than 2 hrs.

My goal is to deploy the example application in Oracle weblogic 10.3.4 and use Jersey JAX-RS 1.5 implementation as this implementation is supported by weblogic and comes as part of shared library. Below are the sequence of steps that I have followed:

1. Enable Jersey JAX-RS implementation in weblogic. Link

2. Setup Maven for weblogic 10.3.4. Link

3. Create a Dynamic webproject in MyEclipse and create a simple service that returns JSON array as response.

POM file

  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>wlrestgrid</groupId>
 <artifactId>wlrestgrid</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <name />
 <description />
 <dependencies>
  <dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>2.1</version>
  </dependency>
  <dependency>
   <groupId>com.sun.xml.bind</groupId>
   <artifactId>jaxb-impl</artifactId>
   <version>2.1.12</version>
  </dependency>
  <dependency>
   <groupId>javax.activation</groupId>
   <artifactId>activation</artifactId>
   <version>1.1</version>
  </dependency>
  <dependency>
   <groupId>javax.xml.stream</groupId>
   <artifactId>stax-api</artifactId>
   <version>1.0-2</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-core</artifactId>
   <version>1.4</version>
  </dependency>
  <dependency>
   <groupId>javax.ws.rs</groupId>
   <artifactId>jsr311-api</artifactId>
   <version>1.1.1</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-server</artifactId>
   <version>1.4</version>
  </dependency>
  <dependency>
   <groupId>asm</groupId>
   <artifactId>asm</artifactId>
   <version>3.1</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-client</artifactId>
   <version>1.4</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-json</artifactId>
   <version>1.4</version>
  </dependency>
  <dependency>
   <groupId>org.codehaus.jettison</groupId>
   <artifactId>jettison</artifactId>
   <version>1.1</version>
  </dependency>
 </dependencies>
 <build>
  <sourceDirectory>${basedir}/src</sourceDirectory>
  <outputDirectory>${basedir}/WebRoot/WEB-INF/classes</outputDirectory>
  <resources>
   <resource>
    <directory>${basedir}/src</directory>
    <excludes>
     <exclude>**/*.java</exclude>
    </excludes>
   </resource>
  </resources>
  <plugins>
   <plugin>
    <groupId>com.oracle.weblogic</groupId>
    <artifactId>weblogic-maven-plugin</artifactId>
    <version>10.3.4</version>
    <configuration>
     <adminurl>t3://localhost:7001</adminurl>
     <user>weblogic</user>
     <password>WEBLOGIC_PASSWORD</password>
     <upload>true</upload>
     <action>deploy</action>
     <remote>false</remote>
     <verbose>true</verbose>
     <source>${project.build.directory}/${project.build.finalName}.${project.packaging}</source>
     <name>${project.build.finalName}</name>
    </configuration>
    <executions>
     <execution>
      <phase>install</phase>
      <goals>
       <goal>deploy</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>a
</project>

web.xml will have JAX-RS servlet mapping

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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">
 <display-name></display-name>
 <servlet>
  <display-name>JAX-RS REST Servlet</display-name>
  <servlet-name>JAX-RS REST Servlet</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>JAX-RS REST Servlet</servlet-name>
  <url-pattern>/services/*</url-pattern>
 </servlet-mapping>
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
</web-app>


HelloWorld.java

package com.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;

import com.bean.GridObject;


@Path("/helloworld")
public class HelloWorld {
 @Context
 private UriInfo context;

 public HelloWorld() {
 }

 @GET
 @Path("getGridData")
 @Produces( { MediaType.APPLICATION_JSON})
 public JSONArray getGridByJson() throws JSONException{
  JSONArray arr = new JSONArray();
  for(int i=0; i< 100; i++){
      arr.put(new GridObject("Task "+i, "5 days", i * 1, "01/01/2009", "01/05/2009", i % 5==0).toJson());
    }
        return arr;
 }
 
}

GridObject.java is a simple POJO object with toJson() method to return json object

package com.bean;

import javax.xml.bind.annotation.XmlRootElement;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

@XmlRootElement
public class GridObject {
 private String title, duration;
 private int percentComplete;
 private boolean effortDriven;
 private String start, finish;

 
 public GridObject() {
  super();
  // TODO Auto-generated constructor stub
 }

 public GridObject(String title, String duration, int percentComplete,
   String start, String finish, boolean effortDriven) {
  this.title = title;
  this.duration = duration;
  this.percentComplete = percentComplete;
  this.start = start;
  this.finish = finish;
  this.effortDriven = effortDriven;
 }

 public String getTitle() {
  return title;
 }

 public void setTitle(String title) {
  this.title = title;
 }

 public String getDuration() {
  return duration;
 }

 public void setDuration(String duration) {
  this.duration = duration;
 }

 public int getPercentComplete() {
  return percentComplete;
 }

 public void setPercentComplete(int percentComplete) {
  this.percentComplete = percentComplete;
 }

 public boolean isEffortDriven() {
  return effortDriven;
 }

 public void setEffortDriven(boolean effortDriven) {
  this.effortDriven = effortDriven;
 }

 public String getStart() {
  return start;
 }

 public void setStart(String start) {
  this.start = start;
 }

 public String getFinish() {
  return finish;
 }

 public void setFinish(String finish) {
  this.finish = finish;
 }

 public JSONObject toJson() throws JSONException {
  JSONObject obj = new JSONObject();
  obj.put("title", title);
  obj.put("duration", duration);
  obj.put("percentComplete", new Integer(percentComplete));
  obj.put("start", start);
  obj.put("finish", finish);
  obj.put("effortDriven", new Boolean(effortDriven));
  return obj;
 }

}



4. Create a JSP page that invokes the RESTful service using JQuery.getJSON() method to get the response and use this response to generate the slickgrid. Why slickgrid?? I like it after seeing the comprehensive exmaple.

Copy all necessary javascript, css and image files from slickgrid to your web applicaiton.

slickgrid.jsp

<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <title>SlickGrid example 1: Basic grid</title>
  <link rel="stylesheet" href="css/slickgrid/slick.grid.css" type="text/css" media="screen" charset="utf-8" />
        <link rel="stylesheet" href="css/smoothness/jquery-ui-1.8.5.custom.css" type="text/css" media="screen" charset="utf-8" />
  <link rel="stylesheet" href="css/slickgrid/examples.css" type="text/css" media="screen" charset="utf-8" />
 </head>
 <body>
  <table width="100%">
  <tr>
   <td valign="top" width="50%">
    <div id="myGrid" style="width:600px;height:500px;"></div>
   </td>
   <td valign="top">
    <h2>Demonstrates:</h2>
    <ul>
     <li>basic grid with minimal configuration</li>
    </ul>
   </td>
  </tr>
  </table>

  <script language="JavaScript" src="lib/jquery-1.4.3.min.js"></script> 
  <script language="JavaScript" src="lib/jquery-ui-1.8.5.custom.min.js"></script> 
  <script language="JavaScript" src="lib/jquery.event.drag-2.0.min.js"></script> 
        
        <script language="JavaScript" src="javascripts/slickgrid/slick.core.js"></script> 
  <script language="JavaScript" src="javascripts/slickgrid/slick.editors.js"></script> 
  <script language="JavaScript" src="javascripts/slickgrid/slick.grid.js"></script> 
  <script>

  var grid;
  var data = [];
  var columns = [
   {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title"},
   {id:"duration", name:"Duration", field:"duration"},
   {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter},
   {id:"start", name:"Start", field:"start", minWidth:60},
   {id:"finish", name:"Finish", field:"finish", minWidth:60},
   {id:"effort-driven", name:"Effort Driven", sortable:false, width:80, minWidth:20, maxWidth:80, cssClass:"cell-effort-driven", field:"effortDriven", formatter:BoolCellFormatter}
  ];
 
  var options = {
   //editable: false,
   enableAddRow: false,
   enableCellNavigation: true
  };

  $(function() {
       //http://localhost:8080/wlrestgrid/services/helloworld/getGridData
             $.getJSON("services/helloworld/getGridData?timire="+Math.min(100, Math.round(Math.random() * 110)) , 
                function(vals){
                $.each(vals, function() { 
                    data.push(this); 
                }); 
                grid = new Slick.Grid($("#myGrid"), data, columns, options); 
            }); 
        });

  </script>

 </body>
</html>



5. Deploy the application to Oracle weblogic server using Maven and open the slickgrid.jsp file in the browser.

No comments:

Post a Comment

PF