当前位置: 首页 > news >正文

Spring MVC 请求处理流程详解

步骤1:用户发起请求
  • 所有请求首先被 DispatcherServlet(前端控制器)拦截,它是整个流程的入口。

  • DispatcherServlet 继承自 HttpServlet,通过 web.xml 或 WebApplicationInitializer 配置映射路径(如 /)。

步骤2:请求映射(Handler Mapping)
  • HandlerMapping 根据请求的 URL、参数、Header 等信息,找到对应的 处理器(Handler)

    • 处理器 可以是 @Controller 注解的类中的方法,或实现 Controller 接口的类。

    • 关键接口RequestMappingHandlerMapping(处理 @RequestMapping 注解)。

  • 匹配规则

    @Controller
    public class UserController {
        @GetMapping("/users/{id}")
        public String getUser(@PathVariable Long id, Model model) {
            // 业务逻辑
        }
    }
步骤3:处理器适配(Handler Adapter)
  • HandlerAdapter 负责调用处理器方法,并处理参数绑定、返回值转换。

    • 关键实现类RequestMappingHandlerAdapter(支持 @RequestMapping 方法)。

    • 适配过程

      1. 解析方法参数(如 @RequestParam@RequestBody)。

      2. 执行方法逻辑。

      3. 处理返回值(如 ModelAndView、JSON 数据)。

步骤4:执行拦截器(Interceptor)
  • HandlerInterceptor 在处理器执行前后插入逻辑:

    • preHandle:在处理器方法执行前调用(如权限校验)。

    • postHandle:在处理器方法执行后、视图渲染前调用。

    • afterCompletion:在请求完成后调用(资源清理)。

步骤5:业务逻辑处理
  • 控制器方法执行业务逻辑,可能涉及:

    • 调用 Service 层处理数据。

    • 操作 Model 对象向视图传递数据。

      @GetMapping("/users")
      public String listUsers(Model model) {
          List<User> users = userService.findAll();
          model.addAttribute("users", users); // 数据传递到视图
          return "user/list"; // 视图名称
      }

步骤6:视图解析(View Resolver)
  • ViewResolver 将控制器返回的视图名称解析为具体的 View 对象。

    • 常见实现

      • InternalResourceViewResolver:解析 JSP 页面(如 /WEB-INF/views/user/list.jsp)。

      • ThymeleafViewResolver:解析 Thymeleaf 模板。

    • 配置示例

      @Bean
      public ViewResolver viewResolver() {
          InternalResourceViewResolver resolver = new InternalResourceViewResolver();
          resolver.setPrefix("/WEB-INF/views/");
          resolver.setSuffix(".jsp");
          return resolver;
      }
步骤7:视图渲染(View Rendering)
  • View 对象将模型数据渲染到响应中(如生成 HTML、JSON)。

    • 渲染方式

      • JSP:使用 JSTL 或 EL 表达式填充数据。

      • REST API:通过 HttpMessageConverter 将返回值序列化为 JSON(如 @ResponseBody)。

步骤8:返回响应
  • 渲染后的响应通过 DispatcherServlet 返回给客户端。

 


 关键组件与接口

组件职责
DispatcherServlet前端控制器,统一调度请求处理流程。
HandlerMapping映射请求到处理器(Controller 方法)。
HandlerAdapter调用处理器方法,处理参数绑定与返回值。
ViewResolver解析视图名称到具体视图实现(如 JSP、Thymeleaf)。
HandlerInterceptor拦截请求,实现预处理和后处理逻辑(如日志、权限校验)。
HttpMessageConverter处理请求/响应的数据转换(如 JSON ↔ Java 对象)。

异常处理机制

  • @ExceptionHandler:在 Controller 内处理特定异常。

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
  • HandlerExceptionResolver:全局异常解析器,自定义异常响应。

  • @ControllerAdvice:定义全局异常处理类。

    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(Exception.class)
        public ModelAndView handleAllExceptions(Exception ex) {
            ModelAndView mav = new ModelAndView("error");
            mav.addObject("message", ex.getMessage());
            return mav;
        }
    }


 RESTful 请求处理

  • @RestController:组合 @Controller 和 @ResponseBody,直接返回数据。

    @RestController
    @RequestMapping("/api/users")
    public class UserApiController {
        @GetMapping("/{id}")
        public User getUser(@PathVariable Long id) {
            return userService.findById(id);
        }
    }
  • 内容协商:根据请求的 Accept Header 返回 JSON/XML 等格式(通过 HttpMessageConverter)。


源码级流程解析(简化版)
  1. DispatcherServlet.doDispatch()

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerExecutionChain mappedHandler = getHandler(request); // 获取处理器链
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
        processDispatchResult(request, response, mappedHandler, mv, dispatchException);
    }

    2.参数解析:通过 HandlerMethodArgumentResolver 解析方法参数。

    3.返回值处理:通过 HandlerMethodReturnValueHandler 处理返回值。


总结
  • 核心流程:DispatcherServlet → HandlerMapping → HandlerAdapter → Interceptor → ViewResolver。

  • 扩展点:拦截器、异常处理器、自定义参数解析器。

  • 设计思想:职责分离、组件化、高度可定制。


相关文章:

  • MySQL联合查询||多表查询
  • Ubuntu安装Docker容器,通过Tomcat部署项目
  • Linux服务之网络共享
  • 深度学习总结(13)
  • 抢票方案推荐(推荐语言)
  • C 语言中经典的数据结构
  • 鲲鹏+昇腾部署集群管理软件GPUStack,两台服务器搭建双节点集群【实战详细踩坑篇】
  • Redis存储“大数据对象”的常用策略及StackOverflowError错误解决方案
  • 第二十六:Mysql 慢查询 开启
  • Ollama模型显存管理机制解析与Flask部署方案对比
  • 【场景应用7】在TPU上使用Flax/JAX对Transformers模型进行语言模型预训练
  • TCPIP详解 卷1协议 六 DHCP和自动配置
  • WinForm真入门(16)——LinkLabel 控件详解
  • vue开发基础流程 (后20)
  • JMeter重要的是什么
  • Java 系统设计:如何应对高并发场景?
  • 阿里云服务器 Ubuntu如何使用git clone
  • 2025年SP SCI2区:自适应灰狼算法IGWO,深度解析+性能实测
  • LLM Post-Training
  • LeetCode[541]反转字符串Ⅱ
  • 剪纸纹样“流动”在水乡,谁不忆江南
  • 男子称喝中药治肺结节三个月后反变大增多,自贡卫健委回应
  • 马上评丨一些影视剧的片名,越来越让人看不懂
  • 外交部回应美财长涉中国发展经济模式言论:损害各国人民共同利益的是美方
  • 一夜跌去200美元,黄金巨震冲上热搜!涨势已近尾声?
  • 上海常务副市长:持续提升跨境投融资便利化水平,稳步扩大金融领域的制度型开放