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

【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,包含 HandlerMethodMappedInterceptor
在(2)处得到 RequestMappingHandlerAdapter
在(3)处,执行MappedInterceptorpreHandle方法
在(4)处,执行 RequestMappingHandlerAdapterhandler方法
在(5)处,执行MappedInterceptorpostHandle方法

3.2. 再看RequestMappingHandlerAdapter的总体过程

继续看 RequestMappingHandlerAdapterhandler方法的总体过程:

注意:执行顺序是从左到右从上到下执行的

  • 封装为ServletInvocableHandlerMethod(1)
  • invokeAndHandle
    • invokeForRequest
      • getMethodArgumentValues(解析参数)
        • resolveArgument解析参数
          • getArgumentResolver(得到“参数解析器”)
          • resolveArgument(真正解析)
      • doInvoke(具体执行)
    • handleReturnValue(处理返回值)
      • selectHandler
      • handleReturnValue
  • 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的系统配置工具&#xff0c;用于类Unix系统。密码重置页面中存在此漏洞&#xff0c;允许未经身份验证的用户通过简单的 POST 请求执行任意命令。 影响版本 Webmin<1.920 漏洞评级 严重 利用方法&#xff08;利…...

webstorm自定义文件模板(Vue + Scss)

最终效果如下&#xff1a; 具体配置如下&#xff1a; 新增文件代码如下&#xff1a; <!--* Description: ${COMPONENT_NAME} 页面* Author: mhf* Date: ${DATE} --> <template><div>${COMPONENT_NAME} </div> </template><script&g…...

楔子-写在之前

最近一年都在忙着一个项目&#xff0c;并且需要学习另一个领域的知识&#xff0c;从单片机过渡到了LINUX嵌入式&#xff0c;倒静不下心去写点东西。看了下之前写的东西&#xff0c;感觉已经过去了很久很久。现在项目快忙完了&#xff0c;准备把最近的心得给大家分享下。 前言 …...

第 5 章 数组和广义表(稀疏矩阵的三元组顺序表存储实现)

1. 背景说明 为了节省存储空间&#xff0c;可以对这类矩阵进行压缩存储。所谓压缩存储是指&#xff1a;为多个值相同的元只分配一个存储空间&#xff0c;对零元不分配空间。 2. 示例代码 1)status.h /* DataStructure 预定义常量和类型头文件 */ #include <string.h>#i…...

【RabbitMQ 实战】11 队列的结构和惰性队列

一、 队列的结构 队列的组成&#xff1a; 队列由 rabbit_amgqueue_process 和 backing_queue两部分组成。rabbit_amqqueue_process负责协议相关的消息处理&#xff0c;即接收生产者发布的消息、向消费者交付消息、处理消息的确认 (包括生产端的 confirm 和消费端的 ack) 等。…...

Python3-批量重命名指定目录中的一组文件,更改其扩展名

Python3-批量重命名指定目录中的一组文件&#xff0c;更改其扩展名 1.argparse模块2.vars内置函数3.os.listdir(path)4.os.path.splitext(filepath)5.os.path.join6.os.rename7.os.path.isfile8.批量重命名指定目录中的一组文件&#xff0c;更改其扩展名 1.argparse模块 argpa…...

渗透测试KAILI系统的安装环境(第八课)

KAILI系统的安装环境(第八课) Kaili是一款基于PHP7的高性能微服务框架&#xff0c;其核心思想是面向服务的架构&#xff08;SOA&#xff09;&#xff0c;支持http、websocket、tcp等多种通信协议&#xff0c;同时还提供了RPC、Service Mesh、OAuth2等功能。Kaili框架非常适合构…...

如何正确方便的理解双指针?力扣102 (二叉树的层序遍历)

双指针&#xff0c;顾名思义就是指针的指针。 在此之前我们需要先理解单指针 &#xff08;简称为指针&#xff09;。指针很简单&#xff0c;直接上例子&#xff1a;例&#xff1a;现有两个变量&#xff0c;a10,b20. 要求&#xff1a;交换他们的值&#xff0c;输出的结果应为a20…...

Midjourney材质质感翻车实录(金属发灰/皮革失真/玻璃无折射):基于1372组AB测试的材质Token黄金配比公式

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Midjourney材质表现方法论总纲 Midjourney 作为以语义驱动的图像生成模型&#xff0c;其对材质&#xff08;Texture&#xff09;的表达并非依赖显式参数控制&#xff0c;而是通过提示词&#xff08;Prompt&…...

