struts-menu 是老牌導航選單標籤庫,Struts 1 時代需在 struts-config.xml 註冊 PlugIn;Struts 2 僅需在 web.xml 註冊 ServletContextListener 即可載入 menu-config.xml。
<listener>
<listener-class>net.sf.navigator.menu.MenuContextListener</listener-class>
</listener>
<context-param>
<param-name>menuConfigLocation</param-name>
<param-value>/WEB-INF/menu-config.xml</param-value>
</context-param>
Listener 會在應用啟動時讀取配置,建立 MenuRepository 存入 ServletContext。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE menu-config PUBLIC
"-//JP Morgan//DTD Menu Configuration 1.0//EN"
"https://www.jpmorgan.com/dtd/menu-config_1_0.dtd">
<menu-config>
<menu name="main" title="主選單">
<item name="home" title="首頁" url="/web/index.action" />
<item name="userMgr" title="用戶管理" url="/web/user/list.action">
<item name="addUser" title="新增用戶" url="/web/user/add.action" />
<item name="editUser" title="編輯用戶" url="/web/user/edit.action" />
</item>
<item name="report" title="報表中心" url="/web/report/index.action" />
</menu>
</menu-config>
關鍵規則: 每個 <item> 的 name 屬性在同一 <menu> 內不可重複,否則渲染異常或拋出異常。
<%@ taglib prefix="menu" uri="https://struts-menu.sf.net/tags-menu" %>
<html>
<body>
<menu:menu name="main">
<menu:renderMenu /> <!-- 預設水平選單 -->
</menu:menu>
<!-- 或垂直樹狀 -->
<menu:menu name="main">
<menu:renderTree />
</menu:menu>
</body>
</html>
結合 <security:authorize> (Spring Security) 或自訂 Tag 判斷用戶角色,決定是否渲染特定 <item>。struts-menu 本身不內建權限,需自行擴充 MenuComponent 實作 isVisible()。
新專案建議改用前端框架(Vue/React + Ant Design/Vuetify)配合後端 REST API 動態獲取選單 JSON,徹底分離前後端。若維護舊系統,struts-menu 仍可穩定運行,只需注意 name 唯一性與 Listener 順序。