SpringMVC的处理流程
深入理解 SpringMVC 的请求处理流程:从用户请求到视图渲染的八个步骤
SpringMVC 是当前流行的基于 Java 的 Web 框架之一,它通过前端控制器 DispatcherServlet
将用户的 HTTP 请求统一接收并处理,随后将请求分发到具体的处理器(通常是控制器方法),再通过视图解析器生成最终的响应视图。这一流程的实现使得 SpringMVC 框架具备了高扩展性、可插拔的特点,适用于大多数 Web 应用开发。
在这篇博客中,我们将以八个步骤的流程,深入解析从用户请求发送到视图渲染的整个过程,帮助你理解 SpringMVC 是如何处理 HTTP 请求的。
1. 用户请求发送到前端控制器 DispatcherServlet
SpringMVC 的核心是 DispatcherServlet
,它是整个框架的前端控制器(Front Controller)。当用户通过浏览器发送 HTTP 请求时,DispatcherServlet
首先接收到该请求,并开始对其进行处理。所有的请求都会先到达 DispatcherServlet
,这是 SpringMVC 中的统一入口。
DispatcherServlet
的职责是将请求转发给合适的组件(处理器或控制器),并协调整个请求处理的流程。这一设计模式确保了请求的集中管理和分发。
2. HandlerMapping
根据请求路径获取对应的处理器执行链 (HandlerExecutionChain
)
收到用户请求后,DispatcherServlet
会调用 HandlerMapping
来根据请求的路径解析出具体的处理器执行链(HandlerExecutionChain
)。这个执行链包含了两个部分:
- 处理器方法(
HandlerMethod
):即将实际处理请求的控制器方法。 - 拦截器(
HandlerInterceptor
):在处理请求前后执行的拦截器,用于预处理和后处理。
HandlerMapping
的作用是根据 URL 路径找到与该请求匹配的处理器和拦截器链。通过这种方式,SpringMVC 可以将请求精准地分发到具体的控制器方法。
3. 根据处理器方法 (HandlerMethod
) 找到对应的处理器适配器 (HandlerAdapter
)
由于 SpringMVC 支持多种类型的控制器(如注解控制器、传统接口控制器等),为了使 DispatcherServlet
能够统一调用不同类型的控制器,Spring 引入了 HandlerAdapter
适配器模式。
在这一阶段,DispatcherServlet
会根据找到的 HandlerMethod
选择对应的 HandlerAdapter
,使得处理器方法能够被正确调用。HandlerAdapter
负责将处理器与 DispatcherServlet
进行适配,这样无论处理器类型如何,都能够以一致的方式调用。
4. 调用拦截器的 preHandle
方法
在执行处理器方法之前,SpringMVC 会先调用处理器执行链中的拦截器的 preHandle
方法。拦截器可以在处理器执行之前对请求进行一系列的预处理,例如权限校验、日志记录、请求参数的处理等。
preHandle
方法的返回值为 true
时,表示继续调用下一个拦截器或处理器方法;如果返回 false
,则请求将被中止,不会继续执行处理器方法。
5. 处理器适配器执行处理器方法,并返回 ModelAndView
在所有拦截器的 preHandle
方法执行完毕且没有中止请求的情况下,处理器适配器(HandlerAdapter
)会调用处理器方法来处理用户请求。处理器方法执行的结果通常是一个包含视图名称和模型数据的 ModelAndView
对象。
- 模型数据(Model):是将数据传递给视图进行展示的容器。
- 视图名称(ViewName):是指向具体视图文件的名称(例如 JSP 或 Thymeleaf 模板)。
这个阶段的关键是处理器方法执行业务逻辑,并生成数据和视图名称,以供接下来的视图解析和渲染使用。
6. 调用拦截器的 postHandle
方法
处理器方法执行完毕,并返回 ModelAndView
之后,SpringMVC 会调用拦截器的 postHandle
方法。这个方法在视图渲染之前执行,通常用于对返回的 ModelAndView
进行进一步的处理。
比如,你可以在 postHandle
中对模型数据进行修改或增加,或根据处理结果动态调整视图名称。如果返回的 ModelAndView
是空的,SpringMVC 将跳过该步骤,不调用 postHandle
。
7. 视图解析器 (ViewResolver
) 解析 ModelAndView
,生成视图 (View
),并进行渲染
在控制器方法返回了 ModelAndView
之后,DispatcherServlet
会将其交给视图解析器(ViewResolver
)。视图解析器根据 ModelAndView
中的视图名称,找到具体的视图模板,并将模型数据传递给视图,最终生成 HTML 响应。
视图解析器可以使用多种模板引擎(如 JSP、Thymeleaf、Freemarker 等)来生成视图,最终的 HTML 页面会返回给客户端。
8. 最后,调用拦截器的 afterCompletion
方法
视图渲染完成后,SpringMVC 会调用拦截器的 afterCompletion
方法。这一方法无论请求是否正常处理完毕,都会被执行。它通常用于资源清理、日志记录或处理异常情况。
通过 afterCompletion
,拦截器可以对整个请求流程进行收尾处理,确保请求生命周期中的资源得到有效管理。
总结
SpringMVC 请求处理的八个步骤:
- 用户请求发送到前端控制器
DispatcherServlet
HandlerMapping
根据请求路径获取处理器执行链,处理器执行链包含了处理器方法handlerMethod
和拦截器。- 根据处理器方法找到处理器适配器
HandlerAdapter
- 调用拦截器的
preHandle
方法 - 处理器适配器执行处理器方法,返回
ModelAndView
- 调用拦截器的
postHandle
方法 - 视图解析器
ViewResolver
解析modelAndView得的视图view并渲染 - 调用拦截器的
afterCompletion
方法
通过这八个步骤,SpringMVC 实现了从请求接收、控制器处理、视图渲染到资源清理的完整生命周期。理解这些步骤有助于更深入地掌握 SpringMVC 框架的运作原理,提高开发效率和代码的可维护性。
相关文章:

