本文提供一套完整的 JSP 動態樹實現方案:前端使用經典 tree.js 渲染交互,後端 MySQL 存儲節點數據,JSP 通過 DAO 查詢並動態生成 JS 初始化代碼。
[瀏覽器] ← tree.js (渲染/交互)
↑
[show_tree.jsp] ← 動態輸出 d.add(id, pid, name...)
↑
[TreeDAO] → [TreeNode Bean] → [MySQL trees 表]
CREATE DATABASE treedemo;
USE treedemo;
CREATE TABLE trees (
tid INT PRIMARY KEY, -- 節點 ID
pid INT NOT NULL, -- 父節點 ID (根節點 pid=-1)
tname VARCHAR(50) NOT NULL, -- 節點名稱
isleaf INT -- 0=父節點, 1=葉子節點
);
-- 示例數據
INSERT INTO trees VALUES (0,-1,'組織內容'), (1,0,'短信'), (2,0,'彩信'), (4,1,'移動生活'), ...;
TreeNode Bean:
public class TreeNode {
private int tid, pid, isleaf;
private String tname;
// getter/setter 省略
}
DBConn 工具類:
public class DBConn {
private static final String URL = "jdbc:mysql://localhost:3306/treedemo";
public Connection getConnection() { /* 標準 JDBC 獲取連接 */ }
}
TreeDAO:
public class TreeDAO {
public Vector getTree() {
Vector vec = new Vector<>();
try (Connection conn = new DBConn().getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM trees")) {
while (rs.next()) {
TreeNode n = new TreeNode();
n.setTid(rs.getInt("tid"));
n.setPid(rs.getInt("pid"));
n.setTname(rs.getString("tname"));
n.setIsleaf(rs.getInt("isleaf"));
vec.add(n);
}
} catch (SQLException e) { e.printStackTrace(); }
return vec;
}
}
Node 對象:保存 id, pid, name, url, icon 等屬性。tree 對象:管理節點集合、縮進圖標、Cookie 狀態持久化、展開/摺疊邏輯。add() 添加節點、toString() 生成 HTML、o(id) 切換展開狀態。<%@ page import="java.util.*, com.sx.mas.beans.*" %>
<SCRIPT src="js/tree.js"></SCRIPT>
<SCRIPT>
d = new tree('d','../'); // 實例化樹,圖片路徑前綴
<%
TreeDAO dao = new TreeDAO();
Vector vec = dao.getTree();
Iterator it = vec.iterator();
while (it.hasNext()) {
TreeNode n = it.next();
if (n.getIsleaf() == 0) { // 父節點
%>
d.add(<%=n.getTid()%>, <%=n.getPid()%>, '<%=n.getTname()%>');
<%
} else { // 葉子節點,帶鏈接
%>
d.add(<%=n.getTid()%>, <%=n.getPid()%>, '<%=n.getTname()%>',
parent.getUrlByCatalogId('<%=n.getTid()%>'), null, 'list');
<%
}
}
%>
document.write(d); // 輸出樹 HTML
</SCRIPT>
<FRAMESET cols="200,*">
<FRAME name="stree" src="show_tree.jsp" scrolling="yes" target="list">
<FRAME name="list" src="list_default.htm">
</FRAMESET>
左側樹框架 target="list" 確保點擊節點在右側框架打開內容。
| 層面 | 技術點 |
|---|---|
| 數據模型 | 遞歸結構 (id, pid) + isleaf 標識葉子 |
| 前端渲染 | tree.js 纯 JS 實現,無依賴,支援 Cookie 記憶狀態 |
| 動態綁定 | JSP 腳本塊輸出 JS 代碼,將服務端數組轉為客戶端調用 |
| 擴展性 | 可添加圖標、右鍵菜單、異步懶加載 (AJAX 獲取子節點) |
/api/tree/nodes?pid=xxx) 支援懶加載。sort_order 欄位控制同級節點順序。此方案雖屬經典模式,但完整展示了「服務端數據→模板輸出 JS 初始化→客戶端渲染」的全鏈路思維,理解其原理有助於掌握現代前後端分離架構的演變邏輯。