| 維度 | Struts (MVC) | JSF (事件驅動組件) |
|---|---|---|
| 事件觸發單位 | 整個表單 → Action.execute()(Command 模式) | 單一組件(輸入框、按鈕)→ Listener 回調 |
| 事件粒度 | 粗粒度 | 細粒度 |
| 綁定方式 | ActionForm 對應整張表單 | 組件直接綁定 Bean 屬性 #{bean.prop} |
| 值變更監聽 | 需 JS 繞道或全表單提交 | <f:valueChangeListener> 原生支援 |
| 動作監聽 | <html:submit> 提交 | <f:actionListener> 掛載按鈕 |
| 編程風格 | Web 化(HTML 表單思維) | 語言化(類 Swing 事件模型) |
<h:inputText id="userId" value="#{login.userId}">
<f:valueChangeListener type="logindemo.UserLoginChanged" />
</h:inputText>
用戶修改 userId 失焦/提交即觸發 UserLoginChanged.processValueChanged(),無需提交整張表單。
單純 Struts 無法直接實現字段級事件,需結合 JavaScript/AJAX 繞道實現。
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
與 Struts ActionServlet 映射 *.do 一模一樣。
faces-config.xml vs struts-config.xml<faces-config>
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/welcome.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.corejsf.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value>me</value> <!-- IoC Setter 注入 -->
</managed-property>
</managed-bean>
</faces-config>
navigation-rule 獨立定義頁面流轉,比 Struts 混雜在 ActionMapping 中更清晰;managed-bean 內建 IoC/依賴注入(Setter 注入),Struts 需外掛 Spring。一個 Backing Bean 聚合多個 Managed Bean,統一 Scope 管理:
<managed-property>
<property-name>visit</property-name>
<value>#{sessionScope.visit}</value> <!-- 引用 Session 級 Bean -->
</managed-property>
程式碼只操作 visit 對象,底層儲存位置(Session/Request/Application)完全由配置決定。
<logic:present name="auth" property="inboxAuthorized">
<html:link action="inbox">InBox</html:link>
</logic:present>
<jia:navigatorItem name="inbox" label="InBox"
icon="/images/inbox.gif" action="inbox"
disabled="#{!authenticationBean.inboxAuthorized}"/>
disabled 屬性直接綁定 EL 表達式,條件為假自動隱藏/禁用,零邏輯標籤巢狀。