SpringMVC的处理流程
深入理解 SpringMVC 的请求处理流程:从用户请求到视图渲染的八个步骤 SpringMVC 是当前流行的基于 Java 的 Web 框架之一,它通过前端控制器 DispatcherServlet 将用户的 HTTP 请求统一接收并处理,随后将请求分发到具体的处理器(通…...

SpringBoot统一日志框架
在项目开发中,日志十分的重要,不管是记录运行情况还是定位线上问题,都离不开对日志的分析。 1.日志框架的选择 市面上常见的日志框架有很多,它们可以被分为两类:日志门面(日志抽象层)和日志实…...

vue-live2d看板娘集成方案设计使用教程
文章目录 前言v1.1.x版本:vue集成看板娘(暂不使用,在v1.2.x已替换)集成看板娘实现看板娘拖拽效果方案资源备份存储 当前最新调研:2024.10.2开源方案1:OhMyLive2D(推荐)开源方案2&…...

springboot接口如何支持400并发量
Spring Boot 本身并不直接限制并发量,但是你可以通过配置来优化应用以处理更多的并发请求。以下是一些关键配置和优化技巧: 服务器连接配置(application.properties 或 application.yml): # 服务器连接数配置 server.tomcat.max…...

Verilog中的: `+:` 和 `-:`
: 和 -: 标准解释 logic [15:0] down_vect; logic [0:15] up_vect;down_vect[lsb_base_expr : width_expr] up_vect [msb_base_expr : width_expr] down_vect[msb_base_expr -: width_expr] up_vect [lsb_base_expr -: width_expr]举例 reg [31:0] dword; reg [7:0] byte0…...

为何四次挥手要等待2MSL
参考文章:https://zhuanlan.zhihu.com/p/204988465 A主动关闭连接一方,B是被动关闭一方 我们假设A发送了ACK报文后过了一段时间t之后B才收到该ACK,则有 0 < t < MSL。因为A并不知道它发送出去的ACK要多久对方才能收到,所以…...

C++——模拟实现list
1.初步实现结点和链表 namespace jxy {template<class T>struct list_node{T _data;list_node<T>* _prev;list_node<T>* _next;list_node(const T& x T()):_data(x),_prev(nullptr),_next(nullptr){}};template<class T>class list//list的框架本…...

React中useState、useReducer与useRef
useState 详解 useState 是 React 函数组件中用于管理组件状态的 Hook。它提供了一种简洁的方式来在函数组件中添加状态,并在状态改变时触发组件重新渲染。以下是 useState 的详细解析: 一、基本概念 useState 是一个函数,它接收一个初始状…...

ReGCL Rethinking Message Passingin Graph Contrastive Learning
AAAI24 推荐指数: #paper/⭐ 总体说:利用梯度对对比正负样本加权的。个人觉得和与正负样本加权没有区别,读完之后不想做笔记了。...

ubutun安装ffmpeg
安装依赖 sudo apt-get install yasm sudo apt-get install libsdl1.2-dev sudo apt-get install libsdl2-dev 下载安装 tar -zxvf filename.gz ./configure --enable-shared --prefix/usr/local/ffmpeg make -j4 sudo make install 添加路径 路径/usr/local/ffmpeg…...

Vue的基本用法及模板语法
Vue.js使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue实例的数据。所有 Vue.js的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。 在底层的实现上,Vue将模板编译成虚拟 DOM 渲染函数。结合响应系…...

Redis数据库与GO完结篇:redis操作总结与GO使用redis
一、redis操作总结 由于写redis命令的时候有提示符,所以下表只给出命令名称 数据类型操作简介字符串GET, SET, MGET, MSET, SETEX,DEL最基本的数据类型,存储任意二进制数据,支持简单操作和原子计数。适合存储重复数据。哈希HSET, HGET, HDE…...

《重生到现代之从零开始的C语言生活》—— 动态内存管理
动态内存分配 我们在开辟内存的时候就是 int a 3;这样 但是这样开的空间大小是固定的,且大小不能调整 但是如果我们用动态内存开辟的话,就可以自己申请和释放空间、 malloc 是C语言提供的一个开辟动态空间的函数 void* malloc (size_t size);//si…...

四、Spring Boot集成Spring Security之登录登出业务逻辑
Spring Boot集成Spring Security之登录登出业务逻辑 一、概要说明二、基于内存的用户名密码1、默认用户名密码2、自定义用户名密码3、为方便测试添加测试接口TestController 三、登录登出重要概念介绍四、登录业务逻辑1、登录业务相关过滤器2、访问业务请求处理流程①、访问业务…...

pipe和pipefd
Linux 中 pipe 的详细介绍 在 Linux 中,pipe 是一个系统调用,用于创建一个管道,这是一种用于进程间通信(IPC)的机制。管道允许两个进程之间进行单向数据传输,通常是一个进程向管道写入数据,而另…...

无人机之飞控仿真技术篇
一、无人机飞控仿真技术的定义 无人机飞控仿真技术主要是指飞行控制系统仿真,它是以无人机的运动情况为研究对象,面向对象的复杂系统仿真。通过该技术,可以模拟无人机的飞行过程,评估飞行控制系统的性能,优化飞行参数&…...

Tetra Pak利乐触摸屏维修beijer北尔触摸屏维修E1151
TetraPak利乐包装机触摸显示屏维修,北尔全系列型号触摸屏修理 维修注意事项: 上电前,应检查负载是否接上或是否正确; 测量电压时,确认档位是否在电压档。要确认仪器仪表的量程应大于测试点的电压; 更换电…...

Python_网络编程(IP 端口 协议)
网络编程: 互联网时代,现在基本上所有的程序都是网络程序,很少有单机版的程序了。网络编程就是如何在程序中实现两台计算机的通信。Python语言中,提供了大量的内置模块和第三方模块用于支持各种网络访问,而且Python语言…...

Adobe Acrobat提示“3D数据解析错误”
原因:在使用Adobe Acrobat打开3D PDF时,因当前Adobe Acrobat的配置存在错误,所以无法打开 解决方法:重新生成配置 首先到达下面的路径C:\Users\你的用户名\AppData\Local\Adobe\Acrobat 下面为我的路径内容 若该路径下存在文件…...

红帽7—Mysql路由部署
MySQL Router 是一个对应用程序透明的InnoDB Cluster连接路由服务,提供负载均衡、应用连接故障转移和客户端路 由。 利用路由器的连接路由特性,用户可以编写应用程序来连接到路由器,并令路由器使用相应的路由策略 来处理连接,使其…...

LLM4Rec最新工作: 字节发布用于序列推荐的分层大模型HLLM
前几个月 Meta HSTU 点燃各大厂商对 LLM4Rec 的热情,一时间,探索推荐领域的 Scaling Law、实现推荐的 ChatGPT 时刻、取代传统推荐模型等一系列话题让人兴奋,然而理想有多丰满,现实就有多骨感,尚未有业界公开真正复刻 …...

怎么高效对接SaaS平台数据?
SaaS平台数据对接是指将一个或多个SaaS平台中的数据集成到其他应用或平台中的过程。在当前的数字化时代,企业越来越倾向于使用SaaS平台来管理他们的业务和数据。然而,这些数据通常散布在不同的SaaS平台中,这对于企业数据的整合和分析来说可能…...

Spark算子使用-Map,FlatMap,Filter,diatinct,groupBy,sortBy
目录 Map算子使用 FlatMap算子使用 Filter算子使用-数据过滤 Distinct算子使用-数据去重 groupBy算子使用-数据分组 sortBy算子使用-数据排序 Map算子使用 # map算子主要使用长场景,一个转化rdd中每个元素的数据类型,拼接rdd中的元素数据…...

CSS响应式布局
CSS 响应式布局也称自适应布局,是 Ethan Marcotte 在 2010 年 5 月份提出的一个概念,简单来讲就是一个网站能够兼容多个不同的终端(设备),而不是为每个终端做一个特定的版本。这个概念是为解决移动端浏览网页而诞生的。…...

AI大模型书籍丨掌握 LLM 和 RAG 技术,这本大模型小鸟书值得一看!
本指南旨在帮助数据科学家、机器学习工程师和机器学习/AI 架构师探索信息检索与 LLMs 的集成及其相互增强。特别聚焦于 LLM 和检索增强生成(RAG)技术在信息检索中的应用,通过引入外部数据库与 LLMs 的结合,提高检索系统的性能。 …...

Mysql和Oracle使用差异和主观感受
这两种常用的关系型数据库有何差异? 支持和社区 MySQL:有一个活跃的开源社区,用户可以获取大量的文档和支持。 Oracle:提供了专业的技术支持,但通常需要额外的费用。 易用性 MySQL:通常被认为是更易于学…...

【Java】—— File类与IO流:File类的实例化与常用方法
目录 1. java.io.File类的使用 1.1 概述 1.2 构造器 1.3 常用方法 1、获取文件和目录基本信息 2、列出目录的下一级 3、File类的重命名功能 4、判断功能的方法 5、创建、删除功能 1.4 练习 练习1: 练习2: 练习3: 1. java.io.Fil…...

C++设计模式——装饰器模式
欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 什么是装饰器模式? 装饰器模式(Decorator Pattern)是一种结构型设计模式,允许你向一个现有的对象添加新的功能,同时又不改变其结构。这种模式通过创…...

C#使用ITextSharp生成PDF文件实例详解
许多项目开发中需要生成PDF, 常规办法使用官方提供的Microsoft.Office.Interop.Worddll插件,但是这种方法需要完全安装OFFICE,另外版本不一致还会出现很多错误。一般不推荐使用。 下面介绍这种巧妙的用法,定能事半功倍。 本文使用ITextSharp完成功能。 首先,通过NuGet…...

10.9QT对话框以及QT的事件机制处理
MouseMoveEvent(鼠标移动事件) widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 设置窗口为无边框,去掉标题栏等装饰this->setWi…...