在J2EE開發中不可避免會使用的樹(Tree),通常狀況有二種實現方式,第一種是初始化的時候將樹信息就所有加載到內存中,這種方式適用於小數據或者性能要求不高的狀況,優勢是加載完後對服務器就不會有壓力而且打開樹節點速度快;第二種是數據異步加載即ajax技術,每次都加載少許的必須的數據,這種方式適用於大量數據和性能要求較高的狀況;咱們作爲軟件設計和開發者都但願軟件性能最佳、用戶體驗最好;javascript
目前網上介紹struts2 ajax tree的實例不少但就是不太全面、完整,就連struts官方網站都沒有完整實例;下面我來介紹一下struts2 ajax tree的使用方法及技巧,這個實例所有引用自jdframe開發框架中的組織機構管理功能源碼:css
1. jsp頁面html
首先JSP要引用,其次在<head>中包含< sx:head/>java
<%@ 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>
<?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代碼 node
AjaxDynamicTreeAction.java
ajax
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.javaapache
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; } }
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; } }