傳統 JSP 開發的三大痛點
- 邏輯與顯示耦合:HTML 與 Java 代碼混雜,頁面設計師與工程師互相干擾。
- 腳本不可重用:大量複製貼上,版本分歧,除錯困難。
- 缺乏組件模型:無標準 UI 元件庫,每專案重複造輪子 (表格、驗證、AJAX)。
JSF 核心定位:Java Web UI 標準框架
- JCP 標準 (JSR 127/252/314/344/372):多廠商實現 (Mojarra、MyFaces),避免廠商鎖定。
- 組件為中心:可重用、可擴展、事件驅動的伺服器端 UI 元件模型。
- 工具友善:支援 RAD 可視化拖拉拽開發 (IBM RAD、Oracle JDeveloper、NetBeans、Eclipse)。
- 完整 MVC:View (Facelets/JSP) + Model (Managed Bean) + Controller (FacesServlet + Navigation)。
- 渲染器分離:元件邏輯與輸出編碼 (HTML、WML、JSON) 解耦,支援多裝置。
JSF 兩大核心構件
| 部分 | 內容 |
| Java API | UIComponent 階層、狀態管理、事件處理、驗證/轉換、國際化、無障礙支援 |
| 標籤庫 | Facelets (標準) / JSP 標籤,聲明式構建視圖樹 |
架構三層職責詳解
1. View (視圖) —— Facelets 頁面
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://xmlns.jcp.org/jsf/html"
xmlns:f="https://xmlns.jcp.org/jsf/core">
<h:head><title>登入</title></h:head>
<h:body>
<h:form>
<h:outputLabel for="username" value="帳號:"/>
<h:inputText id="username" value="#{userBean.username}" required="true"/>
<h:message for="username"/>
<h:outputLabel for="password" value="密碼:"/>
<h:inputSecret id="password" value="#{userBean.password}" required="true"/>
<h:message for="password"/>
<h:commandButton value="登入" action="#{userBean.login}"/>
</h:form>
</h:body>
</html>
- 純標記,零 Java 代碼。
- EL 表達式
#{bean.property} 雙向綁定。
- 內建驗證 (
required、validator) 與訊息顯示 (h:message)。
2. Model (模型) —— Managed Bean
@Named
@RequestScoped // 或 @ViewScoped, @SessionScoped, @ApplicationScoped
public class UserBean implements Serializable {
private String username, password;
// getter/setter
public String login() {
if (userService.authenticate(username, password)) {
return "dashboard?faces-redirect=true"; // 導航規則
}
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("帳號或密碼錯誤"));
return null; // 留在當前頁
}
}
- 純 POJO,無框架基類依賴 (JSF 2.0+)。
- CDI 整合 (
@Named、@Inject) 實現依賴注入。
- 作用域精準控制:請求、視圖、會話、應用、流程、自定義。
3. Controller (控制器) —— FacesServlet + 導航
- FacesServlet:單一前端控制器,攔截
*.faces/*.xhtml,執行完整生命週期 (Restore View → Apply Request Values → Process Validations → Update Model Values → Invoke Application → Render Response)。
- 導航規則:
faces-config.xml 或隱式導航 (Action 方法回傳字串)。
- 攔截器/PhaseListener:橫切關注點 (安全、日誌、事務) 插入生命週期各階段。
開發流程三步驟
- 視圖設計:RAD 工具拖拉元件、綁定 Bean 屬性、設定驗證/轉換、定義 Action。
- 模型設計:實作 Managed Bean 業務邏輯、注入 Service/EJB、定義作用域。
- 控制器配置:
web.xml 宣告 FacesServlet、faces-config.xml 定義導航/轉換器/驗證器/攔截器。
JSF 核心優勢總結
| 優勢 | 說明 |
| 真正 MVC 分離 | View 無邏輯,Model 無視圖感知,Controller 統一調度 |
| 組件生態豐富 | PrimeFaces、RichFaces、ICEfaces、ButterFaces、OmniFaces 提供百款開箱即用元件 |
| 標準化與可移植 | 遵循 JSR,可在 Mojarra/MyFaces 間切換,支援 Java EE / Jakarta EE 全棧 |
| 工具支援極佳 | 可視化設計、屬性編輯器、EL 自動完成、頁面預覽 |
| 渲染器可插拔 | 同一元件樹可輸出 HTML、JSON、PDF、Email、行動端標記 |
| 狀態管理自動化 | 伺服器/客戶端狀態儲存,支援集群複制、部分狀態保存 (JSF 2.2+) |
擴展性與現代化演進
- 自定義元件:繼承
UIComponentBase、撰寫 Renderer、註冊於 faces-config.xml。
- Facelets 模板化:
ui:composition、ui:define、ui:include 構建頁面繼承體系。
- JSF 2.3+ 新特性:WebSocket 整合 (
f:websocket)、類型安全 EL、CDI 完整對齊、JSON 處理、空值友善。
- 前後端分離趨勢:JSF 可作為「BFF (Backend for Frontend)」輸出 JSON,配合 React/Vue/Angular 構建現代 SPA,或使用 JSF 內建 AJAX (
f:ajax) 實現傳統豐富應用。
總結
JSF 以「標準化組件模型、完整 MVC、工具優先、渲染器分離」四大支柱,解決了 Java Web UI 開發長期存在的分離、重用、效率難題。雖面臨前端框架衝擊,但在企業級表單密集型應用、內部管理系統、受監管行業 (需審計追蹤、標準合規) 中,JSF 仍具備不可替代的工程化優勢。掌握 JSF,即掌握了 Java EE/Web Profile 視圖層的標準範式。