目录
[一、Spring MVC 的核心定位与设计思想](#一、Spring MVC 的核心定位与设计思想)
[1. 什么是 MVC 设计模式?](#1. 什么是 MVC 设计模式?)
[2. Spring MVC 的核心思想:前端控制器模式](#2. Spring MVC 的核心思想:前端控制器模式)
[二、Spring MVC 的核心组件(职责与协作)](#二、Spring MVC 的核心组件(职责与协作))
[三、Spring MVC 的工作流程(核心执行链路)](#三、Spring MVC 的工作流程(核心执行链路))
[四、Spring MVC 的核心配置(注解驱动为主)](#四、Spring MVC 的核心配置(注解驱动为主))
[1. 环境准备(Maven 依赖)](#1. 环境准备(Maven 依赖))
[2. Java 核心配置类](#2. Java 核心配置类)
[(1)Web 容器初始化配置(替代 web.xml)](#(1)Web 容器初始化配置(替代 web.xml))
[(2)Spring MVC 配置类(WebConfig)](#(2)Spring MVC 配置类(WebConfig))
[1. 控制器注解](#1. 控制器注解)
[2. 请求映射注解](#2. 请求映射注解)
[3. 请求参数绑定注解](#3. 请求参数绑定注解)
[1. 向视图传递数据](#1. 向视图传递数据)
[示例:Model 传递数据](#示例:Model 传递数据)
[Thymeleaf 视图渲染(user/list.html)](#Thymeleaf 视图渲染(user/list.html))
[2. RESTful 接口返回 JSON](#2. RESTful 接口返回 JSON)
[示例:返回 JSON](#示例:返回 JSON)
[1. 自定义拦截器](#1. 自定义拦截器)
[2. 注册拦截器(WebConfig 中配置)](#2. 注册拦截器(WebConfig 中配置))
[1. 局部异常处理(@ExceptionHandler)](#1. 局部异常处理(@ExceptionHandler))
[2. 全局异常处理(@ControllerAdvice)](#2. 全局异常处理(@ControllerAdvice))
[1. 跨域请求处理(CORS)](#1. 跨域请求处理(CORS))
[2. 文件上传](#2. 文件上传)
[3. 异步请求处理](#3. 异步请求处理)
[十、Spring MVC 的优势与应用场景](#十、Spring MVC 的优势与应用场景)
Spring MVC 是 Spring 框架的Web 模块,基于 MVC(Model-View-Controller)设计模式构建,用于快速开发灵活、松耦合的 Web 应用。它通过「前端控制器」统一处理请求,分离数据处理、页面展示和请求分发逻辑,是目前 Java 后端主流的 Web 开发框架之一。
一、Spring MVC 的核心定位与设计思想
1. 什么是 MVC 设计模式?
MVC 将应用分为三个核心角色,实现关注点分离:
- Model(模型):封装业务数据和逻辑(如实体类、Service 层),专注数据处理;
- View(视图):负责数据展示(如 JSP、Thymeleaf、Vue 页面),专注界面渲染;
- Controller(控制器):接收用户请求,协调 Model 和 View(如调用 Service 获取数据,传递给 View 展示),专注请求分发。
2. Spring MVC 的核心思想:前端控制器模式
Spring MVC 通过DispatcherServlet(前端控制器) 统一接收所有请求,替代传统 MVC 中每个 Controller 独立处理请求的方式,实现「请求集中分发、组件解耦复用」。
简单说:DispatcherServlet 是整个 Spring MVC 的「中央调度器」,所有请求先经过它,再由它分发给对应的组件处理,最终返回响应。
二、Spring MVC 的核心组件(职责与协作)
Spring MVC 的核心组件围绕 DispatcherServlet 协同工作,每个组件各司其职:

三、Spring MVC 的工作流程(核心执行链路)
请求从客户端到服务器的完整处理流程,是理解 Spring MVC 的关键:
- 客户端发送请求 :如
http://localhost:8080/user/list,请求被 Tomcat 等 Servlet 容器接收; - DispatcherServlet 接收请求:Servlet 容器将请求转发给 DispatcherServlet(配置的 URL 映射决定);
- HandlerMapping 匹配 Handler:DispatcherServlet 调用 HandlerMapping,根据请求 URL / 方法找到对应的 Controller 方法(Handler);
- HandlerAdapter 执行 Handler:DispatcherServlet 通过 HandlerAdapter 适配并执行 Handler,处理请求参数绑定、数据转换,调用 Service 层获取数据;
- Handler 返回 ModelAndView:Controller 方法执行完毕,返回 ModelAndView(或直接返回数据);
- ViewResolver 解析视图:DispatcherServlet 调用 ViewResolver,根据 ModelAndView 中的视图名称解析出实际 View;
- View 渲染响应:View 将 Model 数据渲染到页面(或直接返回 JSON 数据),生成响应;
- DispatcherServlet 返回响应:将渲染后的响应返回给客户端。

四、Spring MVC 的核心配置(注解驱动为主)
Spring MVC 支持XML 配置 和Java 配置,目前主流是 Java 配置(无 XML),以下是核心配置方式:
1. 环境准备(Maven 依赖)
XML
<!-- Spring MVC 核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Servlet API(Tomcat 已提供,需标记为 provided) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Thymeleaf 视图依赖(可选,替代 JSP) -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
2. Java 核心配置类
(1)Web 容器初始化配置(替代 web.xml)
通过 AbstractAnnotationConfigDispatcherServletInitializer 配置 DispatcherServlet 和 Spring 容器:
java
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
// Web 应用初始化器,替代 web.xml
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// 根容器配置类(Service、Dao 层)
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
// Spring MVC 容器配置类(Controller、ViewResolver 等)
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
// DispatcherServlet 的 URL 映射("/" 表示处理所有请求)
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
(2)Spring MVC 配置类(WebConfig)
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
@Configuration
@EnableWebMvc // 开启 Spring MVC 注解驱动(替代 XML 的 <mvc:annotation-driven>)
@ComponentScan("com.example.controller") // 扫描控制器包
public class WebConfig implements WebMvcConfigurer {
// 配置 Thymeleaf 视图解析器
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
@Bean
public SpringTemplateEngine templateEngine(ServletContextTemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
return engine;
}
@Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/"); // 视图前缀(页面存放路径)
resolver.setSuffix(".html"); // 视图后缀
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
// 静态资源处理(如 CSS、JS、图片)
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**") // 访问路径
.addResourceLocations("/WEB-INF/static/"); // 实际存放路径
}
}
(3)根容器配置类(RootConfig)
java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(
basePackages = "com.example",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)
)
// 扫描 Service、Dao 层,排除 Spring MVC 相关配置
public class RootConfig {
}
五、核心注解与请求处理
Spring MVC 通过注解简化请求映射和参数处理,以下是高频注解:
1. 控制器注解
@Controller:标注类为 Spring MVC 控制器,处理请求并返回视图;@RestController:@Controller + @ResponseBody组合,返回 JSON/XML 数据(无需视图渲染),适用于 RESTful 接口。
2. 请求映射注解
@RequestMapping:映射请求 URL、方法(GET/POST)、参数等,可标注在类或方法上;@GetMapping:@RequestMapping(method = RequestMethod.GET)的简写;@PostMapping:@RequestMapping(method = RequestMethod.POST)的简写;@PutMapping/@DeleteMapping:对应 PUT/DELETE 请求,支持 RESTful 风格。
示例:请求映射
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/user") // 类级映射:所有方法URL前缀为 /user
public class UserController {
// 匹配 GET /user/list
@GetMapping("/list")
public String userList() {
return "user/list"; // 返回视图名称,ViewResolver 解析为 /WEB-INF/views/user/list.html
}
// 匹配 POST /user/add
@PostMapping("/add")
public String addUser() {
return "redirect:/user/list"; // 重定向到列表页
}
// RESTful:匹配 GET /user/1(路径参数)
@GetMapping("/{id}")
@ResponseBody // 返回 JSON 数据
public String getUserById(@PathVariable("id") Integer id) {
return "User ID: " + id;
}
}
3. 请求参数绑定注解
@RequestParam:绑定请求参数(如?name=张三);@PathVariable:绑定 URL 路径参数(如/user/{id});@RequestBody:绑定请求体(JSON/XML 数据),适用于 POST/PUT 请求;@RequestHeader:绑定请求头信息;@CookieValue:绑定 Cookie 数据;@ModelAttribute:绑定请求参数到实体对象(表单提交常用)。
示例:参数绑定
java
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
public class UserRestController {
// 绑定请求参数:/user/query?name=张三&age=20
@GetMapping("/query")
public String queryUser(
@RequestParam("name") String name,
@RequestParam(value = "age", defaultValue = "18") Integer age
) {
return "Name: " + name + ", Age: " + age;
}
// 绑定路径参数:/user/123
@GetMapping("/{id}")
public String getUser(@PathVariable("id") Long id) {
return "User ID: " + id;
}
// 绑定请求体(JSON):POST /user/save,Body {"name":"李四","age":25}
@PostMapping("/save")
public String saveUser(@RequestBody User user) {
return "Saved: " + user.getName() + ", " + user.getAge();
}
// 表单提交绑定到实体:POST /user/form,FormData name=王五&age=30
@PostMapping("/form")
public String formSubmit(@ModelAttribute User user) {
return "Form: " + user.getName();
}
}
// User 实体类
class User {
private String name;
private Integer age;
// getter/setter
}
六、数据模型与视图渲染
1. 向视图传递数据
Controller 可通过以下方式将数据传递给视图:
Model/ModelMap:添加数据到模型,视图可直接访问;ModelAndView:同时封装视图名称和模型数据;@SessionAttributes:将数据存入 Session(跨请求共享)。
示例:Model 传递数据
java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
public String userList(Model model) {
// 模拟从 Service 获取用户列表
List<User> userList = Arrays.asList(
new User("张三", 20),
new User("李四", 25)
);
// 添加数据到模型,视图中可通过 "users" 访问
model.addAttribute("users", userList);
model.addAttribute("title", "用户列表");
return "user/list"; // 返回视图名称
}
}
Thymeleaf 视图渲染(user/list.html)
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${title}">用户列表</title>
</head>
<body>
<h1 th:text="${title}">用户列表</h1>
<table>
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.name}">张三</td>
<td th:text="${user.age}">20</td>
</tr>
</table>
</body>
</html>
2. RESTful 接口返回 JSON
使用 @RestController 或 @ResponseBody,Spring MVC 会自动将对象序列化为 JSON(需引入 Jackson 依赖):
XML
<!-- Jackson 依赖(JSON 序列化) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.5</version>
</dependency>
示例:返回 JSON
java
@RestController
@RequestMapping("/api/user")
public class UserApiController {
@GetMapping("/{id}")
public User getUser(@PathVariable("id") Long id) {
return new User("张三", 20); // 自动序列化为 JSON:{"name":"张三","age":20}
}
}
七、拦截器(HandlerInterceptor)
拦截器用于在请求处理的前、中、后 插入自定义逻辑(如登录验证、日志记录、权限检查),实现 HandlerInterceptor 接口:
1. 自定义拦截器
java
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
// 请求处理前执行(返回 true 继续,false 终止)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 检查用户是否登录
Object user = request.getSession().getAttribute("user");
if (user == null) {
// 未登录,重定向到登录页
response.sendRedirect("/login");
return false;
}
return true; // 已登录,继续处理请求
}
// 请求处理后、视图渲染前执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 可修改 ModelAndView 数据
}
// 视图渲染后执行(常用于资源清理)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 记录请求完成日志
}
}
2. 注册拦截器(WebConfig 中配置)
java
@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/user/**") // 拦截 /user 下所有请求
.excludePathPatterns("/user/login"); // 排除登录请求
}
}
八、异常处理
Spring MVC 提供多种异常处理方式,实现统一的异常响应:
1. 局部异常处理(@ExceptionHandler)
在 Controller 内定义,仅处理当前 Controller 的异常:
java
@Controller
@RequestMapping("/user")
public class UserController {
// 处理当前 Controller 的 RuntimeException
@ExceptionHandler(RuntimeException.class)
public String handleRuntimeException(RuntimeException e, Model model) {
model.addAttribute("error", e.getMessage());
return "error"; // 跳转到错误页面
}
}
2. 全局异常处理(@ControllerAdvice)
全局生效,处理所有 Controller 的异常:
java
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice // 全局控制器增强
public class GlobalExceptionHandler {
// 处理所有 Exception
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {
ModelAndView mav = new ModelAndView();
mav.addObject("error", "系统异常:" + e.getMessage());
mav.setViewName("error"); // 错误页面
return mav;
}
// 处理 REST 接口异常,返回 JSON
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public String handleIllegalArgument(IllegalArgumentException e) {
return "{\"code\":400,\"msg\":\"" + e.getMessage() + "\"}";
}
}
九、高级特性
1. 跨域请求处理(CORS)
通过 @CrossOrigin 或全局配置支持跨域:
java
// 局部跨域(Controller/方法级)
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:8081") // 允许 8081 端口跨域
public class ApiController {
// ...
}
// 全局跨域(WebConfig 中配置)
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:8081")
.allowedMethods("GET", "POST")
.allowCredentials(true);
}
2. 文件上传
配置文件上传解析器,处理 multipart 请求:
java
// WebConfig 中配置文件上传
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(10 * 1024 * 1024); // 最大上传大小 10MB
resolver.setDefaultEncoding("UTF-8");
return resolver;
}
// Controller 处理文件上传
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
// 保存文件
file.transferTo(new File("D:/uploads/" + file.getOriginalFilename()));
return "redirect:/success";
}
3. 异步请求处理
支持异步响应(如处理耗时任务),避免线程阻塞:
java
@RestController
@RequestMapping("/async")
public class AsyncController {
@GetMapping("/task")
public Callable<String> asyncTask() {
return () -> {
// 模拟耗时任务(5秒)
Thread.sleep(5000);
return "异步任务完成";
};
}
}
十、Spring MVC 的优势与应用场景
核心优势
- 松耦合设计:组件职责清晰,通过注解和接口解耦,易于扩展;
- 强大的配置灵活性:支持注解驱动、Java 配置、XML 配置,适配不同场景;
- 与 Spring 生态无缝集成:可直接使用 Spring 的 IoC、AOP、事务管理等功能;
- 全面的功能支持:覆盖请求处理、数据绑定、视图渲染、异常处理、拦截器等;
- RESTful 友好:原生支持 RESTful 风格的 URL 映射和 JSON 数据交互。
应用场景
- 传统服务器渲染的 Web 应用(JSP/Thymeleaf);
- RESTful API 接口开发(前后端分离项目);
- 企业级 Web 应用(如电商、OA 系统);
- 微服务架构中的 API 网关或服务接口。