在 Java Web 开发领域,SpringMVC 作为轻量级且高效的 MVC 框架,是构建 B/S 架构应用的核心技术之一。本文将从三层架构与 MVC 模型的理论基础出发,逐步深入 SpringMVC 的核心概念,并通过完整的入门案例,帮助开发者理解其工作原理与实践流程。
一、Web 开发基础:三层架构与 MVC 模型
在正式学习 SpringMVC 之前,需先明确 Web 应用的架构设计思想 —— 三层架构是 B/S 应用的整体骨架,而 MVC 则是表现层的设计模式,二者共同支撑起高效、可维护的 Java Web 应用。
1.1 三层架构:B/S 应用的核心骨架
Java Web 开发以 B/S(Browser/Server,浏览器 / 服务器)架构为主,其核心是三层架构,通过职责划分实现解耦,便于后续维护与扩展。三层架构的具体划分如下:
| 架构层级 | 核心职责 | 技术实现 |
|---|---|---|
| 表现层(WEB 层) | 与客户端(浏览器)进行数据交互,接收请求并返回响应 | JSP、Servlet、SpringMVC(本文核心) |
| 业务层(Service 层) | 处理企业核心业务逻辑(如用户认证、订单计算等) | 自定义 Service 接口与实现类 |
| 持久层(DAO 层) | 操作数据库,实现数据的 CRUD(增删改查) | MyBatis、JPA、Spring JDBC |
三层架构的核心优势:
- 职责单一:每层仅关注自身功能,避免代码冗余(如表现层不处理业务逻辑,业务层不直接操作数据库);
- 低耦合:层与层之间通过接口通信,修改某一层逻辑不影响其他层(如替换持久层框架从 MyBatis 到 JPA,无需修改业务层);
- 易维护:问题定位更精准(如数据查询异常仅需排查持久层)。
1.2 MVC 模型:表现层的设计模式
表现层(WEB 层)通常采用MVC 设计模型(Model-View-Controller,模型 - 视图 - 控制器),进一步拆分表现层职责,实现 “数据、展示、控制” 的分离。
MVC 三组件的职责划分如下:
| 组件 | 核心职责 | 技术实现 |
|---|---|---|
| Model(模型) | 封装数据,对应业务实体(如 User、Order) | JavaBean(包含属性、getter/setter 方法) |
| View(视图) | 展示数据给用户,接收用户操作 | JSP、HTML、Thymeleaf、Vue(前后端分离场景) |
| Controller(控制器) | 接收用户请求,协调 Model 与 View,处理流程控制(如数据校验、请求转发) | SpringMVC 的 Controller 类、Servlet |
MVC 的核心优势:
- 视图与逻辑分离:View 仅负责展示,Controller 负责业务逻辑,避免 JSP 中嵌入大量 Java 代码;
- 可复用性:Model 可在不同 View 中复用(如 User 对象可同时用于 “用户列表” 和 “用户详情” 页面);
- 易扩展:新增视图(如移动端页面)无需修改 Controller 逻辑。
二、SpringMVC 概述:定位与优势
SpringMVC 是 Spring 框架的 Web 模块核心,是基于 Java 的 MVC 设计模式的请求驱动型轻量级 Web 框架,现已完全融合到 Spring 生态中,成为 Java Web 开发的主流选择。
2.1 SpringMVC 的核心定位
- 层级定位:属于三层架构中的表现层框架,替代传统 Servlet,简化请求处理流程;
- 生态定位:Spring 框架的子模块,可与 Spring 的 IOC、AOP 等特性无缝集成(如 Controller 对象由 Spring IOC 容器管理);
- 灵活性:支持插件式架构,可选择集成其他视图技术(如 Thymeleaf、FreeMarker)或前后端分离方案(返回 JSON 数据)。
2.2 SpringMVC vs Struts2:主流框架对比
作为曾经的主流 MVC 框架,Struts2 与 SpringMVC 的对比能更清晰体现 SpringMVC 的优势:
| 对比维度 | SpringMVC | Struts2 |
|---|---|---|
| 性能 | 基于方法级别的拦截(通过@RequestMapping),性能更高 | 基于类级别的拦截(每个请求对应一个 Action 实例),性能较低 |
| 集成性 | 与 Spring 生态无缝集成(如 IOC、事务管理) | 需额外配置才能与 Spring 集成,复杂度高 |
| 配置复杂度 | 支持注解驱动(如@Controller),配置简洁 | 早期依赖 XML 配置,后期支持注解但仍较繁琐 |
| 学习成本 | API 简洁,入门门槛低,文档丰富 | 核心概念多(如 ValueStack、OGNL),学习曲线较陡 |
| 社区活跃度 | 持续更新,社区活跃(Spring 6 + 仍在迭代) | 维护缓慢,社区活跃度下降,逐步被 SpringMVC 替代 |
三、SpringMVC 入门案例:完整实现流程
本节通过一个 “请求跳转” 案例,演示 SpringMVC 的完整开发流程,涵盖环境搭建、代码编写、配置与测试。
3.1 环境准备:开发工具与依赖
- 开发工具:IntelliJ IDEA + Tomcat 8.5+ + Maven 3.6+;
- 核心依赖:通过 Maven 引入 SpringMVC 及 Servlet 相关 Jar 包,采用版本锁定避免依赖冲突。
Maven 依赖配置(pom.xml)
5.0.2.RELEASE
org.springframework spring-context ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-webmvc ${spring.version} javax.servlet servlet-api 2.5 provided javax.servlet.jsp jsp-api 2.0 provided
3.2 步骤 1:编写视图页面(View)
创建两个 JSP 页面,分别作为 “请求入口” 和 “成功响应页”:
1. 入口页面:index.jsp(项目根目录)
用于触发请求,包含一个超链接,指向/hello.do:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>SpringMVC入门 SpringMVC入门案例
点击触发请求
2. 成功页面:suc.jsp(/WEB-INF/pages/ 目录下)
用于展示请求处理成功的结果,放在WEB-INF目录下可避免直接访问(需通过 Controller 转发):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>请求成功 SpringMVC入门案例执行成功!
3.3 步骤 2:编写控制器(Controller)
创建HelloController类,作为请求处理的核心,通过注解声明为 Spring 组件,并配置请求映射。
HelloController.java(包路径:com.qcbyjy.demo)
package com.qcbyjy.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/*** SpringMVC控制器:处理用户请求*/
// @Controller:声明该类为Spring管理的Controller组件(替代传统Servlet)
@Controller
public class HelloController {/*** 处理/hello.do请求的方法* @return 跳转的视图名称(需配合视图解析器)*/// @RequestMapping:建立请求URL(/hello.do)与方法的映射关系@RequestMapping(path = "/hello.do")public String sayHello() {// 业务逻辑(此处仅打印日志,实际项目中可调用Service层)System.out.println("HelloController的sayHello方法执行!");// 返回视图名称:若配置视图解析器,无需写完整路径,仅需文件名(suc -> /WEB-INF/pages/suc.jsp)return "suc";}
}
3.4 步骤 3:配置 SpringMVC 核心(关键配置)
SpringMVC 的核心配置分为两部分:Web 容器配置(web.xml) 和SpringMVC 配置(springmvc.xml)。
1. Web 容器配置:web.xml(配置前端控制器)
前端控制器(DispatcherServlet)是 SpringMVC 的入口,负责接收所有请求并分发,需在web.xml中配置:
dispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 dispatcherServlet *.do
2. SpringMVC 配置:springmvc.xml(IOC 与视图解析)
配置 SpringMVC 的核心功能:组件扫描(管理 Controller)、视图解析器(解析视图路径)。
创建springmvc.xml文件,放在src/main/resources目录下:
3.5 步骤 4:部署测试
- 配置 Tomcat:在 IDEA 中添加 Tomcat 服务器,将项目部署到 Tomcat;
- 启动 Tomcat:访问
http://localhost:8080/项目名/index.jsp(如http://localhost:8080/SpringMVC_Demo/index.jsp); - 触发请求:点击 “点击触发请求” 超链接,页面跳转至
suc.jsp,同时控制台打印HelloController的sayHello方法执行!,说明案例成功。
四、入门案例深度解析:执行流程与核心组件
理解 SpringMVC 的执行流程是掌握框架的关键,本节结合入门案例,拆解从 “请求发送” 到 “页面响应” 的完整链路。
4.1 执行流程拆解(6 步)
- 初始化阶段:Tomcat 启动时,因
web.xml中配置了load-on-startup=1,创建DispatcherServlet实例,同时加载springmvc.xml配置文件,开启组件扫描并创建HelloController对象(由 Spring IOC 管理); - 请求发送:用户点击
index.jsp中的超链接,发送/hello.do请求,该请求被DispatcherServlet拦截(因url-pattern=*.do); - 请求映射:
DispatcherServlet调用处理器映射器(HandlerMapping),根据@RequestMapping(path = "/hello.do")找到对应的处理方法(sayHello()); - 方法执行:
DispatcherServlet通过处理器适配器(HandlerAdapter) 调用sayHello()方法,执行业务逻辑(打印日志); - 视图解析:
sayHello()返回视图名称"suc",DispatcherServlet将名称传递给视图解析器(ViewResolver),结合前缀(/WEB-INF/pages/)和后缀(.jsp),解析出完整视图路径/WEB-INF/pages/suc.jsp; - 响应页面:
DispatcherServlet请求转发到suc.jsp,Tomcat 渲染页面并返回给浏览器。
4.2 核心组件详解
SpringMVC 的核心功能由以下 6 个组件协同完成,入门案例中部分组件(如 Handler
Mapping)由 SpringMVC 默认提供,无需手动配置:
| 组件名称 | 核心职责 | 入门案例中的体现 |
|---|---|---|
| 前端控制器(DispatcherServlet) | 全局入口,接收所有请求,协调其他组件 | web.xml中配置的dispatcherServlet |
| 处理器映射器(HandlerMapping) | 根据请求 URL 查找对应的 Handler(处理方法) | 默认映射器根据@RequestMapping找到sayHello() |
| 处理器(Handler) | 实际处理请求的方法(Controller 中的方法) | HelloController的sayHello()方法 |
| 处理器适配器(HandlerAdapter) | 适配并调用 Handler 方法(处理参数绑定、返回值解析) | 默认适配器调用sayHello()并接收返回值"suc" |
| 视图解析器(ViewResolver) | 将视图名称解析为实际视图路径 | InternalResourceViewResolver解析"suc"为/WEB-INF/pages/suc.jsp |
| 视图(View) | 展示数据的页面(如 JSP、HTML) | suc.jsp页面 |
五、RequestMapping 注解:请求映射的核心
@RequestMapping是 SpringMVC 中最核心的注解,用于建立 “请求 URL” 与 “处理方法” 的映射关系,支持作用于类和方法,且提供丰富的属性配置请求规则。
5.1 注解的作用范围
- 作用于类:定义一级请求路径(父路径),所有该类中的方法都需在父路径下访问;
- 作用于方法:定义二级请求路径(子路径),与类上的路径组合成完整 URL。
示例:类与方法组合映射
package com.qcbyjy.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
// 类上的@RequestMapping:一级路径/role
@Controller
@RequestMapping(path = "/role")
public class RoleController {// 方法上的@RequestMapping:二级路径/save.do// 完整请求URL:/role/save.do@RequestMapping(path = "/save.do")public String saveRole() {System.out.println("保存角色成功!");return "suc";}
}
5.2 核心属性详解
@RequestMapping提供多个属性,用于精确控制请求的匹配规则,常用属性如下:
| 属性名 | 类型 | 核心作用 | 示例 |
|---|---|---|---|
path | String[] | 指定请求 URL(与value属性功能一致) | @RequestMapping(path = "/save.do") |
value | String[] | 同path(推荐使用,更简洁) | @RequestMapping(value = "/delete.do") |
method | RequestMethod[] | 限制请求方式(如 GET、POST) | @RequestMapping(value = "/save.do", method = RequestMethod.POST) |
params | String[] | 限制请求必须包含指定参数 | @RequestMapping(value = "/save.do", params = "username")(请求必须带username参数) |
示例:多属性组合配置
package com.qcbyjy.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/role")
public class RoleController {/*** 完整请求规则:* 1. URL:/role/save.do* 2. 请求方式:仅允许GET* 3. 请求参数:必须包含username参数(如/role/save.do?username=admin)*/@RequestMapping(value = "/save.do",method = {RequestMethod.GET},params = "username")public String saveRole() {System.out.println("带参数的角色保存!");return "suc";}
}
六、总结
本文从架构理论到实践案例,完整覆盖了 SpringMVC 的入门核心:
- 理论基础:三层架构是 B/S 应用的骨架,MVC 是表现层的设计模式,二者共同支撑解耦;
- 框架定位:SpringMVC 是表现层主流框架,性能优于 Struts2,且与 Spring 生态无缝集成;
- 实践流程:通过 “环境搭建→视图编写→Controller 编写→配置→测试” 的步骤,实现入门案例;
- 核心原理:理解
DispatcherServlet为核心的执行流程,掌握@RequestMapping的请求映射规则。