【老王读SpringMVC-4】请求参数是如何绑定到Controller method参数对象上的?

news2024/11/24 16:11:37

前面我们分析了,如果我们自己要实现 spring mvc 框架的话,大致需要实现如下功能:

  • 0、将 url 与 Controller method 的对应关系进行注册
  • 1、通过请求的 url 找到 Controller method (即 url 与 Controller method 的映射)
  • 2、将请求参数进行绑定,即将入参绑定到 Controller method 的参数对象上
  • 3、执行处 Controller method (即 HandlerAdapter#handle())
  • 4、对 Controller method 的返回值进行处理
    4.1 如果正常返回的话,对返回值对象进行处理(即 ReturnValueHandler)
    包括:如果返回视图 View 的话,对视图进行渲染 (即 ViewResolver)
    4.2 如果有异常返回的话,对异常进行处理(即 @ExceptionHandler)

上一篇我们分析了根据 url 如何找到 Controller 方法,接下来,我们再看分析一下请求参数是如何绑定到 handler method 的参数对象上的?

handler method 参数绑定的入口

还是从 DispatcherServlet 出发,来看下 Spring MVC 是在哪里开始进行参数绑定的?

DispatcherServlet.png

可以看到,DispatcherServlet#doDispatch() 的处理大体分了 6 步:
1、获取 request 对应的 HandlerExecutionChain(它包含 handler 和 interceptors)
2、获取 handler 对应的 HandlerAdapter
3、执行 handler 的前置处理: HandlerInterceptor#preHandle()
4、通过 HandlerAdapter#handle() 来执行处理程序
5、执行 handler 的后置处理:HandlerInterceptor#postHandle()
6、对返回值进行处理(包括正常返回 和 异常处理)

所以,参数绑定应该是在执行 handler method 的时候,即 HandlerAdapter#handler()

  • 为什么需要获取 HandlerAdapter 之后,通过 HandlerAdapter#handler() 来执行 handler method 呢?
    答: 因为 Spring MVC 支持多种 handler,比如:@RequestMapping 定义的 handler method、通过 org.springframework.web.servlet.mvc.Controller 接口定义的 handler method、servlet 方式定义的 handler method等。
    为了让这些不同种类的 handler method 可以通过统一的方式进行调用执行,Spring MVC 抽象出了 HandlerAdapter 接口来统一处理客户端的 request 请求。

RequestMappingHandlerAdapter

SpringMVC 中最常用的是 @RequestMapping 标记 handler method。
@RequestMapping 标记的 HandlerMethod 对应的 HandlerAdapter 是 RequestMappingHandlerAdapter

RequestMappingHandlerAdapter#handle() 具体的调用过程如下:
RequestMappingHandlerAdapter2.png

可以看到,参数解析、handler method 的执行 和 对返回值的处理,最终是通过 ServletInvocableHandlerMethod#invokeAndHandle() 来处理的。

ServletInvocableHandlerMethod#invokeAndHandle() 的处理过程如下:
ServletInvocableHandlerMethod.png

可以看到,参数的解析绑定是通过 HandlerMethodArgumentResolver 来处理的。

HandlerMethodArgumentResolver

HandlerMethodArgumentResolver 是 SpringMVC 用来将 request 中的参数解析出来赋值给 handler method 的入参的。

HandlerMethodArgumentResolver 的类图如下:(精简了一些实现类)
HandlerMethodArgumentResolver.png

从上图可以看到 HandlerMethodArgumentResolver 的子类针对 Map、Model、@RequestParam、@PathVariable、@RequestBody、ServletRequest、HttpSession、TimeZone等都分别进行了解析处理。

我们重点看下对 @RequestBody 参数的处理:
@RequestBody 标记的参数,最终会通过 HttpMessageConverter#read() 来进行处理。
在 SpringBoot 环境下,默认会使用 MappingJackson2HttpMessageConverter 来处理。

小结

SpringMVC 的请求参数解析通常是通过 HandlerMethodArgumentResolver 来解析的,它会解析 request 中的参数,并赋值给 handler method 入参。
HandlerMethodArgumentResolver 的子类针对 Map、Model、@RequestParam、@PathVariable、@RequestBody、ServletRequest、HttpSession、TimeZone等都分别进行了解析处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/467371.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FPGA时序约束(四)主时钟和虚拟时钟的约束

系列文章目录 FPGA时序约束(一)基本概念入门及简单语法 FPGA时序约束(二)利用Quartus18对Altera进行时序约束 FPGA时序约束(三)时序约束基本路径的深入分析 文章目录 系列文章目录前言主时钟约束跨时钟域…

计算机网络【2】 子网掩码

学习大佬记下的笔记 https://zhuanlan.zhihu.com/p/163119376 "子网"掩码,顾名思义,它就是拿来划分子网的,更准确的说,划分子网的同时,还能通过它知道主机在子网里面的具体ip的具体地址。 子网掩码只有一个…

聊聊「低代码」的实践之路

区块链、低代码、元宇宙、AI智能; 01 【先来说说背景】 这个概念由来已久,但是在国内兴起,是最近几年; 低代码即「Low-Code」; 指提供可视化开发环境,可以用来创建和管理软件应用; 简单的说…

中英文切换,vue项目国际化使用教程(国际化使用详细,i18n国际化)

简述:在工作中,我们难免会遇到把文字切换成外语的需求,这里来记录下如何在项目中点击切换成英语,这里会用到i18n,它是一个支持国际化功能的插件,这里来分享下它的使用过程。 1、首先,我们需要在…

idea使用 ( 四 ) 插件

5.插件 5.1.idea数据库连接 5.1.1.打开配置界面 5.1.2.选择MySQL 点击 号 > Data Source > MySQL 5.1.3.配置数据库驱动jar 先在左边选择 MySQL 再点击 号 > Custom JARs… 在 弹出的窗口中选择 已经存在的 jar位置 就导入 MySQL 的驱动文件 5.1.4.配置连库…

记录一次在x86 软件中使用dpdk 的历程(Makefile gcc改成g++)

我们一台服务器上原本是用grub下预留内存的方式, 然后把物理地址在板卡上的配置文件中传给L1. 但是在客户的环境上服务器windriver上不是能预留内存的. 所以服务器上需要在testMxx程序中用dpdk的方式分配出内存, 然后, 把物理地址通过sdp虚拟的网口, 用socket 传…

为什么要清除浮动?清除浮动的方式

📝个人主页:爱吃炫迈 💌系列专栏:HTMLCSS 🧑‍💻座右铭:道阻且长,行则将至💗 文章目录 浮动的定义浮动的工作原理浮动的特性为什么要清除浮动清除浮动的方式利用clear样式…

vue3 vite typescript volar element-plus element标签报红问题的解决

故障就这样的: 模块 ""element-plus"" 没有导出的成员 "FormInstance" 至于原因咱也不知道,也没搞明白,一直以为是volar校验的问题,能开发咱就接着干,到了发布的时候傻眼了。所有这种…

API低代码平台介绍1-功能概述

API低代码平台之ADI平台 ADI平台是指Application data integration,即“应用数据集成”,使用springboot开发,并通过springcloud实现微服务,是一个动态定义Http API接口的“零代码”或“低代码”平台,支持GET(查)、POST…

Java 实现 YoloV7 人体姿态识别

1 OpenCV 环境的准备 这个项目中需要用到 opencv 进行图片的读取与处理操作,因此我们需要先配置一下 opencv 在 java 中运行的配置。 首先前往 opencv 官网下载 opencv-4.6 :点此下载;下载好后仅选择路径后即可完成安装。 此时将 opencv\b…

30基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序

资源地址: 30基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序资源-CSDN文库 参考文献: 《基于非对称纳什谈判的多微网电能共享运行优化策略》——吴锦领 仿真平台:MATLAB CPLEXMOSEK/IPOPT 主要内容: 主要做的是…

优思学院|精益生产为企业带来革命性转变的效益

企业的成长和发展需要不断的变革和创新,而精益生产则成为了这个时代的代名词。精益生产不仅仅是一个生产方式,更是一种革命性的转变,为企业带来了无限的效益。 什么是精益生产? 精益生产是一种基于持续改进的生产方式&#xff0…

基于matlab的混合波束成形仿真

一、前言 本示例介绍了混合波束成形的基本概念,并展示了如何仿真此类系统。 二、介绍 现代无线通信系统使用空间复用来提高散射体丰富的环境中系统内的数据吞吐量。为了通过通道发送多个数据流,从通道矩阵中导出一组预编码和组合权重。然后,可…

lammps教程:聚合物压缩,避免“bond atoms missing”

本文介绍聚合物的压缩方法。 lammps模拟聚合物体系时,最常见的一个错误是“bond atoms missing”,其中一个原因是建模方法不对。 这个原理在之前的专栏文章中已经详细介绍。 如果使用ms建模,聚合物的链会伸出到盒子外面,在导出data文件后&…

MindFusion.Diagramming for WinForms 6.8.6

您现在可以指定在修改项目时要显示的视觉效果。 2023 年 4 月 26 日 - 15:55新版本 特征 您现在可以指定在修改项目时要显示的视觉效果。新的 Opacity 属性允许您创建半透明的 DiagramItem。添加了新的 CopySelection 重载,它允许您复制项目列表而无需选择它们。您现…

OrbStack

OrbStack 是一个可以在 macOS 上快速运行 Docker 容器,和 Linux 虚拟机的工具,资源占用率低,高效,快速。 macOS 上的 Parallels Desktop 和 Docker Desktop 一直是饱受诟病,慢、重、资源消耗巨大。OrbStack 的出现就是…

goroutine和channel

进程与线程 进程就是程序执行在操作系统中的一次在执行过程,是系统进行资源分配的基本单位。 线程就是进程的一个执行实例,是程序的最小执行单元,是比进程更小的独立运行的单位。 一个进程可以创建多个线程,同一一个进程中的多…

如何在C中动态分配二维数组

在C语言中如何动态申请连续的二维数组。可以采用多申请一些指针,然后这一些指针分别指向后面数据区中对应的位置,如一个3*4的int类型数组,我们先申请大小为sizeof(int*) * 3 3 * 4 * sizeof(int)的一维数组设为arr。然后arr[0]存放指向arr …

OpenAirInterface通过docker build方式构建images

本文主要讲解如何通过build方式构建各个网元的image,因为直接pull的image无法对其进行更改,而build的镜像可以对其源代码进行编辑更改后生成镜像。 参考链接:OAI build iamges 1.获取正确的网络功能分支 此存储库仅包含教程和持续集成脚本…

有假币与求正数数组的最小不可组成和

一、编程题 1.有假币 链接:有假币__牛客网 (nowcoder.com) 居然有假币! 现在猪肉涨了,但是农民的工资却不见涨啊,没钱怎么买猪肉啊。nowcoder这就去买猪肉,结果找来的零钱中有假币!!&#xff…