最近尝试用extjs来展示树状菜单。着实花了一番功夫。树状菜单的菜单项需要动态加载,而目前版本的extjs中只支持JSON格式的数据。查了一些资 料,决定使用struts2的json-plugin。首先按照例子做了一个,但是结果就是不成功,界面上只出来了一个js中生成的root节点,不能加 载从后台生成的数据。研究后发现是数据格式有问题。使用json-plugin生成的数据格式如下:
1
|
{ "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需要的数据格式如下:
1
|
[{ "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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<? 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<? 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)
1
2
3
4
5
6
7
|
public class Menu {
private int id;
private String text;
private boolean leaf;
private String cls;
private List<Menu> children;
}
|
4. action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
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
1
2
|
<%@ 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
/*
* 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数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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数据内容
1
2
|
{ "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两种格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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提供的方法更方便。