在J2EE开发中不可避免会使用的树(Tree),一般情况有二种实现方式,第一种是初始化的时候将树信息就全部加载到内存中,这种方式适用于小数据或者性能要求不高的情况,优点是加载完后对服务器就不会有压力并且打开树节点速度快;第二种是数据异步加载即ajax技术,每次都加载少量的必须的数据,这种方式适用于大量数据和性能要求较高的情况;我们做为软件设计和开发者都希望软件性能最佳、用户体验最好;
目前网上介绍struts2 ajax tree的实例很多但就是不太全面、完整,就连struts官方网站都没有完整实例;下面我来介绍一下struts2 ajax tree的使用方法及技巧,这个实例全部引用自jdframe开发框架中的组织机构管理功能源码:
1. jsp页面
首先JSP要引用,其次在<head>中包含< sx:head/>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>JDFrame System Organization Tree</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<meta content="MSHTML 6.00.2600.0" name=GENERATOR>
<link rel="stylesheet" type="text/css" href="/css/sys/main.css">
<style type="text/css">
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
SCROLLBAR-FACE-COLOR: #37b0dd;
SCROLLBAR-HIGHLIGHT-COLOR:#ffffff;
SCROLLBAR-SHADOW-COLOR: #ffffff;
SCROLLBAR-3DLIGHT-COLOR:0099cc;
SCROLLBAR-ARROW-COLOR:#1c6787;
SCROLLBAR-TRACK-COLOR:#ddfdfd;
SCROLLBAR-DARKSHADOW-COLOR:#1c6787;
}
</style>
<sx:head/>
</head>
<body>
<script language="JavaScript" type="text/javascript">
dojo.event.topic.subscribe("treeSelected", function treeNodeSelected(node) {
dojo.io.bind({
url: "<s:url value='/com/jdframe/sys/core/org/treeSelected.action'/>?nodeId="+node.node.widgetId,
load: function(type, data, evt) {
var divDisplay = dojo.byId("displayId");
divDisplay.innerHTML=data;
},
mimeType: "text/html"
});
window.parent.showOrg(node.node.widgetId);
});
</script>
<s:url id="nodesUrl" namespace="/com/jdframe/sys/core/org" action="getNodes" />
<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td valign="top" id="td_tree">
<div style="float:left; margin-right: 50px;">
<sx:tree id="dorg_tree" href="%{#nodesUrl}" treeSelectedTopic="treeSelected" />
</div>
</td>
</tr>
</table>
</body>
</html>
2. Struts2配置文件
<?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>
<package name="organiztion" namespace="/com/jdframe/sys/core/org" extends="struts-default" >
<action name = "getNodes" class= "com.jdframe.sys.biz.org.DynamicTreeAction">
<result type="freemarker">/sys/core/frame/treeAjaxDynamic.ftl</result>
</action>
<action name = "treeSelected" method="selectTreeNode" class= "com.jdframe.sys.biz.org.DynamicTreeAction">
<result>/sys/core/org/tree.jsp</result>
</action>
...
3. java代码
AjaxDynamicTreeAction.java
package com.jdframe.sys.core.model.tree;
import com.jdframe.sys.core.action.JdframeAction;
import com.jdframe.sys.core.model.tree.Category;
// TODO: Auto-generated Javadoc
/**
* The Path : com.jdframe.sys.core.model.tree.AjaxDynamicTreeAction.java
* The AjaxDynamicTreeAction
* Last-Modified-Time : 2014-2-20 10:44:11
*
* @author support@jdframe.com
* @version 2.0.3.0
* http://www.jdframe.com
* @see
*/
public abstract class AjaxDynamicTreeAction extends JdframeAction {
//default value
/** The node id. */
protected String nodeId = null;
//for ftl
/** The category. */
public Category category;
/* (非 Javadoc)
* <p>Title: perform</p>
* <p>Description: </p>
* @return
* @see com.jdframe.sys.core.action.JdframeAction#perform()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.action.JdframeAction#perform()
*/
@Override
protected abstract String perform();
/**
* Select tree node.
*
* @return the string
*/
public abstract String selectTreeNode() ;
/* (非 Javadoc)
* <p>Title: validators</p>
* <p>Description: </p>
* @see com.jdframe.sys.core.action.JdframeAction#validators()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.action.JdframeAction#validators()
*/
@Override
protected abstract void validators() ;
/* (非 Javadoc)
* <p>Title: initial</p>
* <p>Description: </p>
* @return
* @see com.jdframe.sys.core.action.JdframeAction#initial()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.action.JdframeAction#initial()
*/
@Override
protected abstract String initial() ;
/**
* Gets the category.
*
* @return the category
*/
public Category getCategory() {
return category;
}
/**
* Sets the category.
*
* @param category the new category
*/
public void setCategory(Category category) {
this.category = category;
}
/**
* Gets the node id.
*
* @return the node id
*/
public String getNodeId() {
return nodeId;
}
/**
* Sets the node id.
*
* @param nodeId the new node id
*/
public void setNodeId(String nodeId) {
this.nodeId = nodeId;
}
/**
* Gets the node name.
*
* @return the node name
*/
public String getNodeName() {
return category != null ? category.getName() : "Node not found";
}
}
业务处理类:DynamicTreeAction.java
package com.jdframe.sys.biz.org;
import com.jdframe.sys.core.model.User;
import com.jdframe.sys.core.model.tree.AjaxDynamicTreeAction;
// TODO: Auto-generated Javadoc
/**
* The Path : com.jdframe.sys.biz.org.DynamicTreeAction.java
* The DynamicTreeAction
* Last-Modified-Time : 2014-2-20 9:55:53
*
* @author support@jdframe.com
* @version 2.0.3.0
* http://www.jdframe.com
* @see
*/
public class DynamicTreeAction extends AjaxDynamicTreeAction {
/* (非 Javadoc)
* <p>Title: perform</p>
* <p>Description: </p>
* @return
* @see com.jdframe.sys.core.action.JdframeAction#perform()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.model.tree.AjaxDynamicTreeAction#perform()
*/
@Override
protected String perform() {
// TODO Auto-generated method stub
User user = this.getUserProfileFromSession().getUser();
CategoryImpl cat = new CategoryImpl();
if(nodeId == null ){
nodeId = user.getUser_zzjg_dm();
category = cat.getRootById(nodeId);
}else{
category = cat.getById(nodeId);
}
return SUCCESS;
}
/**
* Select tree node.
*
* @return the string
*/
public String selectTreeNode() {
// TODO Auto-generated method stub
//category = OrgCategory.getInstance().getById(nodeId);
CategoryImpl cat = new CategoryImpl();
category = cat.getById(nodeId);
return SUCCESS;
}
/* (非 Javadoc)
* <p>Title: validators</p>
* <p>Description: </p>
* @see com.jdframe.sys.core.action.JdframeAction#validators()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.model.tree.AjaxDynamicTreeAction#validators()
*/
@Override
protected void validators() {
// TODO Auto-generated method stub
}
/* (非 Javadoc)
* <p>Title: initial</p>
* <p>Description: </p>
* @return
* @see com.jdframe.sys.core.action.JdframeAction#initial()
*/
/* (non-Javadoc)
* @see com.jdframe.sys.core.model.tree.AjaxDynamicTreeAction#initial()
*/
@Override
protected String initial() {
// TODO Auto-generated method stub
return null;
}
}
TREE对象类: Category.java
package com.jdframe.sys.core.model.tree;
import java.util.*;
// TODO: Auto-generated Javadoc
/**
* The Path : com.jdframe.sys.core.model.Category.java
* The Class Category.
* Last-Modified-Time : 2013-12-25 21:32:41
*
* @author support@jdframe.com
* @see
* @version 2.0.3.0 www.jdframe.com
*/
public abstract class Category {
/** The id. */
protected String id;
/** The name. */
protected String name;
/** The children. */
protected List children;
/** The cat map. */
public Category(){}
/**
*
* Title: getById
* Description: TODO(返回包含下级节点的树,初始化后展开节点时执行,一般情况下id为为当前选中的节点)
* @param
* @return Category
*
*/
public abstract Category getById(String id);
/**
*
* Title: getRootById
* Description: TODO(返回包含当前节点的树,初始化时执行,一般情况下id为空)
* @param
* @return Category
*
*/
public abstract Category getRootById(String id);
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Sets the name.
*
* @param name the new name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the children.
*
* @return the children
*/
public List getChildren() {
return children;
}
/**
* Sets the children.
*
* @param children the new children
*/
public void setChildren(List children) {
this.children = children;
}
}
TREE对象类: CategoryImpl.java
package com.jdframe.sys.biz.org;
import java.util.*;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import com.jdframe.sys.core.model.tree.Category;
import com.jdframe.sys.core.util.DbUtils;
import com.jdframe.sys.dao.model.T_sys_organization;
// TODO: Auto-generated Javadoc
/**
* The Path : com.jdframe.sys.biz.org.CategoryImpl.java
* The CategoryImpl
* Last-Modified-Time : 2014-2-20 21:33:19
* @author support@jdframe.com
* @version 2.0.3.0
* http://www.jdframe.com
* @see
*/
public class CategoryImpl extends Category {
/** The log. */
Logger log = Logger.getLogger(CategoryImpl.class);
/**
* Instantiates a new category impl.
*/
public CategoryImpl(){
}
/**
* Instantiates a new category impl.
*
* @param id the id
* @param name the name
* @param children the children
*/
public CategoryImpl(String id, String name, CategoryImpl... children) {
//super(id, name, children);
this.id = id;
this.name = name;
this.children = new ArrayList<CategoryImpl>();
for (CategoryImpl child : children) {
this.children.add(child);
}
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see com.jdframe.sys.core.model.tree.Category#getById(java.lang.String)
*/
@Override
public CategoryImpl getById(String sj_dm){
SqlSession session = DbUtils.buildSqlSession();
CategoryImpl root_cat = null;
try{
List<T_sys_organization> all = session.selectList("getSubOrgByDm",sj_dm);
List allCategory = new ArrayList();
for (int j = 0; j < all.size(); j++) {
CategoryImpl self_category = null;
String self_code = all.get(j).getZzjg_dm();
String self_name = all.get(j).getZzjg_name();
List<T_sys_organization> l = session.selectList("getSubOrgByDm",self_code);
List subCategory = new ArrayList();
for (int i = 0; i < l.size(); i++) {
String _code = l.get(i).getZzjg_dm();
String _name = l.get(i).getZzjg_name();
subCategory.add(new CategoryImpl(_code,_name));
}
if(subCategory.size()>0){
CategoryImpl[] childr = new CategoryImpl[subCategory.size()];
for (int i = 0; i < subCategory.size(); i++) {
if(subCategory.get(i) instanceof CategoryImpl){
childr[i] = (CategoryImpl)subCategory.get(i);
}
}
self_category = new CategoryImpl(self_code,self_name,childr);
}else{
self_category = new CategoryImpl(self_code,self_name);
}
allCategory.add(self_category);
}
CategoryImpl[] allchildr = new CategoryImpl[allCategory.size()];
if(allCategory.size()>0){
for (int i = 0; i < allCategory.size(); i++) {
if(allCategory.get(i) instanceof CategoryImpl){
allchildr[i] = (CategoryImpl)allCategory.get(i);
}
}
root_cat = new CategoryImpl("-1","Root",allchildr);
}else{
root_cat = new CategoryImpl("-1","Root");
}
//if(sj_dm.equals("76300000000")){
// root_cat = self_category;
//}
}finally{
if(session!=null)session.close();
}
return root_cat;
}
/* (non-Javadoc)
* @see com.jdframe.sys.core.model.tree.Category#getRootById(java.lang.String)
*/
@Override
public CategoryImpl getRootById(String id) {
// TODO Auto-generated method stub
SqlSession session = DbUtils.buildSqlSession();
CategoryImpl root_cat = null;
try{
List<T_sys_organization> all = session.selectList("getOrgBySwjgDm",id);
List allCategory = new ArrayList();
for (int j = 0; j < all.size(); j++) {
CategoryImpl self_category = null;
String self_code = all.get(j).getZzjg_dm();
String self_name = all.get(j).getZzjg_name();
List<T_sys_organization> l = session.selectList("getSubOrgByDm",self_code);
List subCategory = new ArrayList();
for (int i = 0; i < l.size(); i++) {
String _code = l.get(i).getZzjg_dm();
String _name = l.get(i).getZzjg_name();
subCategory.add(new CategoryImpl(_code,_name));
}
if(subCategory.size()>0){
CategoryImpl[] childr = new CategoryImpl[subCategory.size()];
for (int i = 0; i < subCategory.size(); i++) {
if(subCategory.get(i) instanceof CategoryImpl){
childr[i] = (CategoryImpl)subCategory.get(i);
}
}
self_category = new CategoryImpl(self_code,self_name,childr);
}else{
self_category = new CategoryImpl(self_code,self_name);
}
allCategory.add(self_category);
}
CategoryImpl[] allchildr = new CategoryImpl[allCategory.size()];
if(allCategory.size()>0){
for (int i = 0; i < allCategory.size(); i++) {
if(allCategory.get(i) instanceof CategoryImpl){
allchildr[i] = (CategoryImpl)allCategory.get(i);
}
}
root_cat = new CategoryImpl("-1","Root",allchildr);
}else{
root_cat = new CategoryImpl("-1","Root");
}
}finally{
if(session!=null)session.close();
}
return root_cat;
}
}
应用效果:
来源:oschina
链接:https://my.oschina.net/u/931066/blog/202413