Seam (JBoss Seam) 是 Java EE 5 整合框架,無縫銜接 JSF,彌補 JSF 原生不足。以下為實戰沉澱的 14 條核心心得。
- 引入 Seam PhaseListener,徹底解決異常追蹤盲區
原生 JSF 異常堆疊丟失、日誌難查。Seam 透過 PhaseListener 攔截全生命週期,無保留輸出完整異常堆疊,開發效率大增。無需 EJB3/JBoss,Servlet 容器 + Spring 即可運行。
- 精通 CSS 布局,打破「JSF 不適合複雜頁面」謬誤
JSF 強調語義結構而非表現樣式,符合 W3C 原意。拒絕 <table> 布局,善用 CSS Flex/Grid,複雜頁面同樣駕輕就熟。
- 謹慎使用
dataTable,它是 JSF 1.x 最大痛點
缺行級樣式控制、回退按鈕風險、分頁整合困難、幻影提交問題。JSF 1.2 引入統一 EL 支援 JSTL forEach,可作為補充方案。
- 模型 Bean 與業務 Bean 合二為一
頁面綁定同時完成業務數據封裝,直接交由服務層處理,消除 DTO 轉換層,利用 JSF 強大的綁定機制一氣呵成。
- 大量使用 Converter 組件,屏蔽頁面與服務層的類型轉換
例:單選框提交 int ID,Converter 負責「ID ⇄ 業務對象」雙向轉換,頁面與服務層只見對象不見原始值。
- MyFaces 跨頁參數傳遞組件,傳對象不傳值
利用 JSF 物件導向本質,跨頁傳遞完整模型對象,避免手工拼裝參數。
- 小心 Session 濫用,改用 Seam Conversation 管理狀態
表現層需有狀態,但 Session 易膨脹。Seam 長對話適配業務編輯流程,短對話填補 JSF 臨時數據易丟失問題。
- 自定義 PhaseListener 介入任意生命週期調試
實作 PhaseListener 接口,斷點掛在任意 Phase(RESTORE_VIEW, APPLY_REQUEST_VALUES 等),精準定位數據變更時刻。
- 分頁方案:DataModel 包裝分頁邏輯,注意與 @DataModel 互斥
參考 Steady 分頁方案,dataTable.value 綁定 DataModel 實例,但不可與 Seam @DataModel 共用。
- 整合 Ajax4jsf/RichFaces 必須用 Facelets + XHTML
非 XHTML 頁面會導致 AJAX 組件渲染失敗,項目伊始即確立 Facelets 模板引擎。
- dataTable 內單選框操作鏈:
immediate="true" + selectBooleanRadio
未選單選時仍允許鏈接/按鈕動作執行;務必用 selectBooleanRadio 而非 selectOneRadio,Checkbox 同理。
- GET 請求處理交給 Seam 組件(
@RequestParameter / pages.xml)
避免手工解析 Query String,Seam 內建支援 RESTful 風格導航。
- 非 Facelets 引入頁面必須純 JSF 組件樹,混合 HTML 會解析失敗
主頁面可混合 HTML + JSF 標籤(JSF 1.2 將混合 HTML 視為 output 組件),但被引入片段必須純組件化。
- 不要信「JSF 慢」謠言,樹狀組件遍歷已高度優化
系統慢多半是業務邏輯、SQL、緩存策略問題,而非框架本身。我的生產系統響應極快。
速查表:關鍵組件與註解
| 需求 | Seam/JSF 方案 |
| 異常全堆疊 | org.jboss.seam.jsf.SeamPhaseListener |
| 對話狀態管理 | @Begin / @End / @Conversational |
| 類型轉換 | 實作 javax.faces.convert.Converter + @Converter |
| AJAX 整合 | Facelets + RichFaces/PrimeFaces |
| GET 參數注入 | @RequestParameter 或 pages.xml param 配置 |