Midjourney构图进阶实战指南(98%用户从未调过的--sref与--style参数协同逻辑大揭秘)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney构图进阶实战指南&#xff08;98%用户从未调过的--sref与--style参数协同逻辑大揭秘&#xff09; 在Midjourney V6中&#xff0c; --sref&#xff08;Style Reference&#xff09;与 --style…...

树莓派CM4刀片服务器设计:从电源管理到集群部署全解析

1. 项目概述&#xff1a;当树莓派计算模块遇上“刀片式”设计如果你和我一样&#xff0c;是个树莓派的老玩家&#xff0c;从最初的Model B一路玩到最新的5代&#xff0c;那你肯定对树莓派计算模块&#xff08;Compute Module&#xff0c;简称CM&#xff09;又爱又恨。爱的是它把…...

VoiceFixer终极指南:三分钟让模糊录音变清晰的免费语音修复神器

VoiceFixer终极指南&#xff1a;三分钟让模糊录音变清晰的免费语音修复神器 【免费下载链接】voicefixer General Speech Restoration 项目地址: https://gitcode.com/gh_mirrors/vo/voicefixer 你是否曾经因为一段珍贵的录音模糊不清而遗憾&#xff1f;也许是重要的会议…...

深入eDP协议栈:从PSR SDP发送到Main Link开关,一次搞懂屏幕自刷新的完整信令流程

深入eDP协议栈&#xff1a;从PSR SDP发送到Main Link开关&#xff0c;一次搞懂屏幕自刷新的完整信令流程 在显示技术的演进中&#xff0c;嵌入式DisplayPort&#xff08;eDP&#xff09;协议因其高效能和低功耗特性&#xff0c;已成为移动设备和高端显示器的首选接口。其中&am…...

别再套table了!手把手教你用LaTeX的longtable搞定跨页表格(附字体调整避坑指南)

LaTeX长表格排版实战&#xff1a;从table到longtable的平滑迁移与字体优化 第一次在LaTeX中遇到需要跨页的表格时&#xff0c;我像大多数初学者一样&#xff0c;本能地在longtable外面套了一层table环境——结果表格不仅无法正确分页&#xff0c;还出现了各种诡异的格式错乱。经…...

别再死记硬背了!图解MATLAB形态学:用‘膨胀腐蚀’和‘开闭运算’修复破损老照片

用MATLAB形态学魔法修复老照片&#xff1a;从膨胀腐蚀到开闭运算的实战指南 翻开泛黄的相册&#xff0c;那些承载着记忆的老照片往往布满时间的痕迹——划痕、斑点、缺失的角落。作为图像处理领域的瑞士军刀&#xff0c;MATLAB提供了一套强大的形态学工具&#xff0c;能像数字修…...

七牛云:批量将标准存储文件转为归档直读存储

&#x1f4cb; 整体流程图 下载安装 qshell → 配置密钥 → 列出符合条件的文件 → 生成批量转换清单 → 执行转换建议先看看不同类型有何区别&#xff0c;选择适合自己的&#xff1a;存储类型_产品简介_对象存储 - 七牛开发者中心https://developer.qiniu.com/kodo/3956/kodo…...

手把手教你用STM32F103C8T6和NTC热敏电阻DIY一个水温监测器(附完整代码)

手把手教你用STM32F103C8T6和NTC热敏电阻DIY一个水温监测器&#xff08;附完整代码&#xff09; 水温监测在家庭养鱼、咖啡机控制、热水器管理等场景中非常实用。本文将带你从零开始&#xff0c;用最常见的STM32F103C8T6最小系统板和NTC热敏电阻&#xff0c;打造一个低成本、高…...

CE修改器进阶:通过内存结构分析,破解‘敌我同源’的游戏逻辑(以浮点数血量为例)

CE修改器进阶&#xff1a;内存结构分析与游戏逻辑破解实战 游戏修改器一直是技术爱好者探索虚拟世界底层逻辑的利器。在众多工具中&#xff0c;Cheat Engine&#xff08;简称CE&#xff09;以其强大的内存扫描和调试功能脱颖而出&#xff0c;成为逆向工程领域的瑞士军刀。今天&…...