JavaServer Faces (JSF) 作為 Java Web 應用程式的第一個標準化 UI 框架,正憑藉其標準地位主導市場。然而 JSF 核心規格明確指出:JSF 並非設計為完整的 Web 應用框架,而是提供健全的事件驅動 API 與 UI 元件庫,供更複雜的應用框架建構之用。許多開發者在實際專案中發現,純 JSF 開發面臨狀態管理、RESTful URL、異常處理、書籤支援、過度 XML 配置等諸多挑戰。
JBoss Seam 作為建構在 JSF 基礎之上的全方位應用框架,精準補足了 JSF 的不足,兩者構成開發 Java 企業應用的黃金組合。本文為三部曲系列首篇,深入探討 Seam 如何增強 JSF 生命週期,涵蓋上下文狀態管理、RESTful URL、Ajax remoting、異常處理與慣例優於配置等核心優勢。
Seam 開發團隊(特別是 Gavin King)經過大量實戰驗證,從一開始就攻克 Web 應用框架的核心難題:上下文狀態管理、RESTful 友善 URL、Ajax remoting、適當異常處理、慣例優於配置。Seam 不僅滿足所有需求,更提供超越預期的功能。若您正使用 JSF 卻未聽聞 Seam,強烈建議研讀其參考文件——隨附手冊即是最佳教材。
流傳較廣的誤解認為「Seam 必須搭配 EJB 3 使用」或「需要 EJB 3 容器」。事實上 Seam 文件明確闢謠:「Seam 不要求元件為 EJB,甚至在無相容 EJB 3.0 容器時也能使用。」正如 Spring 不強制要求 Hibernate、Hibernate 不強制要求 Spring,兩者互補但不相依。Seam 可完美搭配 POJO 於 Servlet 容器(如 Tomcat)運行,僅需 JDK 5 註解支援。

將 Seam 整合至專案極為簡單,無需重新學習 JSF 生命週期。僅需:
org.jboss.seam.servlet.SeamListenerorg.jboss.seam.jsf.SeamPhaseListenerseam.properties 檔案(觸發 Seam 掃描元件,並優化載入效能)
Seam 另提供 Servlet Filter 擴展非 JSF 請求整合、Conversation 傳播、檔案上傳管理等功能。EJB 3 整合需額外配置,詳見參考文件。
相較傳統 JSF 在 faces-config.xml 定義 Managed Bean,Seam 僅需在類別加上 @Name 註解即可暴露至 JSF 生命週期,Seam 自動管理元件可見性與生命週期。核心在於「雙射」——結合注入與注出的雙向資料流:
@Out:將屬性資料注出,視圖可透過名稱存取@In:於 postback 或元件初始化時注入資料,實現控制反轉 (IoC)@Factory:定義資料工廠方法,延遲初始化並快取結果@DataModel/@DataModelSelection:支援資料表格選取操作@Name("addressManager")
public class AddressManagerBean {
@DataModel private List<Address> addresses;
@DataModelSelection @Out(required = false) private Address selectedAddress;
@Factory(value = "addresses")
public void loadAddress() { /* 載入邏輯 */ }
public String showDetail() { return "/address.jspx"; }
public String list() { return "/addresses.jspx"; }
}
透過 @In("#{addressService}") 可將 Spring 容器管理的服務層 Bean 注入 Seam 元件,支援輕量級容器部署架構。

Java 5 註解提供程式碼層級中繼資料,Seam 部署掃描器自動識別標有 @Name 的類別建立元件,徹底解決 JSF 大量 XML 配置的痛點,減少維護檔案數量。
JSF 被動式控制器無法預先處理請求,導致書籤支援、RESTful URL、安全驗證等基於動作框架的常見需求難以實現。Seam 頁面動作於 Render Response 階段前執行,透過 /WEB-INF/pages.xml 或 *.page.xml 配置方法綁定與請求參數映射,支援導航結果判斷。內建 s:link/s:button 產生 HTTP GET 連結,完美支援書籤與 RESTful URL(如 /faces/product/show/10)。
JSF 缺乏可靠的視圖渲染前資料準備機制,getter 重複調用導致效能問題。Seam @Factory 註解定義資料提供者,確保資料首次請求時準備一次,後續直接回傳快取結果,結合 Conversation 作用域實現短期資料快取。
JSF 狀態管理缺陷:JSF 僅還原元件樹,不還原綁定資料。請求/頁面作用域資料在 Restore View 階段消失,導致「虛幻事件效應」(UIData 臨時父元件導致事件遺失)。過度依賴 HTTP Session 造成記憶體洩漏、叢集親和性問題、多標籤瀏覽器行為異常。
Seam Conversation 作用域:由頁面流程起止界定的狀態作用域,綁定瀏覽器視窗/分頁(透過請求提交的 Token 識別),使用 HTTP Session 獨立區段儲存資料,自動管理生命週期並於 Conversation 結束時清理。雙射機制讓資料在各頁面間自然流動,徹底解決 HTTP Session 限制。
JSF 完全忽略異常管理,拋給 Servlet 容器導致錯誤頁面資訊受限、無法交易回滾。Seam 提供 @HttpError、@Redirect、@ApplicationException 註解與 XML 配置,支援 HTTP 狀態碼、重導向、頁面渲染、Conversation 終止、自訂使用者訊息,配合頁面動作確保異常於渲染前解決。
JSF 規格與 Ajax 幾乎同步發布,缺乏非同步支援。Seam 提供類 DWR 但更強大的 Remoting:@WebRemote 註解讓 JavaScript 直接呼叫伺服器元件方法,存取豐富上下文元件模型,配合 Ajax4JSF 實現局部渲染,符合 Swing 事件驅動範式,零開發負擔。
JSR 299 (Web Beans) 表決結果顯示,Seam 核心理念將成未來 Java EE 標準。即使無標準化進程,Seam 以最小設定成本解決 JSF 開發最棘手的問題,回報遠超投入。本系列後續將繼續深入探討 Seam 進階應用與最佳實踐。