Skip to content

SpringMVC 处理一个请求的流程

SpringMVC 作为一个基于请求-响应模型的框架,具有清晰的请求处理流程。下面详细介绍一个请求从接收到响应的完整流程:

请求处理流程概述

  1. 客户端发送请求:浏览器或其他客户端向服务器发送 HTTP 请求
  2. DispatcherServlet 接收请求:前端控制器接收所有的请求
  3. 处理器映射:确定由哪个 Controller 处理此请求
  4. 调用处理器:Controller 处理请求,生成模型数据
  5. 解析视图名:将逻辑视图名解析为实际视图对象
  6. 渲染视图:使用模型数据渲染视图
  7. 返回响应:将渲染后的视图返回给客户端

详细流程

  1. Tomcat 接受到请求之后,会交给DispatcherServlet进行处理

    • 当请求到达服务器后,Servlet 容器(如 Tomcat)根据 web.xml 配置或注解配置,将请求转发给 SpringMVC 的前端控制器 DispatcherServlet
    • DispatcherServlet 作为整个 SpringMVC 的核心控制器,负责协调和组织不同组件处理请求
  2. DispatcherServlet会根据URL路径找到对应的Handler

    • DispatcherServlet 使用 HandlerMapping 来确定哪个 Controller 应该处理请求
    • HandlerMapping 根据配置(如 @RequestMapping 注解)将请求 URL 映射到对应的 Controller 方法
    • 在这个阶段,还会确定拦截器链(Interceptor Chain)
  3. Handler就是加了@RequestMapping方法,通过反射来执行该方法

    • Handler 是 Controller 中的具体处理方法,通常通过 @RequestMapping(或其变体如 @GetMapping, @PostMapping)注解标识
    • DispatcherServlet 使用 HandlerAdapter 适配不同类型的处理器(Handler)
    • HandlerAdapter 通过反射机制调用目标 Controller 方法
  4. 在执行方法之前会解析方法参数,比如解析@RequestParam,@RequestHeader,@PathVariable等注解

    • SpringMVC 使用参数解析器(HandlerMethodArgumentResolver)解析控制器方法的参数
    • 不同类型的参数和注解对应不同的解析策略
    • 参数解析器从请求中提取数据,并转换为方法参数需要的类型
    • 除了常见的 @RequestParam, @RequestHeader, @PathVariable,还支持 @RequestBody, @ModelAttribute 等
  5. 解析的过程就是从请求中获取相对应的数据,比如请求parameters,请求头,然后把数据传给对应的参数

    • @RequestParam:从请求参数(query string 或 form data)中提取值
    • @RequestHeader:从 HTTP 请求头中提取值
    • @PathVariable:从 URL 路径变量中提取值
    • @RequestBody:从请求体中解析 JSON/XML 并转换为 Java 对象
    • 参数解析过程包括数据提取、类型转换和数据绑定
  6. 有了参数之后开始执行方法

    • 所有必要的参数准备好后,通过反射调用 Controller 方法
    • 方法执行过程中可能会调用 Service 层处理业务逻辑
    • 可能会访问数据库或其他外部资源
    • 方法执行可能会抛出异常,异常会被 SpringMVC 的异常处理机制捕获
  7. 方法执行后就会得到方法的返回值,SpringMVC会对返回值进行解析

    • 根据方法返回值类型和注解,SpringMVC 决定如何处理结果
    • 针对不同的返回值类型有不同的处理策略:
      1. 如果方法没有加@ResponseBody或者Controller不是@RestController,而返回值是字符串,那么会根据字符串去找对应的View视图
        • 返回的字符串被视为逻辑视图名
        • ViewResolver 将逻辑视图名解析为具体的 View 对象
        • View 对象使用模型数据渲染最终输出
      2. 如果方法加了@ResponseBody,那么就把返回值直接返回给客户端,如果返回结果是对象类型,还会把对象转成JSON字符串
        • 使用 HttpMessageConverter 将返回值转换为 HTTP 响应
        • 对于对象类型,通常使用 Jackson 或 Gson 等库转换为 JSON
        • 转换后的数据直接作为响应体返回客户端
  8. 响应生成并返回客户端

    • 无论是视图渲染结果还是直接返回的数据,最终都被封装为 HTTP 响应
    • 设置响应状态码、响应头和响应体
    • DispatcherServlet 将响应返回给 Servlet 容器,再由容器返回给客户端

拦截器在请求处理流程中的位置

拦截器(Interceptor)可以在请求处理的不同阶段介入:

  1. preHandle:在 Controller 方法执行前调用

    • 返回 true 继续执行链,返回 false 中断执行
    • 可用于权限检查、日志记录等
  2. postHandle:在 Controller 方法执行后、视图渲染前调用

    • 可以修改 ModelAndView
    • 如果方法抛出异常则不会被调用
  3. afterCompletion:在整个请求处理完成后调用

    • 无论方法是否抛出异常都会被调用
    • 通常用于清理资源

异常处理在请求流程中的位置

当处理过程中发生异常时:

  1. 首先检查是否有 @ExceptionHandler 方法处理异常
  2. 然后检查是否有 HandlerExceptionResolver 可以解析异常
  3. 如果都没有,异常会传播到 DispatcherServlet
  4. 最后可能会显示默认错误页面或返回错误状态码

总结

SpringMVC 的请求处理流程是一个精心设计的责任链,每个组件负责特定的功能:

  • DispatcherServlet 作为中央控制器协调整个流程
  • HandlerMapping 确定请求的处理器
  • HandlerAdapter 适配不同类型的处理器
  • 参数解析器解析方法参数
  • 视图解析器和视图负责结果的渲染

理解这个流程有助于更好地使用 SpringMVC,处理常见问题,以及在必要时进行自定义扩展。