首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 與 Struts 整合的三種核心方案深度解析

     編輯:Java 相關知識

Spring 與 Struts 都是 Java EE 開發中極具代表性的框架,兩者皆對 MVC 模式提供完善支援。Struts 專注於 Web 層的控制器實作,而 Spring 則以輕量級容器管理業務邏輯組件見長。在實際專案中,開發者常採用 Struts 處理表現層,Spring 管理服務層與資料層,因此兩者的整合成為必要課題。

整合核心原理:Action 實例交由 Spring 容器管理

整合關鍵在於將 Struts 中 Action 的實例化控制權移交給 Spring 容器。這要求 Struts 的核心控制器 ActionServlet 能夠載入 Spring 的應用程式上下文。Spring 提供的 org.springframework.web.struts.ContextLoaderPlugin 完美支援此需求。只需在 struts-config.xml 中註冊該外掛即可:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE struts-config PUBLIC
 "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
 "https://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
 ...
 <plug-in className="org.springframework.web.struts.ContextLoaderPlugin">
 <set-property property="contextConfigLocation" value="/WEB-INF/config.xml"/>
 </plug-in>
 ...
</struts-config>

其中 config.xml 為 Spring 的設定檔,定義業務邏輯 Bean 等資源。

三種整合方案對比

方案一:Action 繼承 ActionSupport(最簡單但耦合度最高)

讓 Struts Action 繼承 Spring 的 ActionSupport 類別,並在 Action 中透過 getWebApplicationContext() 取得 Spring 上下文。

缺點:

  • Struts 與 Spring 緊密耦合,難以替換為其他 IoC 容器
  • 無法善用 Spring AOP 等進階特性
  • 不支援 DispatchAction 等 Struts 進階功能

方案二:使用 DelegatingRequestProcessor(解耦容器但依賴 Struts 核心類)

在 struts-config.xml 中以 Spring 的 DelegatingRequestProcessor 取代 Struts 預設的 RequestProcessor,並在 Spring 設定檔定義對應 <action-mappings> 的 Bean。

優點: 不再依賴特定 IoC 容器實作。
缺點: 仍強依賴 Struts 的 RequestProcessor 類別。

方案三:使用 DelegatingActionProxy 代理(最靈活、推薦方案)

在 Struts 設定檔中,將所有 <action-mappings> 的 type 屬性設為 org.springframework.web.struts.DelegatingActionProxy,而非具體 Action 類別名。Action 的實際實作類別在 Spring 設定檔中定義,由 Spring 容器完整管理其生命週期與依賴注入。

此方案將 Struts Action 完全納入 Spring 控制,支援 AOP、事務管理等所有 Spring 特性,且不綁定特定 IoC 容器實作,是最佳實踐選擇。

實戰範例:DelegatingActionProxy 整合步驟

Step 1:修改 struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "https://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="helloWorld" type="com.strutstest.action.HelloWorld"/>
</form-beans>
<action-mappings>
<!-- 關鍵:type 指定為 DelegatingActionProxy -->
<action path="/helloWorld" type="org.springframework.web.struts.DelegatingActionProxy" name="helloWorld" validate="true" input="/WEB-INF/jsp/input.jsp">
<forward name="index" path="/WEB-INF/jsp/index.jsp"/>
<forward name="show" path="/WEB-INF/jsp/show.jsp"/>
</action>
<action path="/input" type="org.apache.struts.actions.ForwardAction" parameter="/WEB-INF/jsp/input.jsp"/>
</action-mappings>
<!-- 註冊 ContextLoaderPlugin -->
<plug-in className="org.springframework.web.struts.ContextLoaderPlugin">
<set-property property="contextConfigLocation" value="/WEB-INF/config.xml" />
</plug-in>
<message-resources parameter="messages"/>
</struts-config>

Step 2:修改 Spring 設定檔 config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="helloWorldService" class="com.strutstest.service.impl.HelloWorldServiceImpl">
</bean>
<!-- Bean 名稱必須與 Struts action path 完全對應 -->
<bean name="/helloWorld" class="com.strutstest.action.HelloWorldAction">
<property name="helloWorldService">
<ref bean="helloWorldService"/>
</property>
</bean>
</beans>

Step 3:定義 Model 層(ActionForm、Service 介面與實作)

ActionForm 類別:

package com.strutstest.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;

public class HelloWorld extends ActionForm {
    private String msg = null;
    public void setMsg(String msg) { this.msg = msg; }
    public String getMsg() { return this.msg; }
    public void reset(ActionMapping mapping, HttpServletRequest req) { this.msg = null; }
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();
        if("".equals(getMsg())) {
            errors.add("msg", new ActionError("error"));
        }
        return errors;
    }
}

Service 介面:

package com.strutstest.service;
import com.strutstest.action.HelloWorld;
public interface HelloWorldService {
    public abstract String addMsg(HelloWorld helloWorld);
}

Service 實作:

package com.strutstest.service.impl;
import com.strutstest.action.HelloWorld;
import com.strutstest.service.HelloWorldService;
public class HelloWorldServiceImpl implements HelloWorldService {
    public String addMsg(HelloWorld helloWorld) {
        helloWorld.setMsg("Hello World... " + helloWorld.getMsg());
        return helloWorld.getMsg();
    }
}

Step 4:定義 Action 類別(由 Spring 管理,支援依賴注入)

package com.strutstest.action;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import com.strutstest.service.HelloWorldService;

public class HelloWorldAction extends Action {
    private HelloWorldService helloWorldService;
    // Setter 注入
    public void setHelloWorldService(HelloWorldService helloWorldService) {
        this.helloWorldService = helloWorldService;
    }
    public HelloWorldService getHelloWorldService() {
        return helloWorldService;
    }
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        String msg = getHelloWorldService().addMsg((HelloWorld)form);
        request.setAttribute("helloWorld", msg);
        return mapping.findForward("show");
    }
}

Step 5:定義視圖層 JSP

input.jsp - 使用者輸入頁:

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@page contentType="text/html;charset=GBK"%>
<html:html locale="true">
<head><title><bean:message key="title"/></title><html:base/></head>
<html:messages id="msg"><bean:write name="msg"/></html:messages>
<body>
<form name="HelloWorld" action="/myStruts/helloWorld.do" method="post">
<bean:message key="welcome"/><input type="text" name="msg" value=""/><br>
<input type="submit" name="method" value="<bean:message key='submit'/>"/>
</form>
</body></html:html>

show.jsp - 結果顯示頁:

<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@page contentType="text/html;charset=GBK"%>
<html:html locale="true">
<head><title><bean:message key="title"/></title><html:base/></head>
<body bgcolor="white">
<html:errors/>
<html:messages id="msg"><bean:write name="msg"/></html:messages>
<%
String str = (String)request.getAttribute("helloWorld");
%>
<body>
<font color="blue">
<bean:message key="input"/>"${helloWorld}"<br>
</font>
</body>
</html:html>

總結

透過 DelegatingActionProxy 方案,Struts Action 成為 Spring 容器管理的普通 Bean,完整享有依賴注入、AOP、宣告式事務等 Spring 核心優勢,同時保持 Struts 處理 Web 請求流程的優勢。這是 Spring 與 Struts 整合的最佳實踐模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved