ExtJs在struts2.0.x上实现动态树的解决方案
ExtJs在struts2.0.x下实现动态树的解决方案
最近因开始学习ExtJs要求在struts2下做一个动态树,因为之前配置环境的时候用的struts为2.0.14版本较老,从而发现在http://bill-xing.iteye.com/blog/743883这套解决方案中有一个问题,就是struts2.0.x使用的json-plugin只能是0.32的版本,没有wrapPrefix和wrapSuffix这两个方法,故生成的json型数据依然会有缺少[]的问题。
通过研究struts返回结果类型,发现stream类型除了用于下载以外,还可以用于ajax等异步通信,于是考虑通过手动组装json数据并通过stream返回的方法来做动态树,过程如下。
数据库设计,其中link为假定树中每个叶子节点的链接。
pojo设计,要点是子节点的创建。
dao设计,这里只给出其dao接口的impl实现
这个方法可结合spring进行改进,但为了示例清晰,只采用了hibernate最基本的数据库调用方法将存好的示例以树形结构拿出。其中返回结果为一个list。
相应的action如下。
这里要特别注意编码方式统一的问题,否则乱码。需统一的部分有:1、前台页面 2、当前class页面 3、inputStream 4、数据库表中相关列。 我这里统一采用了utf-8。
struts.xml配置
ext代码,名为sample.js
最后在html页面上调用就大功告成了。
效果图
最近因开始学习ExtJs要求在struts2下做一个动态树,因为之前配置环境的时候用的struts为2.0.14版本较老,从而发现在http://bill-xing.iteye.com/blog/743883这套解决方案中有一个问题,就是struts2.0.x使用的json-plugin只能是0.32的版本,没有wrapPrefix和wrapSuffix这两个方法,故生成的json型数据依然会有缺少[]的问题。
通过研究struts返回结果类型,发现stream类型除了用于下载以外,还可以用于ajax等异步通信,于是考虑通过手动组装json数据并通过stream返回的方法来做动态树,过程如下。
数据库设计,其中link为假定树中每个叶子节点的链接。
CREATE TABLE `functionlist` ( `id` int(10) NOT NULL, `name` varchar(20) default NULL, `link` varchar(100) default NULL, `parent` int(10) default NULL, PRIMARY KEY (`id`), KEY `parent` (`parent`), CONSTRAINT `functionlist_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `functionlist` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
pojo设计,要点是子节点的创建。
package com.test.pojos; import java.io.Serializable; import java.util.Set; public class functionList implements Serializable{ private int id; private String name; private String link; private functionList parent; private Set<functionList> children = new java.util.HashSet<functionList>(); //省略getter setter方法 public functionList(){} public functionList(String name,String link,functionList parent){ this.name = name; this.link = link; if(parent!=null){ this.children.add(parent); } } }
dao设计,这里只给出其dao接口的impl实现
package com.test.DAO; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.test.pojos.functionList; public class functionListDaoImpl implements functionListDao { public functionListDaoImpl() {} @Override public List<functionList> findRoot() { // TODO Auto-generated method stub Configuration configuration = new Configuration(); configuration.configure("hibernate.cfg.xml"); SessionFactory sessionFactory = configuration.buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction trans = session.beginTransaction(); String sqlQuery="from functionList where parent is null"; Query query =session.createQuery(sqlQuery); List<functionList> rootList = (List<functionList>)query.list(); // for(functionList funL : rootList) // { // System.out.println(funL.getName()); // System.out.println(funL.getLink()); // } trans.commit(); session.close(); return rootList; } }
这个方法可结合spring进行改进,但为了示例清晰,只采用了hibernate最基本的数据库调用方法将存好的示例以树形结构拿出。其中返回结果为一个list。
相应的action如下。
package com.test.action; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; import com.opensymphony.xwork2.ActionSupport; import com.test.DAO.functionListDao; import com.test.DAO.functionListDaoImpl; import com.test.pojos.functionList; public class func extends ActionSupport{ private InputStream inputStream; public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String execute() throws Exception { functionListDao dao = new functionListDaoImpl(); List<functionList> rootList = dao.findRoot(); //手动拼装数据库中取得的功能树,使其成为一个符合json格式的String String json = "["; for(functionList funl1 : rootList) { String root = "{text:'"+funl1.getName()+"',"; if(funl1.getChildren()!=null) { System.out.println("主节点"+funl1.getName()+"的子节点为:"); String children="children:["; for(functionList funl2 : funl1.getChildren()) { String child = "{text:'"+funl2.getName()+"',id:'"+funl2.getId()+"',href:'"+funl2.getLink()+"',leaf:true},"; System.out.println(funl2.getName()); children =children+child; } children = children.substring(0, children.length()-1); root = root+children+"]},"; } json = json+root; } json = json.substring(0, json.length()-1); json = json+"]"; System.out.println(json); // 注意:StringInputStream对中文的支持有问题,这里最好采用ByteArrayInputStream ByteArrayInputStream is = new ByteArrayInputStream(json.getBytes("utf-8")); inputStream = is; return SUCCESS; } }
这里要特别注意编码方式统一的问题,否则乱码。需统一的部分有:1、前台页面 2、当前class页面 3、inputStream 4、数据库表中相关列。 我这里统一采用了utf-8。
struts.xml配置
<!-- 提取功能树 --> <action name="stream" class="com.test.action.func"> <result type="stream"> <param name="contentType">text/html</param> <param name="inputName">inputStream</param> </result> </action>
ext代码,名为sample.js
Ext.onReady(function(){ var mytree=new Ext.tree.TreePanel({ el:"container", animate:true, title:"Extjs动态树 功能列表", collapsible:true, rootVisible:false, autoScroll:true, autoHeight:true, width:250, lines:true, //, root:new Ext.tree.AsyncTreeNode({ }), loader:new Ext.tree.TreeLoader({dataUrl:'stream.action'}) }); mytree.render(); })
最后在html页面上调用就大功告成了。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> <link rel="stylesheet" type="text/css" href="js/ext/resources/css/ext-all.css"> <script type="text/javascript" src="js/ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="js/ext/ext-all.js"></script> <script type="text/javascript" src="js/ext/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="js/sample.js"></script> </head> <body> <div id="container"></div> </body> </html>
效果图