SpringMVC與Struts2對比教學

SpringMVC 和 Struts2 就像武林中的兩大門派,雖然都是處理 Web 請求的高手(MVC 框架),但招式風格和內功心法大不相同。來,咱們用最接地氣的方式掰扯掰扯,保準你笑著記住!

核心區別一句話概括:

Struts2 像是個 “中央集權” 的大家長,啥事兒都得經過它規定的流程(攔截器棧);SpringMVC 則像是個 “自由靈活” 的居委會,搭好平臺讓大家(各種組件)按約定自己玩兒(依賴注入+IoC),它主要當個協調員(DispatcherServlet)。

詳細版 “找不同” (帶段子和例子):

  1. 出身和 “靠山”:

    • Struts2: 是 Struts1 和 WebWork 的 “混血兒”。它自己就是一個獨立的、完整的 MVC 框架,像一家自給自足的 “家族企業”。
    • SpringMVC: 是 Spring 這個龐大 “生態帝國” 的親兒子!它天生就和 Spring 的核心功能(IoC, AOP, 事務管理等)無縫集成,就像帝國里的 “皇太子”,資源豐富,調用其他部門(Spring Bean)超級方便。
    • 段子時刻: 面試官問 Struts2:“你爸是誰?” Struts2:“我自成一家!” 問 SpringMVC:“你爸是誰?” SpringMVC 驕傲一指:“看!那邊那個叫 Spring 的超級大佬就是我爹!我出門辦事刷他臉就行!”
  2. 核心控制器 (Front Controller - “門衛大爺”):

    • Struts2: FilterDispatcher (老版本) 或 StrutsPrepareAndExecuteFilter (新版本)。它是一個強大的過濾器(Filter)。所有請求都得先過它這關,它負責整個請求生命周期的調度,權力很大。
    • SpringMVC: DispatcherServlet。它是一個標準的 Servlet。它更像一個總協調員,收到請求后自己不干所有活,而是把任務分派給其他組件(HandlerMapping, Controller, ViewResolver 等)。
    • 類比: Struts2 的門衛大爺不光看門,還兼任登記、查包裹、甚至幫你把快遞送到家門口。SpringMVC 的門衛大爺就負責登記來訪者(請求)是誰,然后喊:“小王(HandlerMapping),查下這人去哪屋!小李(Controller),3號屋的客人來了,你接待一下!老張(ViewResolver),客人要看資料,你幫忙找找!”
  3. 控制器 (Controller - “業務處理員”):

    • Struts2: Action 類。通常需要繼承特定的基類(如 ActionSupport)。Action 類本身在 Struts2 中默認是多例的(每次請求創建一個新實例)。
    • SpringMVC: @Controller 注解標記的類(或者實現 Controller 接口,但注解方式更流行)。不需要繼承特定類,就是一個普通的 POJO (Plain Old Java Object)。控制器方法用 @RequestMapping 等注解標記。SpringMVC 的控制器默認是單例的(由 Spring IoC 容器管理),更輕量高效。
    • 例子 & 類比:
      • Struts2 Action:
        public class LoginAction extends ActionSupport {private String username; // 屬性!自動封裝請求參數private String password;public String execute() throws Exception {// 業務邏輯if ("admin".equals(username) && "123456".equals(password)) {return SUCCESS; // 返回字符串結果,對應struts.xml里的result} else {return ERROR;}}// Getter/Setter 必須!用于參數封裝
        }
        
        像是一個有固定工位和固定任務清單(繼承 ActionSupport 帶來的功能) 的員工。每次來新活(請求),就克隆一個新員工來處理(多例)。
      • SpringMVC Controller:
        @Controller
        @RequestMapping("/user")
        public class UserController {@Autowiredprivate UserService userService; // 輕松注入其他Spring管理的Bean!@GetMapping("/login") // 更精細的映射public String login(@RequestParam String username, @RequestParam String password, Model model) {// 業務邏輯,通常調用Serviceboolean success = userService.authenticate(username, password);if (success) {model.addAttribute("message", "登錄成功!");return "welcome"; // 返回視圖名} else {model.addAttribute("error", "用戶名或密碼錯誤!");return "login";}}
        }
        
        像一個自由職業者,掛靠在 Spring 平臺(@Controller)。平臺給他派活(@RequestMapping 指定他能接什么活)。他干活需要的工具(UserService),平臺直接提供(@Autowired 依賴注入)。他本身是個固定員工(單例),高效復用。
  4. 請求參數處理 (“收快遞”):

    • Struts2: 主要依賴屬性封裝! 在 Action 類中定義與請求參數同名的屬性,并提供 public 的 getter/setter 方法。Struts2 會利用 OGNL (Object-Graph Navigation Language) 自動把請求參數塞到這些屬性里。也可以使用 ModelDriven 接口封裝到模型對象。耦合性相對較高(Action 類里一堆屬性)。
    • SpringMVC: 方式超級靈活!
      • 方法參數綁定: 直接在控制器方法參數列表聲明,用注解指定來源:
        • @RequestParam:獲取單個請求參數。
        • @PathVariable:獲取 RESTful 風格的 URL 路徑變量。
        • @RequestBody:獲取請求體內容(如 JSON,自動綁定到對象)。
        • @ModelAttribute:綁定到模型對象(也可以用于非請求參數的預加載)。
        • HttpServletRequest, HttpSession 等:直接獲取原生對象。
      • 對象自動封裝: 如果方法參數是一個 POJO,SpringMVC 會嘗試自動將匹配的請求參數綁定到該對象的屬性(同樣需要 setter)。
    • 類比: Struts2 收快遞,要求你必須在家門口放好對應大小和名字的空箱子(Action 里的屬性),快遞員(框架)按名字把包裹(參數)塞進去。SpringMVC 收快遞,你可以告訴快遞員:“放桌上(@RequestParam)”、“放廚房第二個柜子(@PathVariable)”、“整個包裹給我我親自拆(HttpServletRequest)” 或者 “按說明書組裝好放客廳(自動綁定到POJO)”。
  5. 攔截機制 (“關卡檢查”):

    • Struts2: 核心是 Interceptor (攔截器) 和 Interceptor Stack (攔截器棧)。Struts2 的整個處理流程(參數準備、驗證、執行Action、結果渲染等)都是由一系列定義好的攔截器完成的。開發者可以配置使用哪些攔截器以及它們的順序。攔截器是 Struts2 的絕對核心!
    • SpringMVC: 使用 HandlerInterceptor 接口。開發者可以實現該接口定義 preHandle, postHandle, afterCompletion 方法,并在配置中注冊。攔截器主要作用于 Controller 方法執行的前后以及視圖渲染之后。SpringMVC 的核心流程(映射、適配、執行、渲染)是相對固定的,攔截器是在這個流程的特定點插入的鉤子。另外,Spring 強大的 AOP (面向切面編程) 也可以用于實現更通用的橫切關注點。
    • 段子時刻: 想象你進 Struts2 大樓辦事。門口安檢(攔截器1)-> 登記(攔截器2)-> 業務審核(攔截器3)-> 見辦事員(Action)-> 結果蓋章(攔截器4)-> 離開通知(攔截器5)。必須走完整個預設的安檢通道! 進 SpringMVC 大樓,門口保安(DispatcherServlet)問你去哪,然后你直接去辦事員(Controller)那。但保安可以在你進辦事員門前(preHandle)、出辦事員門后(postHandle)、離開大樓時(afterCompletion)對你進行抽查(HandlerInterceptor)。更自由,檢查點可選!
  6. 視圖技術 (“展示成果”):

    • Struts2: 默認使用 OGNL 表達式 在視圖(如 JSP)中訪問值棧(ValueStack)中的數據。值棧是 Struts2 存儲 Action 和相關對象的地方。也支持 JSP, FreeMarker, Velocity 等。
    • SpringMVC: 解耦得非常好! 通過 ViewResolverView 接口實現。開發者配置好 ViewResolver (如 InternalResourceViewResolver 對應 JSP, FreeMarkerViewResolver 對應 FreeMarker),控制器只需要返回一個邏輯視圖名(字符串),ViewResolver 負責找到真正的視圖實現(View 對象)來渲染。在視圖中,通常使用 JSTL/EL 表達式 (JSP) 或模板引擎自己的語法來訪問模型數據(放在 Model / ModelMap / ModelAndView 對象中的數據)。更標準,更符合 Servlet/JSP 規范。
    • 類比: Struts2 展示成果,辦事員(Action)把報告直接放在一個特定的展示臺(ValueStack)上,觀眾(視圖)必須用特制的眼鏡(OGNL)才能看清楚內容。SpringMVC 展示成果,辦事員(Controller)把報告交給講解員(ViewResolverView)說:“這是給客戶的報告(邏輯視圖名 'report')”。講解員根據客戶類型(配置的視圖技術),決定是用普通話講(JSP+EL)、用英語講(FreeMarker)還是放幻燈片(PDF 視圖),并用客戶能理解的方式(EL/模板語法)展示報告內容(模型數據)。
  7. 配置方式 (“定規矩”):

    • Struts2: 重度依賴 struts.xml 文件。Action、Result、Interceptor、常量配置等都在這里。雖然支持注解,但核心配置還是 XML 為主。比較集中,但也可能變得龐大。
    • SpringMVC: 極其靈活!
      • XML 配置: 傳統的 *-servlet.xml 文件配置 HandlerMapping, ViewResolver, 攔截器等。
      • 純 Java 配置 (主流): 使用 @Configuration 類,結合 @EnableWebMvc 和實現 WebMvcConfigurer 接口來配置所有 MVC 相關組件。干凈、類型安全、現代!
      • 注解驅動 (主流中的主流): 大量使用 @Controller, @RequestMapping, @RequestParam, @PathVariable, @ResponseBody 等注解在代碼中聲明式配置,極大簡化開發。結合 Java 配置,XML 幾乎可以消失。
    • 類比: Struts2 定規矩像寫一本厚厚的公司制度手冊(struts.xml),所有流程寫得清清楚楚,改制度就得翻手冊。SpringMVC 定規矩,你可以選擇寫手冊(XML),也可以選擇開個會口頭宣布(Java 配置),或者給每個員工發個電子備忘錄(注解),方式靈活,與時俱進
  8. 性能和社區:

    • Struts2: 歷史包袱較重,早期版本因 OGNL 和安全問題(如遠程代碼執行漏洞)受到詬病。性能相對 SpringMVC 稍遜一籌(主要因為攔截器棧的深度和 ValueStack 的操作)。社區活躍度和新特性發展相對緩慢。很多新項目不再選擇。
    • SpringMVC: 作為 Spring 生態一部分,性能優化好,輕量高效(尤其默認單例 Controller)。社區極其活躍,文檔豐富,與 Spring Boot 結合后成為 Java Web 開發事實上的標準。安全性和最佳實踐更受推崇。

