Struts 透過自定義 JSP 標籤庫,將表單處理、邏輯控制、國際化、模板佈局等繁瑣工作封裝為聲明式標籤,大幅簡化視圖層開發。本文系統梳理六大標籤庫核心功能、常用標籤與實戰場景。
| 標籤庫 | URI 前綴 | 核心職責 | 典型應用 |
|---|---|---|---|
| Bean | bean | Bean 存取、屬性輸出、訊息國際化 | <bean:write>、<bean:message>、<bean:define> |
| HTML | html | 表單生成、輸入驗證、錯誤顯示、超連結 | <html:form>、<html:text>、<html:errors> |
| Logic | logic | 條件判斷、迴代、比較、重導向 | <logic:iterate>、<logic:equal>、<logic:redirect> |
| Template | template | 頁面模板化(已由 Tiles 取代) | 歷史組件,不建議新專案使用 |
| Tiles | tiles | 版面佈局、組合、重用、動態頁面組裝 | <tiles:insert>、<tiles:definition> |
| Nested | nested | 巢狀 Bean 屬性存取,增強上述標籤巢狀能力 | <nested:write property="user.address.city"> |
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html locale="true">
<head><title><bean:message key="login.title"/></title></head>
<body>
<html:errors/> <!-- 顯示 ActionErrors -->
<html:form action="/LoginAction" method="post">
<table>
<tr>
<td><bean:message key="label.username"/></td>
<td><html:text property="username" size="20" maxlength="50"/></td>
</tr>
<tr>
<td><bean:message key="label.password"/></td>
<td><html:password property="password" size="20" maxlength="20"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<html:submit property="action" value="<bean:message key='btn.login'/>"/>
<html:reset value="<bean:message key='btn.reset'/>"/>
</td>
</tr>
</table>
</html:form>
</body>
</html:html>
關鍵優勢:
<html:errors> 統一顯示驗證錯誤,支援 CSS 樣式化<html:link>、<html:rewrite> 自動處理 Context Path,避免硬編碼 URL<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<!-- 輸出 Bean 屬性,自動處理 null、HTML 轉義 -->
<bean:write name="userForm" property="email" filter="true"/>
<!-- 國際化訊息,從 ApplicationResources.properties 讀取 -->
<bean:message key="welcome.msg" arg0="<bean:write name='user' property='name'/>"/>
<!-- 定義腳本變數,供後續標籤使用 -->
<bean:define id="userList" name="userForm" property="users" type="java.util.List"/>
<logic:iterate id="user" name="userList">
<bean:write name="user" property="name"/><br/>
</logic:iterate>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<!-- 條件判斷 -->
<logic:present name="userForm" property="admin">
<span class="badge">管理員</span>
</logic:present>
<logic:equal name="order" property="status" value="PAID">
<span class="success">已付款</span>
</logic:equal>
<!-- 集合迴代 -->
<logic:iterate id="item" name="cartForm" property="items" indexId="idx">
<tr class="<logic:equal name="idx" value="0">first</logic:equal>">
<td><bean:write name="item" property="name"/></td>
<td><bean:write name="item" property="price"/></td>
</tr>
</logic:iterate>
<!-- 重導向 -->
<logic:redirect forward="loginPage"/>
<!-- tiles-defs.xml -->
<definition name="baseLayout" template="/layouts/base.jsp">
<putAttribute name="header" value="/tiles/header.jsp"/>
<putAttribute name="menu" value="/tiles/menu.jsp"/>
<putAttribute name="body" value="/tiles/empty.jsp"/>
<putAttribute name="footer" value="/tiles/footer.jsp"/>
</definition>
<definition name="userMain" extends="baseLayout">
<putAttribute name="body" value="/pages/user/main.jsp"/>
</definition>
<definition name="adminMain" extends="baseLayout">
<putAttribute name="menu" value="/tiles/adminMenu.jsp"/>
<putAttribute name="body" value="/pages/admin/main.jsp"/>
</definition>
<%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
<html>
<body>
<table width="100%">
<tr><td colspan="2"><tiles:insert attribute="header"/></td></tr>
<tr>
<td width="200"><tiles:insert attribute="menu"/></td>
<td><tiles:insert attribute="body"/></td>
</tr>
<tr><td colspan="2"><tiles:insert attribute="footer"/></td></tr>
</table>
</body>
</html>
<action path="/userMain"
type="com.app.action.UserMainAction"
forward="userMain"/> <!-- 對應 tiles-defs.xml 定義名 -->
Tiles 核心價值:
ApplicationResources.properties(預設)、ApplicationResources_zh_TW.properties 等struts-config.xml 配置:<message-resources parameter="ApplicationResources"/><bean:message key="login.title"/>getResources(request).getMessage("error.login.failed")<global-exceptions>
<exception
type="java.lang.Exception"
handler="com.app.exception.GlobalExceptionHandler"
key="global.error.message"
path="/error.jsp"
scope="request"/>
</global-exceptions>
自訂 Handler 實作 ExceptionHandler 介面,execute() 方法中記錄日誌、轉向友善錯誤頁,避免暴露堆疊追蹤給用戶。
validate() 或 Validator 框架nested:) 處理複雜物件圖,如 property="order.customer.address.zip"Struts 六大標籤庫涵蓋表單、邏輯、資料輸出、國際化、版面佈局、巢狀存取全方位需求。掌握其核心標籤與組合模式,能讓 JSP 視圖層保持整潔、可維護、高重用。雖然 Struts 1 已進入維護模式,但其標籤庫設計哲學深深影響了後續 JSF、Spring MVC、Thymeleaf 等框架,理解其精髓有助於跨框架技術遷移。