Java的Struts2框架配合Ext JS处理JSON数据的使用示例
最近尝试用extjs来展示树状菜单。着实花了一番功夫。树状菜单的菜单项需要动态加载,而目前版本的extjs中只支持json格式的数据。查了一些资 料,决定使用struts2的json-plugin。首先按照例子做了一个,但是结果就是不成功,界面上只出来了一个js中生成的root节点,不能加 载从后台生成的数据。研究后发现是数据格式有问题。使用json-plugin生成的数据格式如下:
{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"s600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"slk200"}],"text":"benz"}
而extjs需要的数据格式如下:
[{"cls":"folder","id":10,"leaf":false,"children":[{"cls":"file","id":11,"leaf":true,"children":null,"text":"s600"},{"cls":"file","id":12,"leaf":true,"children":null,"text":"slk200"}],"text":"benz"}]
区别很小,就只相差最外面的两个方括号。但是少了这两个方括号,在json中,含义迥然不同,前者表示一个对象,而后者表示一个数组。而extjs中 tree的dataloader需要的数据必须是一个数组。而这样的数据格式是json-plugin自动生成的,无法改变。所以,我最后放弃了json -plugin,转而使用json-lib来解决这个问题。
1. 下载json-lib, http://json-lib.sourceforge.net/
2. lib目录下的jar文件清单:
commons-beanutils-1.7.0.jar
commons-collections-3.2.jar
commons-digester-1.6.jar
commons-lang-2.3.jar
commons-logging-1.1.jar
dom4j-1.6.1.jar
ezmorph-1.0.4.jar
freemarker-2.3.8.jar
javassist-3.8.1.jar
json-lib-2.2.1-jdk15.jar
log4j-1.2.13.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xml-apis-1.0.b2.jar
xwork-2.0.4.jar
首先配置web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filterdispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
然后是struts.xml
<?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"/> <constant name="struts.i18n.encoding" value="utf-8"/> <package name="person" extends="struts-default"> <action name="menus" method="execute" class="com.lab.menuaction"> <result>/menu.jsp</result> </action> </package> </struts>
3. 树的节点模型(省略了getter,setter)
public class menu { private int id; private string text; private boolean leaf; private string cls; private list<menu> children; }
4. action
package com.lab; import java.util.arraylist; import java.util.list; import net.sf.json.jsonarray; public class menuaction { private string menustring; private list<menu> menus; public string execute() { menus = new arraylist<menu>(); menu benz = new menu(); benz.settext("benz"); benz.setcls("folder"); benz.setleaf(false); benz.setid(10); menus.add(benz); list<menu> benzlist = new arraylist<menu>(); benz.setchildren(benzlist); menu menu; menu = new menu(); menu.settext("s600"); menu.setcls("file"); menu.setleaf(true); menu.setid(11); benzlist.add(menu); menu = new menu(); menu.settext("slk200"); menu.setcls("file"); menu.setleaf(true); menu.setid(12); benzlist.add(menu); menu bmw = new menu(); bmw.settext("bmw"); bmw.setcls("folder"); bmw.setleaf(false); bmw.setid(20); menus.add(bmw); list<menu> bmwlist = new arraylist<menu>(); bmw.setchildren(bmwlist); menu = new menu(); menu.settext("325i"); menu.setcls("file"); menu.setleaf(true); menu.setid(21); bmwlist.add(menu); menu = new menu(); menu.settext("x5"); menu.setcls("file"); menu.setleaf(true); menu.setid(22); bmwlist.add(menu); jsonarray jsonobject = jsonarray.fromobject(menus); try { menustring = jsonobject.tostring(); } catch (exception e) { menustring = "ss"; } return "success"; } public string getmenustring() { return menustring; } public void setmenustring(string menustring) { this.menustring = menustring; } }
5. menu.jsp
<%@ taglib prefix="s" uri="/struts-tags" %> <s:property value="menustring" escape="false"/>
6. html页面和js
我使用的就是extjs的example中的reorder.html和reorder.js,更改了reorder.js中treeloader的dataurl: menus.action
<html> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> <title>reorder treepanel</title> <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" /> <!-- gc --> <!-- libs --> <script type="text/javascript" src="extjs/adapter/ext/ext-base.js"></script> <!-- endlibs --> <script type="text/javascript" src="extjs/ext-all.js"></script> <script type="text/javascript" src="reorder.js"></script> <!-- common styles for the examples --> <link rel="stylesheet" type="text/css" href="extjs/resources/css/example.css" /> </head> <body> <script type="text/javascript" src="../examples.js"></script><!-- examples --> <h1>drag and drop ordering in a treepanel</h1> <p>this example shows basic drag and drop node moving in a tree. in this implementation there are no restrictions and anything can be dropped anywhere except appending to nodes marked "leaf" (the files). <br></p> <p>drag along the edge of the tree to trigger auto scrolling while performing a drag and drop.</p> <p>in order to demonstrate drag and drop insertion points, sorting was <b>not</b> enabled.</p> <p>the data for this tree is asynchronously loaded with a json treeloader.</p> <p>the js is not minified so it is readable. see <a href="reorder.js">reorder.js</a>.</p> <div id="tree-div" style="overflow:auto; height:300px;width:250px;border:1px solid #c3daf9;"></div> </body> </html>
js:
/* * ext js library 2.0.1 * copyright(c) 2006-2008, ext js, llc. * licensing@extjs.com * * http://extjs.com/license */ ext.onready(function(){ // shorthand var tree = ext.tree; var tree = new tree.treepanel({ el:'tree-div', autoscroll:true, animate:true, enabledd:true, containerscroll: true, loader: new tree.treeloader({ dataurl:'http://localhost:8080/lab/menus.action' }) }); // set the root node var root = new tree.asynctreenode({ text: 'ext js', draggable:false, id:'source' }); tree.setrootnode(root); // render the tree tree.render(); root.expand(); });
7.解析为list数据
代码如下:
extjs中的json数据
var combostore = new ext.data.store({ proxy: new ext.data.httpproxy({ url:'admingroup', //这里是struts请求到action method:'post' //请求方式 }), reader: new ext.data.jsonreader({ //总记录数 totalproperty: 'results', //总记录数 root: 'items', //记录集合 id:'roleid' }, ['roleid','rolename'] //显示的两个字段 ) });
json数据内容
{"items":[{"password":"ahui","adminid":1,"role":{"rolename":"系统管理员","roleid":2,"sequence":"2","admin":null,"logoutmark":"否"},"adminname":"ahui","logout":"否"}, {"password":"xiao","adminid":2,"role":{"rolename":"系统管理员","roleid":2,"sequence":"2","admin":null,"logoutmark":"否"},"adminname":"xiao","logout":"是"},"results":13}
下面是struts2里面的action代码 里面封装了exthelper工具类,里面有转换xml和json两种格式
public string findall() throws exception{ httpservletrequest request = servletactioncontext.getrequest(); httpservletresponse response = servletactioncontext.getresponse(); list list = groupservice.getgroup(); //调用service里面的方法,把所有的数据都查询出来 string json = exthelper.getjsonfromlist(list);//把list转换为json格式的数据 response.setcontenttype("text/json;charset=utf-8");//设置数据到前台显示的字符编码,如果不转会有乱码 response.getwriter().write(json); system.out.println(json); return null; }
解析json的方法有很多,所以是怎么方便怎么来,json自己的包里也可以进行转换,但如果项目中用的是struts2,直接用struts2提供的方法更方便。