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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;对比了观察者模式与消息中间件在设计理念、耦合程…