Files
blog-press/docs/Web-Backend/SpringBoot/SpringMVC.md
2025-12-15 23:25:25 +08:00

7.1 KiB
Raw Blame History

一、基础概念

Spring MVCSpring Model-View-Controller是 Spring Framework 中的一部分,它是一个基于 请求驱动 的 Web 框架,主要用于构建 Web 应用程序,并且遵循 MVC模型-视图-控制器) 设计模式。它将 Web 应用的业务逻辑、用户界面和请求处理分离,使得代码更加模块化和可维护。

二、具体流程

暂无图片

  1. 客户端发起HTTP请求

客户端浏览器、API 客户端等)向服务器发送 HTTP 请求。请求包含了目标 URL、HTTP 方法GET、POST 等)以及可能的请求参数。 前端通过发送 HTTP 请求(通常是 AJAX 请求)到后端的 API 端点,并期望获得响应(通常是 JSON 数据)。

  1. 请求到达 DispatcherServlet

  所有 HTTP 请求都会先到达 Spring MVC 的核心组件:DispatcherServlet。它是前端控制器负责将请求分发给正确的处理器。DispatcherServlet 是所有请求的入口Spring Boot 会自动配置它。
DispatcherServlet 接受所有的 HTTP 请求,根据请求 URL 和 HTTP 方法,定位匹配的控制器方法,将请求交给相应的 Handler Mapping 来匹配控制器。在请求处理前后,执行 拦截器(可选)。最终通过 View Resolver 返回一个合适的视图(对于 RESTful API通常返回 JSON 格式的数据)。

  1. 查找处理器Handler Mapping

DispatcherServlet 根据请求的 URL 和 HTTP 方法,查找与之匹配的处理器方法(通常是一个控制器中的方法)。这是由 HandlerMapping 完成的。Spring MVC 提供了多种方式来映射 URL 到控制器方法,例如 @RequestMapping、@GetMapping 等注解。
@RestController该注解标记的类会返回 JSON 数据。
@RequestMapping用于映射 URL 路径和 HTTP 方法。
@GetMapping、@PostMapping 等:简化版本的 @RequestMapping。

  1. 执行拦截器Interceptor

在请求到达控制器之前DispatcherServlet 会依次执行配置的拦截器。拦截器主要用于日志记录、安全检查、请求参数的预处理等。
preHandle请求进入控制器方法之前。
postHandle请求完成后视图渲染之前。
afterCompletion视图渲染完成后。
如果拦截器的 preHandle 方法返回 false请求会被拦截后续的处理不会继续进行。

  1. 控制器方法处理请求Handler Execution

DispatcherServlet 调用合适的控制器方法来处理请求。控制器方法负责处理请求的业务逻辑,并返回一个 Java 对象,这个对象会被自动转换成 JSON 格式返回给客户端。
Spring 通过 @ResponseBody 注解(或 @RestController实现将 Java 对象自动转换为 JSON 格式。默认情况下Spring 使用 Jackson 来将 Java 对象序列化成 JSON 数据。
@RestController将控制器标记为返回 JSON 数据的 RESTful 控制器。
@ResponseBody标记方法返回的数据需要直接作为响应体返回而不是解析为视图。
@RequestParam用于获取单个请求参数。
@PathVariable用于从 URL 中提取变量(如 /users/{id} 中的 {id})。

  1. 响应返回客户端

DispatcherServlet 将处理完的结果JSON 数据)返回给客户端。响应数据通常会包含:
状态码:如 200 OK成功、201 Created资源创建成功、404 Not Found资源未找到、500 Internal Server Error服务器错误等。
响应头:通常包括 Content-Type: application/json表示响应体是 JSON 格式。
响应体:包含返回的数据,通常是一个 JSON 格式的对象或数组。

以上只适用于基于RESTful API 前后端分离的架构。

三、完整流程

暂无图片 在SpringMVC前面还有Tomcat容器层。客户端发起请求后先经过Tomcat容器根据请求的 URL 确定该请求是否是静态资源请求(如 .html、.css、.js。如果是静态资源请求Tomcat 会直接返回文件,而不经过 Spring MVC 的请求处理链。对于动态请求(如请求 /user 等Tomcat 会将这些请求交给 DispatcherServlet 进行处理。
在进入DispatcherServlet前可以增加过滤器进行处理。过滤器不属于Spring部分。
Tomcat 是一个轻量级的 Web 服务器和 Servlet 容器,支持 Java Servlet 和 JSP 规范,能够处理 HTTP 请求并生成动态 Web 内容。
Servlet 是 Java 编写的服务器端程序,能够接收 HTTP 请求并生成响应,它是动态 Web 内容生成的核心技术。
Tomcat 管理 Servlet 的生命周期,并负责处理客户端的请求和返回响应。

四、重要知识点

4.1 拦截器和过滤器区别

  1. 拦截器不依赖与servlet容器过滤器依赖与servlet容器。
  2. 拦截器只能对action请求(DispatcherServlet 映射的请求)起作用,而过滤器则可以对几乎所有的请求起作用。
  3. 拦截器可以访问容器中的Bean(DI)而过滤器不能访问基于spring注册的过滤器也可以访问容器中的bean
  4. 执行顺序:过滤器->拦截器

4.2 拦截器执行顺序

HandlerInterceptor 拦截器执行顺序:

  1. preHandle():请求处理前 按注册顺序依次执行。
  2. Controller请求处理 请求到达Controller并被处理。
  3. postHandle():请求处理后,视图渲染前 按注册顺序逆序执行。
  4. afterCompletion():视图渲染后 按注册顺序逆序执行。

4.3 请求和响应体拦截器

RequestBodyAdvice, ResponseBodyAdvice主要发生在Controller执行前后

  1. preHandle():请求处理前
  2. beforeBodyRead请求体反序列化前
  3. @RequestBodyController方法参数绑定
  4. Controller请求处理
  5. beforeBodyWrite():响应体序列化之前
  6. postHandle():请求处理后
  7. 视图渲染
  8. afterCompletion():请求结束

4.4 @Controller 和 @RestController区别

@Controller用于定义一个 Spring MVC 控制器类。它通常用于返回视图(如 JSP 或 Thymeleaf
@RestController是 @Controller 和 @ResponseBody 的组合,用于开发 RESTful API。它将方法的返回值直接写入 HTTP 响应体中,通常返回 JSON 或 XML 格式的数据。

4.5 异常处理

@ExceptionHandler用于控制器类或方法中处理特定异常。它会捕获指定的异常并返回相应的响应如错误页面、错误消息等
@ControllerAdvice是一个全局异常处理器用于捕获应用中所有控制器抛出的异常。