因为公司项目需要,在Hibernate+Struts2的环境下,研究了一下如何使用jqGrid。
说实在的,Struts2+jqGrid不是一个很好的组合。因为jqGrid中很多功能,基本上都使用的是AJAX的访问方式,并且,大家都知道,jqGrid需要的数据,要么是XML格式的,要么是JSON格式。(当然,我说的是一般情况,其实jqGrid还支持本地数据,以及xml字符串、json字符串之类的)
而Struts2已经把Action的返回做了很好的封装了。一般的情况下,最好不要通过Action的Execute方法去访问HttpServletResponse对象。但是要使用qGrid,就必须在execute方法中调用response,组装需要的xml或者json格式的数据,并返回到客户端。
怎么说呢,感觉比较怪异。另外,估计是我对struts2的json-plugin还不太熟悉,也不会用这个玩意,所以老是觉得程序的结构很怪异!
直白的说,jqGrid提供了一个很方便的数据显示外壳,但是具体的所有动作,还是要自己来实现。记住:jqGrid是基于服务器端处理的,也就是说,一切的查询、排序、分页等功能,都需要你在服务器端去自己实现。(我准备在下一篇文章中详细说一下jqGrid的简单查询——只通过一个字段过滤的查询动作,这是jqGrid默认的查询!)
下面是我的一个例子,随便写在这里供以后查阅(写给同事看的,大家别较真!):
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-CN" lang="zh-CN">
<head>
<title>jqgrid demo in Struts2</title>
<link rel="stylesheet" type="text/css" media="screen" href="themes/redmond/jquery-ui-1.7.1.custom.css" />
<link rel="stylesheet" type="text/css" media="screen" href="themes/ui.jqgrid.css" />
<link rel="stylesheet" type="text/css" media="screen" href="themes/ui.multiselect.css" />
<style>
html, body {
margin: 0; /* Remove body margin/padding */
padding: 0;
overflow: hidden; /* Remove scroll bars on browser window */
font-size: 75%;
}
.ui-tabs-nav li {position: relative;}
.ui-tabs-selected a span {padding-right: 10px;}
.ui-tabs-close {display: none;position: absolute;top: 3px;right: 0px;z-index: 800;width: 16px;height: 14px;font-size: 10px; font-style: normal;cursor: pointer;}
.ui-tabs-selected .ui-tabs-close {display: block;}
.ui-layout-west .ui-jqgrid tr.jqgrow td { border-bottom: 0px none;}
.ui-datepicker {z-index:1200;}
</style>
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery.jqGrid.min.js" type="text/javascript"></script>
<script src="js/i18n/grid.locale-en.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.7.2.custom.min.js" type="text/javascript"></script>
<script src="js/jquery.layout.js" type="text/javascript"></script>
<script src="js/jquery.tablednd.js" type="text/javascript"></script>
<script src="js/jquery.contextmenu.js" type="text/javascript"></script>
<script src="js/ui.multiselect.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#jsonmap").jqGrid({
url:'queryAllUsers.action',
datatype: "json",
postData: {depId: 1},
colNames:['ID','姓名', '登录名', '部门ID','是否可用'],
colModel:[
{name:'id',index:'id', width:90},
{name:'userName',index:'usrName', width:110},
{name:'loginName',index:'loginName', width:100},
{name:'dpCode',index:'dpCode', width:80, align:"right"},
{name:'isUsed',index:'isUsed', width:80, align:"right"}
],
rowNum:10,
rowList:[10,20,30],
pager: '#pjmap',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
jsonReader: {
repeatitems : false,
id: "0"
},
caption: "部门人员信息"
}).navGrid('#pjmap',{edit:false,add:false,del:false});
});
</script>
</head>
<body>
<table id="jsonmap" class="scroll" cellpadding="0" cellspacing="0"></table>
<div id="pjmap" class="scroll" style="text-align:center;"></div>
<!--
关于JQGrid的使用说明
1.jsp文件说明
请注意本文件中第一行的contentType="text/html; charset=UTF-8"这一句,这是解决中文问题的,非常重要。
请注意本文件中的<!DOCTYPE这一行代码,以及HTML行的代码,这是有xmlns验证的,如果没有这两句,显示出来的Table的样式非常难看!!
jquery-ui的字体大小与jqgrid字体大小不一致,故需要在页面上在加上一段style来指定页面上文字大小。
请注意,需要使用jqGrid,必须的js代码主要包括jquery以及jqGrid.min,另外就是jqGrid的语言包。其它的js代码是可选的,根据使用jqGrid的不同功能有所不同。
请注意,需要使用的css文件,jquery-ui-1.7.1.custom.css以及ui.jqgrid.css是必须的。其它的css是可选的,根据使用jqGrid的不同功能有所不同。
最后请注意,导航条,一定只能是一个DIV,不能是Table。比如本例子中的pjmap。
2.主方法jqGrid参数说明(上面例子中的参数,其它参数说明见doc目录下的文档)
$("#jsonmap").jqGrid({ //此处请注意#jsonmap,这是需要显示的Table的对象ID
url:'queryAllUsers.action', //请求的URL地址
datatype: "json", //服务器返回的数据类型,常用的是xml和json两种
postData: {depId: 1}, //提交的其他参数,比如查询条件。这里depId是参数名称,值可以通过$(#ID).val();来获取
colNames:['ID','姓名', '登录名', '部门ID','是否可用'], //表头显示的列名称
colModel:[ //这个属性是为每一个列设置属性的。非常重要
{name:'id',index:'id', width:90}, //具体的列属性,name必须有。index属性设置鼠标点击相应的表头的时候,排序的字段。这里还可以设置列是否可见,是否可编辑.....详细请参考文档
{name:'userName',index:'usrName', width:110},
{name:'loginName',index:'loginName', width:100},
{name:'dpCode',index:'dpCode', width:80, align:"right"},
{name:'isUsed',index:'isUsed', width:80, align:"right"}
],
rowNum:10, //默认的每页显示记录条数
rowList:[10,20,30], //可供用户选择的每页显示记录条数。
pager: '#pjmap', //pjmap是导航条对应的Div标签的ID,注意一定是DIV,不是Table
sortname: 'id', //默认的查询排序字段
viewrecords: true, //定义是否在导航条上显示总的记录数
sortorder: "desc", //默认的排序规则
jsonReader: { //jsonReader定义了一些期望返回数据的结构信息,通过修改这些参数定义,我们可以实现自己的Json数据格式,不用遵照JQGrid的默认规则(不熟悉的情况下,不建议修改)
repeatitems : false, //告诉JqGrid,返回的数据的标签是否是可重复的。This element tells jqGrid that the information for the data in the row is repeatable - i.e. the elements have the same tag cell described in cell element. Setting this option to false instructs jqGrid to search elements in the json data by name. This is the name from colModel or the name described with the jsonmap option in colModel。
id: "0" //每行数据的唯一标识。可以设置为空字符串或者一个数字。在这个例子中,表示每行数据的ID是返回数据的第一个字段。
},
caption: "部门人员信息" //显示表格的表名称
}).navGrid('#pjmap',{edit:false,add:false,del:false}); //navGrid是比较重要和常用的一个jqGrid方法。主要用来指示导航条的一些动作,包括设置整个Grid的编辑、删除、查询、导航的一些属性信息。详细参考文档Navgiation章节。
//更多更详细的参数以及说明,请参考本项目doc/JQuery & Plugin/jqGrid Document.doc.
3.服务器Struts的Action方法说明
假设使用Struts 2.0作为Web层框架,那么我们在Struts中的execute方法中,需要直接返回查询结果。
首先,Action需要获取jqGrid上传的一些参数,以下几个参数是jgGrid必须包括的参数:(可以在prmNames参数中设置这些参数的值为null,则不会在调用url的使用上传这些参数,当然,也可以自定义一些其他名字的参数。)
page :指示需要查询第几页的数据。
rows :指示每页显示的记录条数。
sidx :指示查询排序的条件,这是一个字符串,可能是数据库表字段或者是POJO对象的属性名。这需要程序来处理。
sord :指示查询排序的方式,可能的值是ASC和DESC
_search :用来指示是否是查询,值是true或者false。但是我测试了一下,比如这个例子中,刚开始访问页面的时候,_search=false。这个时候不管是点击哪一个表头排序,执行的动作,后台接收到的都是false。如果点击一下Navigation工具条最左边的查询按钮,执行一次查询动作,这个时候,_search就变成true了。包括之后,再去点击显示表头进行排序,其_search的结果都是true了。有点怪异!!!
nd :暂时没搞懂什么意思?
npage:暂时没搞懂什么意思?
其次,Action返回的xml或者json数据,有一些数据需要包含,主要包括
page:当前是第几页数据
total:总共有多少页数据
records:总的记录条数
服务器端代码示例:(execute方法或者是Struts.xml中配置的某些方法名称)
//假设查询结果是一个封装了查询List的POJO对象,注意,调用方法的参数,具有分页功能,分页参数,可以通过Struts2的Action属性自动获取
UserSearchTo to = this.service.findTo( page, rows, sidx, sord);
//封装成JSON对象返回,这里使用了json-lib包,要注意,这个包要用到几个其他的jar包,主要包括commons-lang 2.4、commons-beanutils 1.7.0、commons-collections 3.2、commons-logging 1.1.1以及ezmorph 1.0.6
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("text/json; charset=UTF-8"); //处理中文问题的必须的代码
PrintWriter out = response.getWriter();
JSONObject obj = new JSONObject();
obj.put("page", to.getPage()); //当前页
obj.put("total",to.getTotal()); //总页数
obj.put("records",to.getRecords()); //总记录数
JSONArray lineitemArray = new JSONArray();
for(User u:to.getUserList()){
JSONObject o = new JSONObject();
o.put("id", u.getId());
o.put("userName", u.getUsrName());
o.put("loginName", u.getLoginName());
o.put("dpCode", u.getDpCode());
o.put("isUsed", u.getIsUsed());
lineitemArray.add(o);
}
obj.put("rows", lineitemArray); //具体的Table显示内容
out.print(obj.toString());
服务器端代码示例:struts.xml配置片段
<action name="queryAllUser" class="brandAction" method="queryAllBrand">
<result name="success">/viewBrandGrid.jsp</result>
<result name="error">/viewBrandGrid.jsp</result>
<result name="input">/viewBrandGrid.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
-->
</body>
</html>
来源:oschina
链接:https://my.oschina.net/u/4347/blog/1905