自動完成 是 Web 應用高頻交互組件:用戶輸入字符 → 即時請求服務端匹配數據 → 下拉列表展示 → 用戶選中 → 回填輸入框。傳統實現需整合 jQuery UI / Select2 / Typeahead.js 等第三方庫,面臨 **JS 與 Java 端雙份邏輯、組件狀態管理、多實例衝突、安全性 (XSS/CSRF)、國際化、無障礙** 等挑戰。JSF 2 **復合組件** 機制提供了原生解決方案:
| 功能點 | 描述 | 技術實現 |
| 輸入觸發 | 用戶輸入 ≥ 2 字符 → 發送 Ajax 請求 | `onkeyup` + JS 防抖 (350ms) + `jsf.ajax.request` |
| 服務端過濾 | 前綴匹配 (忽略大小寫) → 返回匹配項 | `ValueChangeListener` + `UISelectItems.setValue()` |
| 下拉展示 | 絕對定位於輸入框下方、寬度自適應、最多 10 行 | JS 計算座標 → Ajax 參數 `x,y` → Java 動態設置 `style`、`size` |
| 選中回填 | 點擊/鍵盤選中 → 輸入框顯示完整值、列表隱藏 | 列表框 `onchange` → Ajax `render=input` → Java `input.setValue()` |
| 失焦隱藏 | 輸入框失焦 200ms 後隱藏列表 (防誤觸點擊) | `onblur` + `setTimeout(200ms)` + `Element.hide()` |
| 多實例共存 | 同頁多個自動完成組件互不干擾 | JSF `clientId` 命名空間 + 監聽器屬性映射隔離 |
| 數據源靈活 | 靜態列表 / JPA 實體 / REST API / 緩存 | `@ApplicationScoped` Bean 提供 `String[]`,可擴展介面 |
2. 架構設計:四層協同模型
┌─────────────────────────────────────────────────────────────┐
│ Facelet (autoComplete.xhtml) — 組件模板 │
│ • cc:interface 定義屬性 (value, completionItems) │
│ • cc:implementation 組合 HTML/JS/JSF 標籤 │
│ • 綁定 valueChangeListener → #{autocompleteListener.method} │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ JavaScript (autoComplete.js) — 交互觸發層 │
│ • updateCompletionItems: 防抖 + jsf.ajax.request(render=listbox, x,y) │
│ • inputLostFocus: 延遲隱藏列表框 │
│ • getListboxId: ClientId 推導算法 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Java Listener (AutocompleteListener) — 業務邏輯層 │
│ • valueChanged: 過濾完成項、更新列表模型、計算樣式/位置 │
│ • completionItemSelected: 回寫輸入框、隱藏列表 │
│ • 狀態隔離: 列表框屬性映射緩存原始數據 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Data Model (User + AutoComplete) — 數據層 │
│ • User @SessionScoped: 綁定 value (用戶選擇) │
│ • AutoComplete @ApplicationScoped: 提供 completionItems │
└─────────────────────────────────────────────────────────────┘
3. 關鍵技術棧版本
- JSF 2.0 / 2.1 / 2.2 (Mojarra 2.1+ / MyFaces 2.1+)
- Java EE 6 / 7 Web Profile (含 CDI 1.0/1.1/1.2)
- 容器:GlassFish 3.1+/4.x、Payara 4/5/6、WildFly 8+/10+/14+/18+、WebLogic 12c+、WebSphere 8.5+
- 構建:Maven / Gradle (無需特殊插件)
- IDE:Eclipse + GlassFish Tools / IntelliJ IDEA Ultimate / NetBeans
4. 系列文章規劃
- 需求分析與架構設計 (本文)
- Facelet 使用組件與運行效果
- 托管 Bean 與數據模型
- 復合組件定義 (autoComplete.xhtml) — 核心
- 前端 JavaScript 協同邏輯
- Java 端監聽器完整實現
- Eclipse + GlassFish 環境搭建
- Eclipse 專案配置與目錄結構
- Eclipse 部署 GlassFish 運行配置
- 運行驗證與總結
5. 參考資源
- JSF 2 規範 (JSR 314/344/372)
- 《Core JavaServer Faces》3rd Ed. — David Geary & Cay Horstmann
- Mojarra 專案: javaee.github.io/mojarra
- PrimeFaces / OmniFaces — 生產級組件庫參考實現
結語
JSF 2 復合組件將「自動完成」這類複雜交互組件的開發門檻從 **「框架級開發」降至「應用級組合」**。本系列將完整演示從零構建生產可用的自動完成組件,展示 JSF 2 在**組件化、Ajax化、可重用**三大維度的工程效能。下篇將展示 Facelet 中如何使用該組件及其運行效果。
- 上一篇文章: JSF 2 實作可重用 Ajax 自動完成組件 (二):Facelet 整合與測試
- 下一篇文章: Java EE 6 數據源定義新範式:註解與部署描述符雙軌制
Copyright ©
程式碼之家 All Rights Reserved