Spring 與 Struts 都是經典 Java Web 框架,整合兩者可發揮 Spring IOC 容器管理業務邏輯元件、Struts 處理表現層的優勢。本文詳細說明三種主流整合方式、配置步驟與優缺點比較,並推薦最佳實踐。
在 struts-config.xml 加入外掛,載入 Spring 應用程式上下文:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
確保 applicationContext.xml 位於 WEB-INF 目錄下。
org.springframework.web.struts.ActionSupport 繼承自 Struts Action,提供 getWebApplicationContext() 取得 Spring 容器。
public class LoginAction extends org.springframework.web.struts.ActionSupport {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;
WebApplicationContext ctx = getWebApplicationContext();
LoginDao dao = (LoginDao) ctx.getBean("loginDao");
// ... 業務邏輯 ...
}
}
<beans>
<bean id="loginDao" class="com.cao.dao.LoginDao"/>
</beans>
以 Spring 的 DelegatingRequestProcessor 取代 Struts 預設 RequestProcessor,攔截 Action 建立過程,自動將 Spring Bean 注入 Action 的 setter 屬性。
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>
public class LoginAction extends Action { // 繼承原生 Struts Action
private LoginDao dao; // 提供 setter/getter
public void setDao(LoginDao dao) { this.dao = dao; }
public ActionForward execute(...) {
// 直接使用 dao,無需手動取得 Context
}
}
<beans>
<bean id="loginDao" class="com.cao.dao.LoginDao"/>
<bean name="/login" class="com.cao.struts.action.LoginAction">
<property name="dao"><ref local="loginDao"/></property>
</bean>
</beans>
name="/login" 對應 Struts <action path="/login",class 對應 type。
RequestProcessor(如編碼處理),會與 DelegatingRequestProcessor 衝突。Action 的建立與依賴注入完全交給 Spring IOC 容器,Struts 僅透過 DelegatingActionProxy 代理轉發請求給 Spring 管理的 Action Bean。
<action-mappings>
<action path="/login"
type="org.springframework.web.struts.DelegatingActionProxy"
name="loginForm" scope="request" input="login.jsp">
<forward name="success" path="/ok.jsp"/>
<forward name="error" path="/error.jsp"/>
</action>
</action-mappings>
type 指向 Spring 代理類,而非實際 Action 類。<controller> 設定(不再需要 DelegatingRequestProcessor)。<beans>
<bean id="loginDao" class="com.cao.dao.LoginDao"/>
<bean name="/login" class="com.cao.struts.action.LoginAction">
<property name="dao"><ref local="loginDao"/></property>
</bean>
</beans>
| 方式 | 耦合度 | 擴充性 | 推薦指數 |
|---|---|---|---|
| 1. ActionSupport | 高 | 低 | ⭐⭐ |
| 2. DelegatingRequestProcessor | 中 | 中 | ⭐⭐⭐ |
| 3. 全權委托 | 低 | 高 | ⭐⭐⭐⭐⭐ |
struts-config.xml(加入外掛、設定 controller 或 action type)。applicationContext.xml(定義業務 Bean、Action Bean 及注入關係)。雖然三種方式皆可達成整合,但全權委托最能發揮 Spring IOC 容器優勢,實現表現層與業務層的徹底解耦,也是官方文件與社群公認的最佳實踐。建議新專案直接採用方式三。