在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;
- }
- }
应用效果:
原网址:http://blog.csdn.net/china_melancholy/article/details/19540689