Spring MVC 请求处理流程步骤详解

 更新时间:2025年04月15日 09:48:21   作者:云之兕  
这篇文章主要介绍了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 方法)。
  • 适配过程
    • 解析方法参数(如 @RequestParam@RequestBody)。
    • 执行方法逻辑。
    • 处理返回值(如 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)。

源码级流程解析(简化版)

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。
  • 扩展点:拦截器、异常处理器、自定义参数解析器。
  • 设计思想:职责分离、组件化、高度可定制。

到此这篇关于Spring MVC 请求处理流程详解的文章就介绍到这了,更多相关Spring MVC 请求处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springcould多模块搭建Eureka服务器端口过程详解

    Springcould多模块搭建Eureka服务器端口过程详解

    这篇文章主要介绍了Springcould多模块搭建Eureka服务器端口过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java语言字典序排序算法解析及代码示例

    Java语言字典序排序算法解析及代码示例

    这篇文章主要介绍了Java语言字典序排序算法解析及代码示例,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • 将SpringBoot项目的HTTP站点改为HTTPS的全过程

    将SpringBoot项目的HTTP站点改为HTTPS的全过程

    本文介绍了如何在Spring Boot项目中实现HTTPS请求,首先,创建一个Spring Boot项目并编写一个BasicController.java文件,然后,配置application.yaml文件以支持HTTPS,接着,使用Java自带的keytool工具生成一个免费的HTTPS证书,需要的朋友可以参考下
    2026-02-02
  • springboot整合sentinel接口熔断的实现示例

    springboot整合sentinel接口熔断的实现示例

    为了防止慢接口导致的服务阻塞,可以通过添加熔断处理来避免应用的大量工作线程陷入阻塞,保证其他接口的正常运行,本文介绍了如何使用Spring Boot与Sentinel进行接口熔断的配置与实现,感兴趣的可以了解一下
    2024-09-09
  • Java基础之详细总结五种常用运算符

    Java基础之详细总结五种常用运算符

    在通常代码逻辑处理中,我们常常都会使用到运算符,今天我们就详细了解一下运算符的使用以及分类.运算符是对常量或者变量进行操作的符号,它分为算术运算符,赋值运算符,比较运算符,逻辑运算符以及位运算符.需要的朋友可以参考下
    2021-05-05
  • java面试常问的Runnable和Callable的区别

    java面试常问的Runnable和Callable的区别

    大家好,本篇文章主要讲的是java面试常问的Runnable和Callable的区别,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • Java中关于isEmpty方法、null以及““的区别

    Java中关于isEmpty方法、null以及““的区别

    这篇文章主要介绍了Java中关于isEmpty方法、null以及““的区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • JAVA8 List<List<Integer>> list中再装一个list转成一个list操作

    JAVA8 List<List<Integer>> list中再装一个list转成一个list操

    这篇文章主要介绍了JAVA8 List<List<Integer>> list中再装一个list转成一个list操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • SpringBoot对Filter过滤器中的异常进行全局处理方案详解

    SpringBoot对Filter过滤器中的异常进行全局处理方案详解

    这篇文章主要介绍了SpringBoot对Filter过滤器中的异常进行全局处理,在SpringBoot中我们通过 @ControllerAdvice 注解和 @ExceptionHandler注解注册了全局异常处理器,需要的朋友可以参考下
    2023-09-09
  • Spring中的ImportSelector接口原理解析

    Spring中的ImportSelector接口原理解析

    这篇文章主要介绍了Spring中的ImportSelector接口原理解析,ImportSelector接口是spring中导入外部配置的核心接口,根据给定的条件(通常是一个或多个注释属性)判定要导入那个配置类,需要的朋友可以参考下
    2024-01-01

最新评论