@ModelAttribute 参数(封装后的)显示名
@RequestParam 参数接收名
场景:
某个字段不能修改,如:createTime、password
controller类中添加 方法 ,并在方法上加注解 <mark>@ModelAttribute</mark>
@ModelAttribute
有 @ModelAttribute 标记的方***在 每个目标方法执行之前被 SpringMVC 调用!
原理(浅析)
运行流程
- 执行 @ModelAttribute 注解修饰的方法:从数据库中取出对象,把对象放入到 Map中,键为 user
- SpringMVC 从 Map 中取出 User 对象,并把表单的请求参数赋给该 User 对象的对应属性。
- SpringMVC 把上述对象传入目标方法的参数。
注意:在 @ModelAttribute 修饰的方法中,放入到 Map 时的键需要和目标方法传入参数类型的第一个字母小写的字符串一样
原理(剖析) 2.2 版
在上面的代码中 打断点
<mark>implicate/ˈɪmplɪkeɪt/ vt. 使卷入;涉及;暗指;影响</mark>
源代码分析的流程
- 调用 @ModelAttribute 注解修饰的方法。实际上把 @ModelAttribute 方法中 map 中的数据放在了 implicitModel 中。
- 解析请求处理器的目标参数,实际上该目标参数来自于 WebDataBinder 对象的 target 属性
- 创建 WebDataBinder 对象。
- 确定 objectName 属性:如果是
"".equal(attribute)
,就赋值 objectName 为 类名+首字母小写org.springframework.core.Convertions
*注意:
@ModelAttribute也可以作为参数的注解
若目标方法的 POJO 属性使用了 @ModelAttribute 来修饰,则 attrName 值为 @ModelAttribute 的 value 属性值
- 确定 target 属性
在 implicitModel 中查找 attrName 对应的属性值 ,
若存在,ok
若不存在:则验证当前 Handler 是否使用了@SessionAttribute
修饰- 若使用了,则尝试从 Session 中 获取 attrName 所对应的属性值。
若 session 中没有对应的属性值。则抛出异常 - *若 Handler 没有使用 @SessionAttributes 进行修饰,或 @SessionAttributes 中没有使用 value 值指定的 key
和 attrName 相匹配,则通过反射创建。
- 若使用了,则尝试从 Session 中 获取 attrName 所对应的属性值。
- 确定 objectName 属性:如果是
- SpringMVC 把表单的请求参数赋给了 WebDataBinder 的 target 对应的属性
-
- SpringMVC 会把 WebDataBinder 的 attrName 和 target 给到 implicitModel(进而传到 Request 域对象中)
- 把 WebDataBinder 的 target 作为参数传递给目标方法的入参
- 创建 WebDataBinder 对象。
SpringMVC 确定目标方法 POJO 类型入参的过程
- 确定一个 key
1.若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰
则 key 为 POJO 类名第一个字母的小写
2.若使用了 @ModelAttribute 来修饰
,
则 key 为 @ModelAttribute 注解的 value 属性值 - 在
implicitModel
中查找 key 对应的对象,若存在,则作为参数传入
<mark>若在 @ModelAttribute 标记的方法中在 Map 中保存过,且 key 和 1 确定的 key 一致,则会获取到。</mark> - 若
implicitModel
中不存在 key 对应的对象,则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰,
1.若使用了该注解,且 @SessionAttributes 注解的 value 属性值中包含了 key
,
则会从 HttpSession 中获取 key 所对应的 value 值,若存在则直接传入到目标方法的入参中,若不存在则抛出异常
2.若 Handler 没有 表示 @SessionAttributes 注解 或 @SessionAttributes 注解的 Value 值中不包含 key
,
则会通过反射来创建 POJO 类型的参数,传入为目标方法的参数 - SpringMVC 会把 key 和value 保存到 implicitModel 中,进而会保存到 request 中