最近嘗試用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. * * 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提供的方法更方便。