Friday, September 16, 2011

Spring MVC: Integrating MySQL, MongoDB, RabbitMQ, and AJAX - Part 1: jQgrid View

Review

In the previous section, we've managed to create the core Event management system and use DataTables to display tabular data. In this section, we will use jQgrid, a jQuery plugin, to provide advance features to our table like sorting and searching.

Where am I?

Table of Contents

  1. Event Management
  2. Messaging support
  3. Error persistence
  4. Build and deploy

jQgrid View

As mentioned in the previous section, we will present tabular data using jQgrid and we'll add caching functionality to improve the application's performance. We'll utilize Spring Cache as our abstraction tool, and Ehcache as our cache storage.

What is jQgrid?
jqGrid is an Ajax-enabled JavaScript control that provides solutions for representing and manipulating tabular data on the web. Since the grid is a client-side solution loading data dynamically through Ajax callbacks, it can be integrated with any server-side technology, including PHP, ASP, Java Servlets, JSP, ColdFusion, and Perl.
jqGrid uses a jQuery Java Script Library and is written as plugin for that package. (Source: http://www.trirand.com/jqgridwiki/doku.php)

What is Ehcache?
Ehcache is an open source, standards-based cache used to boost performance, offload the database and simplify scalability. Ehcache is robust, proven and full-featured and this has made it the most widely-used Java-based cache. Source: http://ehcache.org/

Before we proceed with the development, let's preview the final output:

Development

Since we'll be adding caching functionality, we need to provide a custom controller, and since jQgrid requires a specific JSON format, we need to create a custom DTO. We shall divide this page as follows:
  1. Data Transfer Object (DTO)
  2. Controller
  3. JSP page

1. Data Transfer Object (DTO)

jQgrid can exchange and communicate data via different formats: XML, JSON, Arrays, and etc. We will use JSON as our data-interchange format because it's lightweight and flexible. In order for our JSON format to work, we need to create a custom data transfer object (DTO) that matches our jQgrid's JSON reader property.

Below is our jQgrid JSON reader declaration:


We have to match those fields in our DTO (for an explanation of those fields, read the comments in the DTO). Consequently, we have the following class:



2. Controller

Next we will create a new controller to handle jQgrid-related requests with caching functionality:



We are re-using the same EventService for the DataTables. The methods for adding, editing, and deleting are exact copies of the EventController for the DataTables as well.

There are two unique methods here: the getEventPage() and the getAll(). The getEventPage() returns a JSP page containing a jQgrid table. The getAll() is a little-bit involved since it needs to wrap the results in a DTO, but nonetheless, it's quite straightforward.

We've also annotated the CRUD methods with two Java annotations: @Cacheable and @CacheEvict to add caching functionality. Notice how easy it is to add cache to our existing application.

To highlight the difference, I suggest comparing the DataTables and jQgrid version and monitor the calls to EventService via the Event Monitor page (part of the application's feature). Only the DataTables will show calls to readAll().

What is @Cacheable?
@Cacheable is used to demarcate methods that are cacheable - that is, methods for whom the result is stored into the cache so on subsequent invocations (with the same arguments), the value in the cache is returned without having to actually execute the method. Source: Spring Reference 3.1.0.M1

What is @CacheEvict?
@CacheEvict demarcates methods that perform cache eviction, that is methods that act as triggers for removing data from the cache. Just like its sibling, @CacheEvict requires one to specify one (or multiple) caches that are affected by the action, allows a key or a condition to be specified but in addition, features an extra parameter allEntries which indicates whether a cache-wide eviction needs to be performed rather then just an entry one Source: Spring Reference 3.1.0.M1

3. JSP page

Now, let's examine the JSP page. It's a single page containing the following sections:
  1. URLs
  2. Imports
  3. Menu
  4. Table
  5. jQgrid initialization
  6. Pager functions
    1. Add function
    2. Edit function
    3. Delete function

event-page.jsp


Let's discuss each section:

a. URLs
The following section declares two URLs which uses the JSTL core tag: the root and the resources URLs respectively. These URLs are here for reusability purposes:



b. Imports
The following snippet imports a number of CSS and JavaScript resources which includes the core jQuery library, the DateJS library (a Date utility, http://www.datejs.com/), and the jQgrid plugin (http://www.trirand.com/blog/):



c. Menu
The following section declares a menu list:



d. Table
The following section declares a div with two inner elements: a table and a div for attaching the jQgrid and the control buttons respectively:



e. jQgrid initialization
The following section initializes the jQgrid table. The function declares the table properties, column models, url where to retrieve the data, and control buttons to display in the pager section:



f. Pager functions

1. Add function
The following section attaches a function to the Add button in the jQgrid pager section:



2. Edit function
The following snippet attaches a function to the Edit button in the jQgrid pager section:



3. Delete function
The following section attaches a function to the Delete button in the jQgrid pager section:



Results

When we run the application, the result should be similar to the following image (this is an actual screenshot taken from a live deployment):


Limitations

Our jQgrid view has some limitations. However, these are not jQgrid limitations but rather something that we intentionally (and unintentionally) did not implement:
  • Search feature is not implemented
  • Sort feature is not implemented
  • UI validation is not fully implemented

Playground

Some developers might not have time to build the entire project. Maybe they just want something to play around really fast. Because of that, I've deployed live samples to Cloud Foundry and added sample fiddles via JSFiddle.

JSFiddle

If you want to explore more about jQgrid, I've provided a fiddle for you to play around. This fiddle do not need any server-side programs to run. Feel free to fork it.

Here's the fiddle: http://jsfiddle.net/krams/jqJch/

What is JSFiddle?
JsFiddle is a playground for web developers, a tool which may be used in many ways. One can use it as an online editor for snippets build from HTML, CSS and JavaScript. The code can then be shared with others, embedded on a blog, etc. Using this approach, JavaScript developers can very easily isolate bugs. We aim to support all actively developed frameworks - it helps with testing compatibility - Source: http://doc.jsfiddle.net/

Cloud Foundry

If you want to tinker with a live deployment, I suggest you visit the application's live site at http://spring-mysql-mongo-rabbit.cloudfoundry.com/jqgrid/event

What is Cloud Foundry?
Cloud Foundry is the open platform as a service project initiated by VMware. It can support multiple frameworks, multiple cloud providers, and multiple application services all on a cloud scale platform.

Next Section

In the next section, we will add messaging support using RabbitMQ and Spring AMQP. Read next.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC: Integrating MySQL, MongoDB, RabbitMQ, and AJAX - Part 1: jQgrid View ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

8 comments:

  1. Using the same code, but the submit on the add/edit pages doesn't seem to work. Any ideas ?

    ReplyDelete
  2. Trying this fiddle,

    http://jsfiddle.net/krams/jqJch/
    how do i view the data, the event jqgrid doesn't seem to be doing any formating also, add/edit doesn't work gives a status code 404.
    Can you help .

    ReplyDelete
  3. @smitha, it's supposed to produce a 404 since that fiddle is supposed to demo the jQgrid UI only without any server-side dependencies. Regarding your initial inquiry, you'll have to check the logs. It's hard to pinpoint the cause of such error if we don't have any logs.

    ReplyDelete
  4. Thanks for the wonderful tutorial. It has helped me a lot.. but i am stuck with some data type conversion for the date object.
    I defined an Entity with a date object
    @DateTimeFormat(iso=ISO.DATE)
    @Column private Date dob;
    and that resulted in json having the date as '710793000000' Hence i used the JsonSerializer http://blog.seyfi.net/2010/03/how-to-control-date-formatting-when.html
    and converted the date to the dd/mm/yy format. With this i am able to get the right date in the jqgrid. But on edit, (i use the datepicker with the dd/mm/yy format, i am able to see that the post data has the same date. I do serialize the postdata with
    serializeRowData: function(postdata){
    return { x01: JSON.stringify(postdata) };
    }
    but the date in my controller is all wrong, it seems to use the date given for month and the year also gets messed up.. Can you help.

    ReplyDelete
  5. Nice tutorial
    I do not want to implement an 'id' field. Instead what i have is a Project list and i want the id to be projectId which is the primary key field of Project Entity class.

    so in colModel {
    name : 'projectId',
    key : true,
    width : 100,
    sortable : false,
    editable : false,
    search : false
    }

    ant in the
    jsonReader : {
    root : "projects",
    page : "page",
    total : "total",
    records : "records",
    repeatitems : false,
    id : "projectId"
    }

    but this doesnt work. any valuable comments?

    ReplyDelete
  6. I have read your blog its very attractive and impressive. I like it your blog.

    Spring online training Spring online training Spring Hibernate online training Spring Hibernate online training Java online training

    spring training in chennai spring hibernate training in chennai

    ReplyDelete
  7. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    core java training in Electronic City

    Hibernate Training in electronic city

    spring training in electronic city

    java j2ee training in electronic city

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete