MVC 模式將應用程式分為三大核心角色:Model(模型/數據與業務邏輯)、View(視圖/用戶界面)、Controller(控制器/請求分發)。Struts 框架完整實現了這一架構,並將其映射至 Web 應用組件。
Struts 架構將 MVC 概念具體化為以下 Web 組件:
ActionServlet 與 ActionMappingModel 可細分為「內部狀態」(名詞)與「改變狀態的行為」(動詞)。通常以一組 JavaBeans 表示狀態,屬性對應狀態細節。根據應用複雜度,Beans 可為自包含型(自行持久化)或門面型(從外部數據源獲取數據)。大型應用常用 Entity EJBs 表示持久狀態。
業務邏輯行為可封裝在狀態 Beans 的方法中,或獨立的 Session EJBs 中。小型應用可將簡單邏輯置於 Action 類,但 Struts 建議將業務邏輯(做什麼)與 Action 類(決定做什麼)分離。
Struts 應用的 View 層主要基於 JSP 技術。JSP 包含靜態模板文本(HTML/XML)與動態內容(由標籤解析插入)。Struts 提供豐富的自定義標籤庫,便於構建國際化用戶界面,並與 ActionForm Beans 完美配合。
業務對象亦可根據當前狀態渲染 HTML/XML,透過 <jsp:include> 整合至 JSP 頁面。
Controller 集中接收客戶端請求,決定執行業務邏輯,再委派適當 View 組件生成響應。Struts 中的核心控制器為 ActionServlet,透過 ActionMapping 接口定義的映射集合進行配置。每個映射包含:匹配請求 URI 的路徑、負責業務邏輯的 Action 類全名。控制器將控制權轉交給 Action 類,執行完畢後再導向對應 View。
ActionMapping 支持擴展屬性,允許保存應用專屬信息;並支持邏輯名稱定義轉向目標,實現控制邏輯與顯示邏輯的解耦。
Model 組件開發聚焦於創建支撐所有功能需求的 JavaBeans 類。開發前需理解「作用域」概念,因其決定 Bean 的生命週期與可見性。
Web 應用中 JavaBeans 可存放於四種屬性集合,對應不同作用域:
| 作用域 | 說明 | Servlet API 對應 |
|---|---|---|
| page | 單一 JSP 頁面可見,生命週期限於當前請求 | service() 方法局部變量 |
| request | 單一 JSP 頁面及包含/轉向頁面可見 | Request 屬性 |
| session | 特定用戶會話中所有 JSP/Servlet 可見,跨請求 | Session 屬性 |
| application | 整個 Web 應用所有 JSP/Servlet 可見 | ServletContext 屬性 |
同一 Web 應用的 JSP 與 Servlet 共享相同 Bean 集合。例如 Servlet 中設定 request 屬性,轉向的 JSP 即可透過 <jsp:useBean> 獲取。
Struts 假定每個輸入請求對應一個 ActionForm Bean(實現 ActionForm 接口)。在 ActionMapping 配置後,Controller Servlet 自動執行:
<jsp:setProperty property="*">)perform() 方法編寫原則:
ActionForm 接口無需實現方法,僅作角色標識;通常僅含 getter/setter,不含業務邏輯ActionForm Bean 並提交至同一 Action實際業務狀態通常由一組 JavaBeans 表示。如購物車系統包含購物車 Bean(維護選購項目)、用戶信息 Bean、商品目錄 Bean 等。小型系統可全量駐留內存;大型系統常對應外部數據庫(如 CustomerBean 對應 CUSTOMERS 表),按需創建/清除,或使用 Entity EJBs。
功能邏輯應封裝於專門設計的 JavaBeans 方法中。為最大化復用,業務邏輯 Bean 應不依賴 Web 環境(避免 import javax.servlet.*)。Action 類(Controller)負責將 HTTP 請求轉換為業務 Bean 方法調用。根據複雜度,業務 Bean 可為普通 JavaBeans(配合 JDBC)或有狀態/無狀態 EJBs。
推薦模式:使用連接池(ConnectionPool)。啟動 Servlet 在 init() 中初始化連接池並存入 ServletContext(application 作用域);destroy() 中釋放資源。Action 類調用業務邏輯時:從池獲取連接 → 傳遞給業務方法 → 用完歸還池(即使拋出異常也必須在 finally 中歸還)。此模式使業務邏輯類與連接獲取邏輯解耦,便於在非 Web 環境(如批處理)復用。
聚焦於 JSP 技術構建 View,Struts 提供表單交互與國際化支持。
Web 應用常需支持多語言(i18n)與本地化。核心類:
java.util.Locale:代表特定國家/語言及格式假設java.util.ResourceBundle:多語言消息基礎工具PropertyResourceBundle:標準實現,支援 properties 文件格式java.text.MessageFormat:運行時參數替換消息佔位符({0}、{1}...)org.apache.struts.util.MessageResources:Struts 封裝,支援按 Locale 獲取消息資源文件命名慣例:基礎名.properties(默認語言)、基礎名_xx.properties(ISO 語言代碼)。在 web.xml 配置 Controller Servlet 時指定資源包基礎名。
傳統 HTML 表單處理繁瑣且易錯。Struts 提供基於 JSP 1.1 的自定義標籤庫大幅簡化:
<struts:text name="username"/>
框架自動從關聯 Bean 獲取初始值,無需顯式編碼。
完整登入頁面 Logon.jsp 展示核心特性:
taglib 指令引入標籤庫描述符message 標籤從 MessageResources 獲取國際化文本errors 標籤顯示業務邏輯保存的錯誤消息form 標籤渲染 <form> 並關聯 Session 作用域 FormBeantext/password 標籤渲染輸入框,自動綁定 Bean 屬性submit/reset 按鈕文本同樣國際化Struts 為所有 HTML 輸入類型提供標籤:checkbox、hidden、password、radio、reset、select/option、submit、text、textarea。所有字段標籤必須嵌套在 form 標籤內。
enumerate / iterate:遍歷集合(後者支援 Java 2 Collection API)getProperty:獲取 Bean 屬性作為 page 作用域 BeanifAttributeExists/Missing、ifParameterEquals/NotEquals/NotNull/Null:條件渲染link:生成超鏈接,無 Cookie 時自動 URL 重寫維持 Sessionparameter:安全輸出請求參數property:顯示唯讀 Bean 屬性實現 ValidatingActionForm 接口(擴展 ActionForm),新增 validate() 方法:
null 或空數組,Controller 繼續調用 ActionActionMapping 的 inputForm 指定)此特性為可選,若僅實現 ActionForm 則假定驗證由 Action 類負責。
除 Struts 內建標籤外,可創建應用專屬標籤。示例應用包含:checkLogon(檢查會話、未登入導向登入頁)、linkSubscription、linkUser(生成攜帶鍵值的超鏈接)。
單一 JSP 構建完整頁面屬常見做法,但門戶類應用常需組合多個邏輯獨立片段(搜索、新聞、討論、郵件提示等)。可透過 JSP include 機制組裝:
<%@ include file="..." %>):編譯期處理,適合靜態片段<jsp:include page="..." flush="true" />):請求期處理,支援條件包含動態生成圖表(如股價走勢)常用兩法:
Content-Type: image/gif 直接輸出Controller 相關職責:編寫 Action 類、ActionMapping 實現、action.xml 配置、更新 web.xml、添加 Struts 組件。
實現 Action 接口,核心方法:
public ActionForward perform(ActionServlet servlet,
ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
典型 perform() 邏輯:驗證 Session/登入狀態 → 表單驗證(若未自動驗證) → 執行業務處理(建議調用業務 Bean) → 更新服務端對象(request/session 作用域 Bean) → 返回 ActionForward 指向下一個 JSP。
設計要點:
servlet.log())ActionMapping 接口封裝映射元數據:actionClass、formAttribute、formClass、path。Struts 提供便利基類 ActionMappingBase;可擴展添加自定義屬性(如示例應用的 failure、success 邏輯名),使 Action 類與具體 JSP 頁面名解耦。
action.xml)基於 XML 配置,Struts Digester 模塊解析並創建映射對象。文件放置於 WEB-INF/action.xml,根元素 <action-mappings> 包含多個 <action>。示例:
<action-mappings>
<forward name="Logon" path="/Logon.jsp"/>
<action path="/Logon"
actionClass="org.apache.struts.example.LogonAction"
formAttribute="LogonForm"
formClass="org.apache.struts.example.LogonForm"
inputForm="/Logon.jsp">
<forward name="success" path="/mainMenu.jsp"/>
</action>
</action-mappings>
<forward> 定義邏輯名,Action 類透過 mapping.findForward() 獲取。全局 forward 定義在 <action> 外部,供所有 Action 共享。
web.xml)<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>org.apache.struts.example.ApplicationResources</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/action.xml</param-value>
</init-param>
<init-param><param-name>debug</param-name><param-value>2</param-value></init-param>
<init-param><param-name>mapping</param-name><param-value>org.apache.struts.example.ApplicationMapping</param-value></init-param>
<load-on-startup>2</load-on-startup>
</servlet>
主要初始化參數:application(資源包基類)、config(映射文件路徑)、debug、mapping(ActionMapping 實現類)、nocache、null(未知消息鍵行為)。
兩種常用 URL 模式:
<url-pattern>/execute/*</url-pattern> → https://host/context/execute/Logon<url-pattern>*.do</url-pattern> → https://host/context/Logon.do(示例應用採用)<taglib>
<taglib-uri>/WEB-INF/struts.tld</taglib-uri>
<taglib-location>/WEB-INF/struts.tld</taglib-location>
</taglib>
將 struts.tld 複製至 WEB-INF,struts.jar 複製至 WEB-INF/lib。