Spring MVC 请求处理流程详解

发布于:2025-04-16 ⋅ 阅读:(21) ⋅ 点赞:(0)
步骤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。

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

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



网站公告

今日签到

点亮在社区的每一天
去签到