← 返回题目列表

Spring MVC 的请求处理流程是怎样的?

高频 中等 第 13 / 30 题 更新于 2026/07/26
Spring MVCDispatcherServletHandlerMappingHandlerAdapter

简化版

请求进入 DispatcherServlet 后,由 HandlerMapping 找到处理器和拦截器链,再由 HandlerAdapter 调用 Controller。返回值随后要么通过 HttpMessageConverter 写成响应体,要么经 ViewResolver 解析并渲染视图;异常则交给 HandlerExceptionResolver 链处理。

详细版

核心流程是:Servlet 容器过滤器 → DispatcherServlet → HandlerMapping → HandlerExecutionChain → HandlerAdapter → 参数解析与 Controller → 返回值处理 → 消息转换或视图渲染 → 响应。DispatcherServlet 是前端控制器,负责协调组件,而不是自己完成所有参数绑定、业务调用和序列化。

@RequestBody 通常由 HttpMessageConverter 读取请求体,@ResponseBody@RestController 的返回值由它写入响应;返回视图名时则由 ViewResolver 找到 View 后渲染。拦截器围绕 Handler 执行,Filter 位于 Servlet 链外层,两者职责和作用范围不同。

完整版教学

一、DispatcherServlet 是总调度器

浏览器请求先由 Servlet 容器接收,匹配的 Filter 在进入 Servlet 前执行。请求到达 DispatcherServlet 后,它使用容器中配置的策略组件完成映射、调用、异常处理和渲染。

前端控制器模式的价值,是 Controller 不需要自行寻找其他 Controller 或决定如何渲染响应。公共流程集中在一个入口,不同扩展点各司其职。

二、HandlerMapping 找到谁来处理

HandlerMapping 根据请求路径、HTTP 方法、请求头等条件查找 Handler。注解式 MVC 中,常见结果是一个 HandlerMethod,它封装 Controller Bean 和目标方法。

返回的通常不只是 Handler,而是 HandlerExecutionChain,其中还包含匹配的 HandlerInterceptor。多个 HandlerMapping 可以共存并按顺序尝试,因此 DispatcherServlet 不依赖某一种固定映射方式。

三、HandlerAdapter 为什么存在

DispatcherServlet 面对的 Handler 形式可能不同,不应写死调用方式。HandlerAdapter 把“如何执行这种 Handler”适配成统一流程;注解 Controller 通常由 RequestMappingHandlerAdapter 处理。

调用目标方法之前,参数解析器会处理 @PathVariable@RequestParam、Model、Servlet API 等参数;需要读取 @RequestBody 时,再选择能够处理目标媒体类型和 Java 类型的 HttpMessageConverter。数据绑定、类型转换和校验也在这一阶段协作完成。

四、Controller 返回后如何生成响应

返回值先交给 HandlerMethodReturnValueHandler 体系判断语义:

  • @ResponseBody@RestController:选择合适的 HttpMessageConverter,把对象写为 JSON、文本等响应体;
  • 视图名或 ModelAndView:整理模型和视图名,再由 ViewResolver 解析 View 并渲染;
  • ResponseEntity:同时表达状态码、响应头和响应体;
  • 异步返回类型:启动异步处理,结果就绪后再恢复后续分派流程。

所以“Controller 返回对象就由 Jackson 序列化”并不完整。Spring 先按返回值处理器确定语义,JSON 只是某个消息转换器在内容协商后可能选择的格式。

五、异常处理链

Controller、参数解析或拦截器发生异常时,DispatcherServlet 会尝试交给 HandlerExceptionResolver 链。@ExceptionHandler@ControllerAdvice、状态码映射等能力都通过相应 resolver 参与处理。

若某个 resolver 生成了可用的 ModelAndView 或直接完成响应,请求可以转为正常错误响应;无人处理的异常才继续交给 Servlet 容器。全局异常处理仍应区分业务错误、参数错误和系统错误,避免一律返回 HTTP 200。

六、Filter 与 Interceptor 的区别