終極總結 & 面試金句:

  • 架構哲學: Struts2 是 “重量級、侵入式、流程固定” 的中央集權;SpringMVC 是 “輕量級、非侵入式(相對)、高度可定制、與 Spring 生態深度集成” 的自由聯邦。
  • 核心差異點:
    • 控制器: Struts2 需繼承(多例),SpringMVC 是 POJO + 注解(單例)。
    • 參數綁定: Struts2 靠屬性+OGNL(耦合高),SpringMVC 靠靈活的方法參數綁定注解(解耦好)。
    • 攔截器: Struts2 的攔截器棧是核心流程;SpringMVC 的攔截器是流程中的鉤子
    • 視圖: Struts2 強綁定 OGNL+值棧;SpringMVC 標準解耦 ViewResolver + EL/模板。
    • 配置: Struts2 重度 XML;SpringMVC 擁抱 Java 配置 + 注解。
    • 生態 & 未來: SpringMVC + Spring Boot 是 絕對主流和趨勢;Struts2 逐漸成為 “上古” 技術(維護老項目才會接觸)。

幽默收尾:

面試時如果被問到,可以笑著說:“這就像問現在出門是騎馬(Struts2)還是開車(SpringMVC)。雖然馬兒也曾風光無限,但時代變了,老司機們都開 SpringMVC 這輛 ‘Spring Boot 超跑’ 了!當然,如果貴司馬廄里(老系統)還有幾匹 Struts2 的千里馬需要照顧,我也略懂馴馬術(維護經驗)😉。”

