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:

        java 复制代码
        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:

        java 复制代码
        @Controller
        @RequestMapping("/user")
        public class UserController {
        
            @Autowired
            private UserService userService; // 轻松注入其他Spring管理的Bean!
        
            @GetMapping("/login") // 更精细的映射
            public String login(@RequestParam String username, 
                              @RequestParam String password, 
                              Model model) {
                // 业务逻辑,通常调用Service
                boolean 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 的千里马需要照顾,我也略懂驯马术(维护经验)😉。"

记住这些核心点,结合生动的类比,面试官想不给你加分都难!加油!

相关推荐
皮皮林5511 小时前
SpringBoot 加载外部 Jar,实现功能按需扩展!
java·spring boot
郑道1 小时前
Docker 在 macOS 下的安装与 Gitea 部署经验总结
后端
3Katrina1 小时前
妈妈再也不用担心我的课设了---Vibe Coding帮你实现期末课设!
前端·后端·设计
rocksun1 小时前
认识Embabel:一个使用Java构建AI Agent的框架
java·人工智能
汪子熙1 小时前
HSQLDB 数据库锁获取失败深度解析
数据库·后端
高松燈2 小时前
若伊项目学习 后端分页源码分析
后端·架构
没逻辑2 小时前
主流消息队列模型与选型对比(RabbitMQ / Kafka / RocketMQ)
后端·消息队列
倚栏听风雨3 小时前
SwingUtilities.invokeLater 详解
后端
Java中文社群3 小时前
AI实战:一键生成数字人视频!
java·人工智能·后端
王中阳Go3 小时前
从超市收银到航空调度:贪心算法如何破解生活中的最优决策谜题?
java·后端·算法