springboot源码解析之Model和Map参数解析

springboot源码解析之Model和Map参数解析

标签:源码:springboot

测试代码

@Controller
public class HelloController {@RequestMapping("/helloModelAndMap")public String helloModelAndMap(HttpServletRequest request, Model model, Map<String, Object> map) {System.out.println(model.getClass().getSimpleName());System.out.println(map.getClass().getSimpleName());System.out.println(model == map);request.setAttribute("message", "Hello World!");model.addAttribute("name", "张三");map.put("age", 18);// 这里拿不到Model和Map中的值,转发后能拿到 在视图渲染阶段才会放到请求域中System.out.println("helloMapAndModel:" + request.getAttribute("name"));System.out.println("helloMapAndModel:" + request.getAttribute("age"));return "forward:/success";}@RequestMapping("/success")@ResponseBodypublic Object success(ServletRequest request) {Map<String, Object> result = new HashMap<>();result.put("message", request.getAttribute("message"));result.put("name", request.getAttribute("name"));result.put("age", request.getAttribute("age"));return result;}}

控制台输出

BindingAwareModelMap
BindingAwareModelMap
true
helloMapAndModel:null
helloMapAndModel:null

请求响应

{"name":"张三","message":"Hello World!","age":18}

结果分析

通过输出可以看到,这里传入的Model对象和Map对象都是BindingAwareModelMap类型,并且指向同一个对象,BindingAwareModelMap既是Model也是Map

ModelAndViewContainer

image-20240306202335477

public class ModelAndViewContainer {// ...private final ModelMap defaultModel = new BindingAwareModelMap();public ModelMap getModel() {if (useDefaultModel()) {return this.defaultModel;}else {if (this.redirectModel == null) {this.redirectModel = new ModelMap();}return this.redirectModel;}}// ... }

MapMethodProcessor

Map是由MapMethodProcessor参数处理器处理的

public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {@Overridepublic boolean supportsParameter(MethodParameter parameter) {// 参数类型为Map,并且没有啥注解(所以如果想要用map接受前段传递的请求体里的参数,一定要不要忘记加上@RequestBody注解)return Map.class.isAssignableFrom(parameter.getParameterType()) &&parameter.getParameterAnnotations().length == 0;}@Override@Nullablepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");// 解析参数 这里拿到了ModelAndViewContainer 里面的Model 也就是 BindingAwareModelMapreturn mavContainer.getModel();}@Overridepublic boolean supportsReturnType(MethodParameter returnType) {return Map.class.isAssignableFrom(returnType.getParameterType());}@Override@SuppressWarnings({"rawtypes", "unchecked"})public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {if (returnValue instanceof Map){mavContainer.addAllAttributes((Map) returnValue);}else if (returnValue != null) {// should not happenthrow new UnsupportedOperationException("Unexpected return type: " +returnType.getParameterType().getName() + " in method: " + returnType.getMethod());}}}

ModelMethodProcessor

Model参数是由ModelMethodProcessor解析的

public class ModelMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {@Overridepublic boolean supportsParameter(MethodParameter parameter) {// 参数类型是modelreturn Model.class.isAssignableFrom(parameter.getParameterType());}@Override@Nullablepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");// 解析参数 和 MapMethodProcessor 一样,拿到了同一个 BindingAwareModelMap 对象,这也就是为什么测试方法里面model 和 map指向同一个对象的原因return mavContainer.getModel();}@Overridepublic boolean supportsReturnType(MethodParameter returnType) {return Model.class.isAssignableFrom(returnType.getParameterType());}@Overridepublic void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {if (returnValue == null) {return;}else if (returnValue instanceof Model) {mavContainer.addAllAttributes(((Model) returnValue).asMap());}else {// should not happenthrow new UnsupportedOperationException("Unexpected return type: " +returnType.getParameterType().getName() + " in method: " + returnType.getMethod());}}}

参数解析过程中只是拿到了 BindingAwareModelMap 对象,执行目标方法的时候只是将key和value设置到了 BindingAwareModelMap 对象里面,那么具体是在哪里将 BindingAwareModelMap 中的key和value设置到请求域中的呢?

AbstractView

org.springframework.web.servlet.view.AbstractView#exposeModelAsRequestAttributes

protected void exposeModelAsRequestAttributes(Map<String, Object> model,HttpServletRequest request) throws Exception {model.forEach((name, value) -> {if (value != null) {// 这样就是为什么给model 和 map中方数据和给request放数据一样的原因request.setAttribute(name, value);}else {request.removeAttribute(name);}});
}

通过调用链我们可以发现是在渲染视图的过程中将BindingAwareModelMap 对象中的值设置到请求域中的

image-20240306204213299

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

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

相关文章

万物皆可Find My,伦茨科技ST17H6x芯片赋能产品苹果Find My功能

苹果的Find My功能使得用户可以轻松查找iPhone、Mac、AirPods以及Apple Watch等设备。如今Find My还进入了耳机、充电宝、箱包、电动车、保温杯等多个行业。苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、Ai…

[ISP]DCT离散余弦变换及C++代码demo

1.基本定义 离散余弦变换(DCT for Discrete Cosine Transform) DCT&#xff08;Discrete Cosine Transform&#xff0c;离散余弦变换&#xff09;是一种常用的信号处理技术&#xff0c;广泛应用于图像处理、音频处理、视频压缩等领域。DCT将一个信号或数据序列从时域&#xf…

【Tauri】(5):本地运行candle和 qwen 大模型,并测试速度

1&#xff0c;本地运行candle 关于candle项目 https://github.com/huggingface/candle Hugging Face 使用rust开发的高性能推理框架。 语法简单&#xff0c; 风格与 PyTorch 相似。 CPU 和 Cuda Backend&#xff1a;m1、f16、bf16。 支持 Serverless&#xff08;CPU&#xff…

简单两步,从补税到退税

大家好&#xff0c;我是拭心。 最近到了一年一度的个人所得税年度申报时期&#xff0c;有人可以退好几千&#xff0c;而有的人则需要补上万元&#xff0c;人类的悲喜这一刻并不相通。 我申报的时候&#xff0c;提示我需要补税一万多&#xff0c;心有不甘但差一点就认了&#xf…

java SSM科研管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM科研管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S…

selenium鼠标操作实战

鼠标操作实战 鼠标单击操作 click()内置鼠标操作包ActionChains鼠标双击操作double_click()鼠标右击操作context_click()鼠标指针悬浮操作move_to_element(ele)鼠标拖动操作drag_and_drop(source, target)其他鼠标操作汇总 鼠标单击操作 click() from selenium import webdriv…

python中的文件操作2

文件遍历 在Python中&#xff0c;遍历文件通常指的是逐行读取文件中的内容。这种方式对于处理大型文件特别有用&#xff0c;因为它不需要一次性将整个文件加载到内存中。下面是几种常见的遍历文件内容的方法&#xff1a; 1. 使用with语句和for循环 这是最推荐的方式&#xf…

“2024杭州智慧城市及安防展会”将于4月在杭州博览中心盛大召开

2024杭州国际智慧城市及安防展览会&#xff0c;将于4月24日在杭州国际博览中心盛大开幕。这场备受瞩目的盛会&#xff0c;不仅汇集了全球智慧城市与安防领域的顶尖企业&#xff0c;更是展示最新技术、交流创新理念的重要平台。近日&#xff0c;从组委会传来消息&#xff0c;展会…

【网站项目】089理发店会员管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

设计模式之模版方法实践

模版方法实践案例 实践之前还是先了解一下模版方法的定义 定义 模板方法模式是一种行为设计模式&#xff0c;它定义了一个骨架&#xff0c;并允许子类在不改变结构的情况下重写的特定步骤。模板方法模式通过在父类中定义一个模板方法&#xff0c;其中包含了主要步骤&#xf…

上海亚商投顾:沪指缩量调整 机器人概念股午后大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日缩量震荡&#xff0c;创业板指午后涨超1%&#xff0c;随后上演冲高回落走势。风电、光伏等新能源方向…

Redis第7讲——哨兵模式详解

为了解决主从模式的无法自动容错及恢复的问题&#xff0c;Redis在主从复制的基础上加入了哨兵节点&#xff0c;也就是我们熟悉的哨兵模式。但现在基本不会用到哨兵模式&#xff0c;也就是这种模式只存在于面试中。 一、什么是哨兵模式 ps&#xff1a;主从服务器之间的数据同步…

ping多个IP的工具

Ping Tool 项目地址 python开发的IP搜索小工具 ping一个网段所有IP&#xff0c;显示结果查看某个ip地址开放监听的端口配置可保存

Python基于opencv的人脸识别上课签到考勤系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

MATLAB环境下基于图像处理的计算病理学图像分割(MATLAB R2021B)

人工智能是病理学诊断和研究的重要新兴方法&#xff0c;其不仅可用于病理形态数据分析&#xff0c;还可整合免疫组化、分子检测数据和临床信息&#xff0c;得出综合的病理诊断报告&#xff0c;为患者提供预后信息和精准的药物治疗指导。计算病理学是病理学与AI、计算机视觉等信…

vant van-field 密码输入框小程序里隐藏、显示密码bug总结

老规矩先上效果图: vant 输入框组件 密码的隐藏与显示功能&#xff1a; 注: 用password属性控制密码的显示与隐藏 不要用type属性&#xff0c;type属性在真机上有时会没有效果 1、当然如果只用typepassword 不需要切换显示、隐藏也可以使用。 2、如果用到了密码的显示与…

面试问答之Spring进阶

文章目录 &#x1f412;个人主页&#xff1a;信计2102罗铠威&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;说说你对Spring的认识与理解&#x1f415;Bean的分类&#x1f415; BeanFactory 接口和ApplicationContex 接口 的区别&#x1f415;SpringBe…

CIA402协议笔记

文章目录 1、对象字典1.1 Mode of Operation&#xff08; 606 0 h 6060_h 6060h​)1.2 Modes of opration display( 606 1 h ) 6061_h) 6061h​) 2、状态机2.1 控制字&#xff08;ControlWord、6040h&#xff09;2.2 状态字&#xff08;StatusWord、6041h&#xff09;2.3 shutd…

视频扩散模型介绍 Video Diffusion Models Introduction

视频扩散模型介绍 Video Diffusion Models Introduction Diffusion 扩散模型中的一些概念DDPMDDIMCLIPLatent DiffusionStable DiifusionLoRADreamBoothControlNet 视频生成评估标准图片层面视频层面 前人的工作Make-A-VideoAlign your Latents 开源视频生成模型ModelScopeT2V&…