記住這些核心點,結合生動的類比,面試官想不給你加分都難!加油!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909206.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909206.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909206.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Nginx配置指南與最佳實踐

Nginx 的配置文件通常位于 /etc/nginx/nginx.conf,并通過 include 指令加載其他目錄(如 /etc/nginx/conf.d/ 或 /etc/nginx/sites-enabled/)中的配置片段。以下是一個結構化指南: 核心配置結構 # 全局配置 (主上下文) user nginx…

Apache 反向代理Unity服務器

Apache 反向代理Unity服務器 前言項目使用PHPStudy開啟服務修改配置文件修改配置負載均衡(可選)重啟 總結 前言 使用Unity開了個后臺服務器,但是另一個Java服務器進行大量異步請求時會導致服務器回復過慢,所以開一個Apache緩沖一…

【力扣 簡單 C++】94. 二叉樹的中序遍歷

目錄 題目 解法一&#xff1a;遞歸 解法二&#xff1a;迭代 解法三&#xff1a;Morris遍歷 題目 解法一&#xff1a;遞歸 class Solution { private:void traverse(TreeNode* root, vector<int>& inorder){if (!root)return;traverse(root->left, inorder);i…

idea2024版本設置TODO快捷鍵

直接開干&#xff1a; 首先打開File–>Settings…–>Editor–>Live Templates 復制文本&#xff1a;//wk TODO $data$ 定義自定義todo使用范圍&#xff1a; 設置自定義todo的過濾器&#xff1a; 正式開始設置todo的過濾器&#xff1a; 復制文本&#xff1a; \bwk TO…

