ModelAndView
当控制器方法的返回值如果为ModelAndView,那么它既包含视图信息,也包含模型数据信息,其实如果返回String的话,他最终也会被SpringMVc转换成ModelAndView对象。
添加模型数据的方法
- ModelAndView addObject(String attributeName,Object attributeValue)
- ModelAndView addAllObject(Map<String,?> modelMap)
设置视图
- void setView(View view)
- void setViewName(String viewName)
例子:
1 | @Controller |
Map和Model
Spring MVC 在内部使用了一个org.springframework.ui.Model 接口存储模型数据
Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
如果方法的入参为Map或Model类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体中,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
@SessionAttributes注解
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes,Spring MVC 将在模型中对应的属性暂存到 HttpSession 中
该注解只能放在类的上面. 而不能修饰方法。
@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
@SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”}) 会将名字为user1和user2的属性添加到session对话中
@SessionAttributes(types={User.class, Dept.class})会将User类型和Dept类型的对象添加到会话中
@SessionAttributes(value={“user1”, “user2”}, types={Dept.class}) 会将名字为user1,user2还有类型为Dept的对象添加到session会话中
ModelAttribute的使用场景
比如当我们要修改一个user对象的属性,但是其中ID属性的值我们不能修改,这时我们可以先从数据库中拿到这个user对象,然后再把用户发送过来的修改请求赋值给这个user对象,(前端只对除ID属性以外的属性赋值修改了)这时我们拿到的就是ID没有被修改的user对象了
例子:
1 | //被ModelAttribute修饰的方法会在每个目标方法执行之前被SpringMVC调用 |
运行流程:
ModelAttribute修饰的方法先从数据库中获取要修改的user对象,并把这个对象放入Map中,键为user
SpringMVC从map中取出键为user的对象,并将用户输入的修改的值赋给这个对象的相应属性
SpringMVC将这个被赋值好的对象传到目标方法的入参中
放入map的对象的键值要和目标方法第一个字母小写的String值要相同
SpringMVC 确定目标方法 POJO 类型入参的过程
- 调用 @ModelAttribute 注解修饰的方法. 实际上把 @ModelAttribute 方法中 Map 中的数据放在了 implicitModel 中.
确定一个 key:
若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母小写
若使用了 @ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值.
在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入
若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到.
若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰, 若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从HttpSession 中来获取 key 所对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.
若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则 会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数
SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中.
ModelAttribute修饰方法的入参
ModelAttribute修饰的POJO类型入参有个value值,SpringMVC会通过value值为key在implicitModel中查找对应的属性,若存在,则把这个属性直接赋值给目标方法入参(POJO对象)。
若不存在,则SpringMVC会以value为key,POJO入参为value存入Request中