Friday, March 15, 2013

How to use jqgrid with Struts2 JSON result

jqgrid plugin is one of the most famous jquery plugins to display tables in web pages which enables searching, sorting and filtering etc.

I wanted to integrate jqgrid with Struts2 but there was little to no proper documentation on how to do it. I wanted to use JSON format and no website has clearly mentioned (or atleast I didn't find any) the format of the JSON and how it needs to be created using Struts2. So after some trial and error I managed to get this to work.



struts.xml will look like the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
 
<struts>    

     <constant name="struts.devMode" value="true" />     
    <package name="user" namespace="/User" extends="struts-default">
        <result-types>
            <result-type name="json" class="com.googlecode.jsonplugin.JSONResult"/>
        </result-types>    
        <action name="getUsersList" class="com.shazin.struts2hello.action.GetUsersListAction">
               <result type="json" />
          </action>        
          <action name="ListUsers" class="com.shazin.struts2hello.action.ListUsersAction">
            <result name="SUCCESS">../pages/list_users.jsp</result>            
        </action>
    <package>

There are two Actions getUserList which will return the JSON result and ListUsers which will render the JSON into the jqgrid. Following is the source code for GetUsersListAction and since this object is directly used to serialize the result into JSON it needs to have the instance variable names as it is with getters and setters.

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.Action;
import com.shazin.struts2hello.model.User;
import com.shazin.struts2hello.service.UserService;
import com.shazin.struts2hello.service.impl.UserServiceImpl;

public class GetUsersListAction {
    
    private String page;  
    private Double total;  
    private String records;  
    private List rows; 
    
    public String execute() {
        page = "1";
        total = 1.0;        
        UserService userService = new UserServiceImpl(); 
        List<User> usersList = userService.getAllUsers(); // Retrieves users from database
        records = usersList.size()+"";
        rows = new ArrayList();
        int id = 1;
        for(User u:usersList) {
            rows.add(new Row(String.valueOf(id), 
                    new String[] { String.valueOf(id), u.getFirstName() , u.getLastName(), u.getUsername(), u.getEmail() }));
            id++;
        }
        
        return Action.SUCCESS;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public Double getTotal() {
        return total;
    }

    public void setTotal(Double total) {
        this.total = total;
    }

    public String getRecords() {
        return records;
    }

    public void setRecords(String records) {
        this.records = records;
    }

    public List getRows() {
        return rows;
    }

    public void setRows(List rows) {
        this.rows = rows;
    }

    public class Row implements Serializable {
        private String id;
        
        private String[] cell;
        
        public Row() {
            
        }
        
        public Row(String id, String[] cell) {
            setId(id);
            setCell(cell);
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String[] getCell() {
            return cell;
        }

        public void setCell(String[] cell) {
            this.cell = cell;
        }        
        
    }    
}

The JSON output will be like this and it should be in this format to work with jqgrid.

{"page":"1","records":"1","rows":[{"cell":["1","Shazin","Sadakath","ssadakath","shazin.sadakath@gmail.com"],"id":"1"}],"total":1.0}

ListUsers action source code is really simple

public class ListUsersAction {
    public String execute() {
        return "SUCCESS";
    }
}


Finally the source code for list_users.jsp page

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" media="screen" href="../css/jquery-ui-1.10.2.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="../css/ui.jqgrid.css" />
<script src="../js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="../js/jquery-ui-1.10.2.custom.min.js" type="text/javascript"></script>
<script src="../js/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="../js/jquery.jqGrid.min.js" type="text/javascript"></script>
<title>List Users</title>
<script type="text/javascript"> 
jQuery().ready(function (){
    //alert('Hi');
    jQuery("#list1").jqGrid({
           url:'/Struts2Hello/User/getUsersList.action',
        datatype: "json",
           colNames:['User Id','First Name', 'Last Name', 'Username','Email'],
           colModel:[
               {name:'id',index:'id', width:75},
               {name:'firstName',index:'firstName', width:90},
               {name:'lastName',index:'lastName', width:100},
               {name:'username',index:'username', width:80},
               {name:'email',index:'username', width:80}                   
           ],
           rowNum:10,
           autowidth: true,
           rowList:[10,20,30],
           pager: jQuery('#pager1'),
           sortname: 'id',
        viewrecords: true,
        sortorder: "desc",
        caption:"Users"
    }).navGrid('#pager1',{edit:false,add:false,del:false});    
});                
</script>
</head>
<body>
    <table id="list1"></table>
    <div id="pager1"></div>
</body>
</html>

9 comments:

  1. Thank you very much for this example. It helped a lot.
    Your mention of the variables naming convention to match with getters and setters has helped a lot.
    Were you able to find any reading material?

    ReplyDelete
  2. I get this following json data

    Grid Data: {"total":1,"page":1,"records":8,"rows":[{"firstName":"chk1", "lastName":"Air", "address":"Air"},{"firstName":"Chk2", "lastName":"Oil", "address":"Oil"}]}



    But it doesn't get populated in the jqGrid

    here is my action



    ReplyDelete
  3. Hi selva jj,

    You JSON output is different from the one in the post. rows should have cell and id.

    ReplyDelete
  4. Getting Ognl:NoConversationPossible Error

    I’m Facing some Issue, Can you please Look here, I posted in detail..,

    http://stackoverflow.com/questions/21474295/getting-ognlnoconversationpossible-error

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

    ReplyDelete
  6. Can you please upload complete source files.
    Thanks

    ReplyDelete
  7. Would u pls send me full source code for strtus2 jqgrid example to my mail id(rajeshsavi123@gmail.com)

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

    ReplyDelete
  9. could you please send the complete source code to my id infobalu@gmail.com
    Thanks
    in Advance

    ReplyDelete