云原生核心技術 (12/12): 終章:使用 GitLab CI 將應用自動部署到 K8s (保姆級教程)

大家好&#xff0c;歡迎來到《云原生核心技術》系列的最終章&#xff01; 我們一起走過了漫長而充實的旅程。從 Docker 的集裝箱&#xff0c;到 K8s 這座自動化的數字港口&#xff1b;從部署單個 Pod&#xff0c;到構建復雜的有狀態應用。現在&#xff0c;我們站在了實現全自動…

DEVICENET轉MODBUS TCP網關連接ABB機器人配置案例

在工業自動化場景中&#xff0c;DeviceNet和Modbus TCP是兩種常見的通信協議。DeviceNet通常用于連接現場設備&#xff08;如傳感器、執行器等&#xff09;&#xff0c;而Modbus TCP則廣泛應用于以太網環境下的遠程監控和數據采集。當需要將基于DeviceNet協議的ABB機器人集成到…

達夢數據庫單機部署dmhs同步復制(dm8->kafka)

本文討論了達夢數據實時同步軟件DMHS的相關內容&#xff0c;包括概念總結、環境模擬及部署實現從達夢數據庫到Kafka隊列的同步復制。關鍵要點包括&#xff1a; 1.DMHS系統概述&#xff1a; 達夢公司推出的異構環境高性能數據庫實時同步系統&#xff0c;可應用于應急、容災等多…

爬蟲+動態代理助力 AI 訓練數據采集

文章目錄 引言新手之選&#xff1a;網頁抓取API可靠之選&#xff1a;動態住宅代理總結 引言 近年來&#xff0c;AI 技術飛速發展&#xff0c;很多朋友都投身于 AI 模型的訓練。然而&#xff0c;相較于模型的獲取&#xff0c;高質量的數據往往更加難以收集。一方面&#xff0…

OpenEuler服務器警告郵件自動化發送:原理、配置與安全實踐

OpenEuler服務器警告郵件自動化發送&#xff1a;原理、配置與安全實踐 在服務器的運維管理過程中&#xff0c;及時感知系統異常狀態至關重要。當OpenEuler系統運行時&#xff0c;將服務器的警告信息實時推送至郵箱&#xff0c;能幫助運維人員快速響應潛在問題&#xff0c;保障…

使用vite-plugin-html在 HTML 文件中動態注入數據,如元數據、環境變量、標題

vite-plugin-html 是一個用于 Vite 構建工具的插件&#xff0c;它可以幫助你在構建過程中動態注入一些 HTML 內容&#xff0c;比如標題、元數據、環境變量等。通過使用這個插件&#xff0c;你可以根據項目的配置和環境變量自動生成帶有動態內容的 HTML 文件&#xff0c;適用于 …

學習筆記087——Java接口和抽象類的區別和使用

