Java的Struts2框架配合Ext JS处理JSON数据的使用示例

前端技术 2023/09/08 Java

最近尝试用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提供的方法更方便。

本文地址:https://www.stayed.cn/item/20496

转载请注明出处。

本站部分内容来源于网络,如侵犯到您的权益,请 联系我

我的博客

人生若只如初见,何事秋风悲画扇。