Struts 與 JSF 雖同屬表現層框架,但核心架構截然不同:Struts 採用傳統 MVC + Command 模式,JSF 則是事件驅動的組件模型。本文從事件粒度、配置方式、托管 Bean 與導航機制等維度深度對比。
<form> 對應一個 Action(或 DispatchAction),屬於 Application Event,粒度較粗。若需針對單一表單欄位觸發邏輯,需配合 JavaScript 繞彎實現。<h:inputText id="userId" value="#{login.userId}">
<f:valueChangeListener type="logindemo.UserLoginChanged"/>
</h:inputText>
<h:commandButton id="login" action="login">
<f:actionListener type="logindemo.LoginActionListener"/>
</h:commandButton>
觀察者模式讓事件處理更貼近 Swing 等桌面開發習慣。兩者在 web.xml 中均註冊核心 Servlet 並映射 URL 模式:
<!-- Struts -->
<servlet><servlet-name>action</servlet-name><servlet-class>org.apache.struts.action.ActionServlet</servlet-class></servlet>
<servlet-mapping><servlet-name>action</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
<!-- JSF -->
<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-config.xml | faces-config.xml |
|---|---|---|
| 表單/資料載體 | <form-bean> (ActionForm) | <managed-bean> (支援 IoC/DI) |
| 導航規則 | <action> + <forward> | <navigation-rule> + <navigation-case> |
| 事件驅動 | 不支援 | 原生支援 ValueChange/Action 事件 |
JSF 的 managed-bean 不僅對應 Struts 的 ActionForm,更融入了依賴注入(IoC),可聲明 managed-property 實現 Bean 間關聯注入,功能更強大。
JSF 將「事件結果」與「目標視圖」解耦:
<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>
頁面按鈕 <h:commandButton action="login"/> 直接對應 from-outcome,導航邏輯集中管理,優於 Struts 分散在各 Action 的 mapping.findForward()。