文章目錄 1、主要區別2、使用場景2.1 使用接口的情況&#xff1a;2.1 使用抽象類的情況&#xff1a; 3、Java 8及以后的接口增強4、設計建議 1、主要區別 特性接口(Interface)抽象類(Abstract Class)定義方式使用interface關鍵字使用abstract class關鍵字方法實現Java 8前不能…

Squid 代理服務器實戰:解決動態 IP 訪問第三方接口的生產級方案

前言&#xff1a;動態IP場景下的業務痛點與解決方案 在企業開發場景中&#xff0c;經常會遇到這樣的需求&#xff1a;第三方服務&#xff08;如API接口、云平臺服務&#xff09;要求將訪問源IP加入白名單以保障安全。然而&#xff0c;企業辦公網絡通常采用動態IP分配&#xff0…

React中子傳父組件通信操作指南

文章目錄 為什么需要子傳父通信&#xff1f;方法一&#xff1a;回調函數&#xff08;最常用&#xff09;基礎示例實際場景&#xff1a;待辦事項列表 方法二&#xff1a;使用useRef傳遞引用方法三&#xff1a;Context API&#xff08;跨層級通信&#xff09;方法四&#xff1a;自…

【android bluetooth 框架分析 04】【bt-framework 層詳解 5】【AbstractionLayer介紹】

1. AbstractionLayer 介紹 我們在閱讀 native 和 java 層 藍牙服務代碼時&#xff0c;會發現很多 AbstractionLayer.xxxxx 的字段。 這些字段 雖然很容易理解是干什么的。 但是 大家有沒有考慮過&#xff0c; 為啥要專門定義一個類來存放他們。 這樣設計的意義是什么&#xff…

AI大模型從0到1記錄學習 大模型技術之機器學習 day27-day60

機器學習概述 機器學習&#xff08;Machine Learning, ML&#xff09;主要研究計算機系統對于特定任務的性能&#xff0c;逐步進行改善的算法和統計模型。通過輸入海量訓練數據對模型進行訓練&#xff0c;使模型掌握數據所蘊含的潛在規律&#xff0c;進而對新輸入的數據進行準確…

c/c++ 匯編碼中的.cfi 指令有什么用途?

author: hjjdebug date: 2025年 06月 12日 星期四 14:24:40 CST descrip: c/c 匯編碼中的.cfi 指令有什么用途? 文章目錄 1. 幾個簡寫詞.2. 看一個簡單的測試代碼:3. 生成匯編代碼:4. 分析.cfi 指令5. 小結: 1. 幾個簡寫詞. cfi(call frame info) 調用幀信息, 名詞. 描述的是…

ArcGIS Pro 3.4 二次開發 - 任務

環境:ArcGIS Pro SDK 3.4 + .NET 8 文章目錄 任務1 任務1.1 檢索項目中的所有任務項1.2 打開任務文件 - .esriTasks 文件1.3 打開項目任務項1.4 關閉任務項1.5 導出任務項1.6 獲取任務信息 - 從 TaskProjectItem1.7 獲取任務信息 - 從 .esriTasks 文件1.8 在任務文件中打開特定…

vscode如何修改終端的默認配置

問題困擾&#xff1a; 每次打開都是 powershell, 因為每次要是用 git bash, 所以每次手動切換很麻煩。 要將默認終端設置為 Git Bash&#xff0c;可以通過以下步驟完成。以下是詳細的操作方法&#xff1a; 步驟 1&#xff1a;打開終端設置 在 Visual Studio Code 的菜單欄中…

kafka快速入門與知識匯總

? kafka快速入門與知識匯總 一、前言 kafka是一款消息中間件&#xff0c;可以用于傳輸消息和日志收集、監控項目狀況。與其類似的技術棧有rocketmq、rabbitmq等&#xff0c;但這些技術棧大多應用在一些簡單的消息傳輸平臺&#xff0c;而kafka則因其對大量數據的高性能處理在…

設計模式——觀察者設計模式(行為型)

摘要 本文詳細介紹了觀察者設計模式&#xff0c;包括其定義、結構、實現方式、適用場景以及實戰示例。通過代碼示例展示了如何在Spring框架下實現觀察者模式&#xff0c;以及如何通過該模式實現狀態變化通知。同時&#xff0c;對比了觀察者模式與消息中間件在設計理念、耦合程…