【Spring MVC研究】DispatcherServlet如何处理请求(doDispatcher方法)
文章目录
- 1. 最经典的MVC的使用情况
- 2. 经典情况相关的组件
- 3. 执行
- 3.1. 先看DispatcherServlet的总体过程
- 3.2. 再看`RequestMappingHandlerAdapter`的总体过程
- 3.2.1. RequestParamMethodArgumentResolver
- 3.2.2. 反射调用 Controller 的方法
- 3.2.3. RequestResponseBodyMethodProcessor
- 4. 总结
本文以“最经典”的情况分析了 DispatcherServlet 处理请求的全部过程。通读全文,读者应该对总体框架有一定的认识,且要求今后能有能力把 mvc 的其他组件原理“嵌入到总体框架中”。
1. 最经典的MVC的使用情况
这个过程很长,设计的到 web 组件很多,所以需要以一个最常见的情况作为“经典情况”来简化分析过程。突破之后再在对总体流程和框架的基础上,往上面新的补充内容。为了方便我讲解,我以:
“经典情况”是:Controller 中的@RequestMapping,方法的参数贴了@RequestParam注解,返回值上贴了@ResponseBody注解
搞完“经典情况”,后续的其他 mvc 组件作者会一个一个的分析。
2. 经典情况相关的组件
RequestMappingHandlerMapping(请求映射器)
功能:把请求 request 映射到 handler;根据路径匹配
对应关系:只要我们的 Controller 写的路径匹配上了请求就可以了,假设匹配上。
HandlerMethod(处理请求)
功能:具体处理请求的
对应关系:对应是 Controller 中的方法
HandlerExecutionChain(处理器链)
功能:等于“处理器” + “匹配的拦截器”
对应关系:这里就是等于:“HandlerMethod + 匹配到的拦截器MappedInterceptor”
RequestMappingHandlerAdapter(对HandlerExecutionChain 再次包装)
记住:反正就是由RequestMappingHandlerAdapter 开始执行的就可以了。
RequestParamMethodArgumentResolver(参数解析器)
功能:专门处理
@RequestParam注解的
对应关系:从请求 request 中解析出参数(调用 ServletRequest的 getParameterValues方法)
RequestResponseBodyMethodProcessor(返回值处理器)
功能:专门刚好处理
@ResponseBody注解。
3. 执行
3.1. 先看DispatcherServlet的总体过程
DispatcherServlet 的doDispatch方法的总体执行过程:
- getHandler(1)
- getHandlerAdapter(2)
- applyPreHandle(3)
- handle(重点:真正处理)(4)
- applyPostHandle(5)
在(1)处得到 HandlerExecutionChain,包含 HandlerMethod和 MappedInterceptor
在(2)处得到 RequestMappingHandlerAdapter
在(3)处,执行MappedInterceptor的 preHandle方法
在(4)处,执行 RequestMappingHandlerAdapter的 handler方法
在(5)处,执行MappedInterceptor的 postHandle方法
3.2. 再看RequestMappingHandlerAdapter的总体过程
继续看 RequestMappingHandlerAdapter的 handler方法的总体过程:
注意:执行顺序是从左到右从上到下执行的
- 封装为ServletInvocableHandlerMethod(1)
- invokeAndHandle
- invokeForRequest
- getMethodArgumentValues(解析参数)
- resolveArgument解析参数
- getArgumentResolver(得到“参数解析器”)
- resolveArgument(真正解析)
- resolveArgument解析参数
- doInvoke(具体执行)
- getMethodArgumentValues(解析参数)
- handleReturnValue(处理返回值)
- selectHandler
- handleReturnValue
- invokeForRequest
- getModelAndView(2)
主要就只有 3 个关键过程(上面已加粗说明):
1、按 Controller 方法的要求解析参数。用的是 RequestParamMethodArgumentResolver
2、执行 Controller 方法。
3、处理 Controller 方法的返回值。用的是 RequestResponseBodyMethodProcessor
下面简单提一下其他过程(按序号):
在(1)处,把真正的执行的组件HandlerMethod 一顿疯狂包装成ServletInvocableHandlerMethod
比如就包装了 web 数据绑定器:WebDataBinder
在(2)处,处理视图,现在都是前后端开发,不用视图技术了。作者不讲,略,自己搞。
3.2.1. RequestParamMethodArgumentResolver
- 支持的参数
在它的 supportsParameter 方法中,表明了支持“参数上贴了@RequestParam注解的参数”
- 执行解析参数
1、 调用RequestParamMethodArgumentResolver的resolveArgument方法,
2、 会调用到RequestParamMethodArgumentResolver 的resolveName方法
3、会调用到解析文件的multipartRequest方法 和 从请求获取参数的 request.getParameterValues方法
4、解析之后还没有结束,还需要转换成 Controller 方法需要的参数类型(略,这就是另外的小细节故事了)
截止目前:也就通过从请求中获取参数完成了 Controller 方法参数的解析,
3.2.2. 反射调用 Controller 的方法
没什么好讲的,反射调用 Controller 的方法。
3.2.3. RequestResponseBodyMethodProcessor
- 支持的类型
在supportsReturnType方法中表明了支持的类型是方法上@ResponseBody注解
- 处理返回值
1、会调用到RequestResponseBodyMethodProcessor 的 handleReturnValue方法
2、会调用writeWithMessageConverters方法
3、最后直接调用“消息转换器”messageConverters把“返回值写到流里面去了”
注意:既然既然写到响应流 response 里面去了,响应就结束了,后面的视图处理过程就没了。
4. 总结
读完全文,读者要求掌握以下组件的工作情况。(对细节不需要苛责,但是一定要能知道** 组件的功能 **和 **组件在流程中的位置**。
- RequestMappingHandlerMapping(请求映射器)
- HandlerMethod(处理请求)
- HandlerExecutionChain(处理器链)
- RequestMappingHandlerAdapter(对HandlerExecutionChain 再次包装)
- RequestParamMethodArgumentResolver(参数解析器)
- RequestResponseBodyMethodProcessor(返回值处理器)
相关文章:
【Spring MVC研究】DispatcherServlet如何处理请求(doDispatcher方法)
文章目录 1. 最经典的MVC的使用情况2. 经典情况相关的组件3. 执行3.1. 先看DispatcherServlet的总体过程3.2. 再看RequestMappingHandlerAdapter的总体过程3.2.1. RequestParamMethodArgumentResolver3.2.2. 反射调用 Controller 的方法3.2.3. RequestResponseBodyMethodProces…...
解决github加载过慢问题
github打不开怎么办?看到这篇文章,一切都稳了! DNS被污染,一句话,修改系统hosts文件! 1.hosts文件在哪?C:\Windows\System32\drivers\etc 2.用记事本打开hosts,在最后加入以下两行…...
利用python批量处理nc数据
参考自:用Python批处理指定数据-以WRF输出结果为例演示按照指定维度合并(附示例代码)-腾讯云开发者社区-腾讯云 #下面将分别展示选择单个变量进行合并以及将所有变量按照指定维度进行合并。 #1.以单个变量P为例,可以根据需求更改,按照时间顺…...
popen() 获取 ping 命令结果解析
ref: Linux:popen() 获取 ping 命令结果 用C/C代码检测ip能否ping通(配合awk和system可以做到批量检测)_c 验证网卡能拼同-CSDN博客 Android中调用Ping操作及结果分析 - 简书 2. Linux使用ping命令查看网络延迟 - 简书...
【pytorch】深度学习准备:基本配置
深度学习中常用包 import os import numpy as np import torch import torch.nn as nn from torch.utils.data import Dataset, DataLoader import torch.optim as optimizer超参数设置 2种设置方式:将超参数直接设置在训练的代码中;用yaml、json&…...
etcd随笔
大集群 大集群主要问题有 btree重平衡和分解过程中超过20Gi的性能瓶颈,是O(n)复杂度,启动耗时增大,放大expensive request的影响。 其中最重要的就是最大程度地减少 expensive request。 对几十万级别的对象数量来说…...
0基础学习VR全景平台篇 第107篇:全景图调色和细节处理(上,地拍)
上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 今天教给大家的课程是地拍全景图调色和细节处理,下面我们就开始吧! 1.把照片快速导入LR软件 选择【图库】模块 打开软件后,点击【导入】按…...
Verilog功能模块——同步FIFO
前言 FIFO功能模块分两篇文章,本篇为同步FIFO,另一篇为异步FIFO,传送门: Verilog功能模块——异步FIFO-CSDN博客 同步FIFO实现起来是异步FIFO的简化版,所以,本博文不再介绍FIFO实现原理,感兴趣…...
Unity ToLua热更框架使用教程(1)
从本篇开始将为大家讲解ToLua在unity当中的使用教程。 Tolua的框架叫LuaFramework,首先附上下载链接: https://github.com/jarjin/LuaFramework_UGUI_V2 这个地址的是UGUI的。 下载完之后导入项目,首先,我们要先让这个项目跑起…...
车载相关名词--车载数据中心方案
车载数据中心方案 参考链接:https://zhuanlan.zhihu.com/p/600031042?utm_id=0 下面这张图是小鹏汽车嵌入式系统高级专家 唐黾 在同ARM一起的一个演讲稿中发布的,是一张未来车载数据中心单芯片方案构想图。主要针对的是智驾域和座舱域融合方案,下面对如上图的内外部组件及…...
helm使用
前言 类似于 Linux 的 YUM、APT,Helm 是 K8S 的包管理工具。 Helm, 一个二进制工具,用来安装、升级、卸载 K8S 中的应用程序。 Helm Chart,一个 tgz 包,类似安卓的 APK。 K8S 应用打包成 Chart,通过 He…...
Python in Visual Studio Code 2023年10月发布
排版:Alan Wang 我们很高兴地宣布 Visual Studio Code 的 Python 和 Jupyter 扩展于 2023 年 10 月发布! 此版本包括以下公告: Python 调试器扩展更新弃用 Python 3.7 支持Pylint 扩展更换时的 Lint 选项Mypy 扩展报告的范围和守护程序模式G…...
Webmin远程命令执行漏洞复现报告
漏洞编号 CVE-2019-15107 漏洞描述 Webmin是一个基于Web的系统配置工具,用于类Unix系统。密码重置页面中存在此漏洞,允许未经身份验证的用户通过简单的 POST 请求执行任意命令。 影响版本 Webmin<1.920 漏洞评级 严重 利用方法(利…...
webstorm自定义文件模板(Vue + Scss)
最终效果如下: 具体配置如下: 新增文件代码如下: <!--* Description: ${COMPONENT_NAME} 页面* Author: mhf* Date: ${DATE} --> <template><div>${COMPONENT_NAME} </div> </template><script&g…...
楔子-写在之前
最近一年都在忙着一个项目,并且需要学习另一个领域的知识,从单片机过渡到了LINUX嵌入式,倒静不下心去写点东西。看了下之前写的东西,感觉已经过去了很久很久。现在项目快忙完了,准备把最近的心得给大家分享下。 前言 …...
第 5 章 数组和广义表(稀疏矩阵的三元组顺序表存储实现)
1. 背景说明 为了节省存储空间,可以对这类矩阵进行压缩存储。所谓压缩存储是指:为多个值相同的元只分配一个存储空间,对零元不分配空间。 2. 示例代码 1)status.h /* DataStructure 预定义常量和类型头文件 */ #include <string.h>#i…...
【RabbitMQ 实战】11 队列的结构和惰性队列
一、 队列的结构 队列的组成: 队列由 rabbit_amgqueue_process 和 backing_queue两部分组成。rabbit_amqqueue_process负责协议相关的消息处理,即接收生产者发布的消息、向消费者交付消息、处理消息的确认 (包括生产端的 confirm 和消费端的 ack) 等。…...
Python3-批量重命名指定目录中的一组文件,更改其扩展名
Python3-批量重命名指定目录中的一组文件,更改其扩展名 1.argparse模块2.vars内置函数3.os.listdir(path)4.os.path.splitext(filepath)5.os.path.join6.os.rename7.os.path.isfile8.批量重命名指定目录中的一组文件,更改其扩展名 1.argparse模块 argpa…...
渗透测试KAILI系统的安装环境(第八课)
KAILI系统的安装环境(第八课) Kaili是一款基于PHP7的高性能微服务框架,其核心思想是面向服务的架构(SOA),支持http、websocket、tcp等多种通信协议,同时还提供了RPC、Service Mesh、OAuth2等功能。Kaili框架非常适合构…...
如何正确方便的理解双指针?力扣102 (二叉树的层序遍历)
双指针,顾名思义就是指针的指针。 在此之前我们需要先理解单指针 (简称为指针)。指针很简单,直接上例子:例:现有两个变量,a10,b20. 要求:交换他们的值,输出的结果应为a20…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