Filter 属于 Servlet 规范,包围 Servlet,可处理静态资源或非 Spring MVC 请求,适合编码、跨域、基础安全和请求包装。Interceptor 属于 Spring MVC,围绕已映射的 Handler 工作,能获得 Handler 信息,适合登录检查、审计和通用 Controller 逻辑。

Interceptor 的典型阶段是 preHandlepostHandleafterCompletionpreHandle 返回 false 会中止后续 Handler 调用;异步请求还涉及额外的异步回调和再次分派,不能把同步请求的时序原样套用。

七、用一次 REST 请求串起组件

POST /orders、请求体 512 字节 JSON 为例,Filter 可以先记录请求或完成认证;DispatcherServlet 找到 OrderController#create 后,参数解析器识别 @RequestBody,消息转换器把 JSON 读成 CreateOrderRequest。Controller 返回 ResponseEntity<OrderView> 时,返回值处理器先确定状态码和响应头,再由合适的消息转换器写出响应体,不会进入传统视图渲染。

HTTP request
  → Filter chain
  → DispatcherServlet
  → HandlerMapping
  → HandlerExecutionChain.preHandle
  → HandlerAdapter
      → ArgumentResolver / DataBinder / Validator
      → Controller method
      → ReturnValueHandler / HttpMessageConverter
  → postHandle(同步正常流程)
  → afterCompletion
  → HTTP response
扩展点主要输入主要职责常见用途
FilterServletRequest/Response包围 Servlet 链请求包装、基础安全、编码
HandlerInterceptorHandler + 请求包围 MVC Handler鉴权、审计、Controller 指标
ArgumentResolver方法参数描述构造 Controller 参数当前用户、自定义分页对象
HttpMessageConverterHTTP body 与 Java 类型读写消息体JSON、文本、二进制
HandlerExceptionResolver异常与 Handler转换异常结果局部或全局异常响应

内容协商还要结合 Content-TypeAccept。请求声明 JSON 却发送不能解析的内容,可能在进入 Controller 前就失败;客户端只接受一种服务器无法提供的媒体类型,也会在返回值处理阶段产生相应错误。

记忆钩子:Mapping 解决“谁处理”,Adapter 解决“怎么调用”,ReturnValueHandler 解决“返回值代表什么”,Converter 才负责“消息体怎样读写”。

八、常见误区与追问

  • 误区:DispatcherServlet 自己完成参数绑定、业务调用和 JSON 序列化。 它是协调者,实际工作由 HandlerMapping、HandlerAdapter、参数与返回值处理器、消息转换器等组件完成。
  • 误区:Controller 返回对象就一定由 Jackson 转成 JSON。 返回值处理器先判断语义,随后才在内容协商结果中选择合适的 HttpMessageConverter;Jackson 只是常见实现。
  • 误区:Filter 和 Interceptor 的执行位置完全相同。 Filter 属于 Servlet 链并包围 DispatcherServlet,Interceptor 只围绕已经映射到的 MVC Handler。
  • 追问:@RequestBody 读取失败发生在 Controller 前还是后? 通常在 HandlerAdapter 解析方法参数时发生,目标 Controller 方法尚未真正执行。
  • 追问:异常一定会进入 @ControllerAdvice 吗? 只有相应 HandlerExceptionResolver 能匹配并处理时才会转换;未处理异常仍会继续传播给 Servlet 容器。
  • 追问:postHandle 为什么有时不执行? Handler 抛异常或异步处理改变同步流程时可能不会走普通 postHandle;对于 preHandle 已成功返回 true 的拦截器,afterCompletion 承担请求完成通知语义,异步场景还需结合再次分派分析。

九、加强记忆

记住一条调度链:DispatcherServlet 收口,HandlerMapping 找人,HandlerAdapter 调人,返回值处理器定语义,消息转换器写响应体或 ViewResolver 找视图,异常交给 Resolver。Filter 在 Servlet 外层,Interceptor 在 MVC Handler 周围。