Spring MVC 有以下几种方式输出模型数据:
- ModelAndView:处理方法返回值类型为 ModelAndView时,方法体即可通过该对象添加模型数据;
- Map 及 Model :入参为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 Java.uti.Map 时,处理方法返回时,Map中的数据会自动添加到模型中;
- @SessionAttributes:将模型中的某个属性暂存到 HttpSession 中,以便多个请求可以共享这个属性;
- @ModelAttribute:方法入参标注该注解后,入参的对象就会自动放到数据模型中
一、ModelAndView
控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。
添加模型数据:
- ModelAndView addObject(String attributeName, Object attributeValue)
- ModelAndView addAllObject(Map<String, ?> modelMap)
设置视图:
- void setView(View view)
- void setViewName(String viewName)
@RequestMapping("/handle3")
public ModelAndView handle3() {
ModelAndView view = new ModelAndView();
view.setViewName("success");
view.addObject("name", "crystal");
view.addObject("age", 20);
return view;
}
说明:SpringMVC会把ModelAndView中的Model中的数据方法Request域对象中。
二、Map及Model
下面传入的 Map 实际是BindingAwareModelMap,所以我们定义参数用Map即可。
@RequestMapping("/testModelAndMap")
public String testModelAndMap(Map<Object, Object> map) {
map.put("age", 20);
return "success";
}
Spring MVC 在内部使用了一个org.springframework.ui.Model 接口存储模型数据。
Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
注意:这里初始化map之后里面会将 检查有没有 @ModelAttribute 方法 和@SessionAttribute 存储的信息,若果有会将信息保存到 map里面
三、@SessionAttributes
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes,SpringMVC将在模型中对应的属性暂存到 HttpSession 中。
@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
- @SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
- @SessionAttributes(value={“user”,”admin”})
- @SessionAttributes(types={User.class, Department.class})
- @SessionAttributes(value={“user”,”admin”}, types={User.class})
@Controller
@SessionAttributes("user")
public class Test {
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<Object, Object> map) {
User user = new User();
user.setAge(23);
user.setName("crystal");
map.put("user", user);
return "success";
}
}
页面显示
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
success<br>
sessionScope:${sessionScope.user }<br>
requestScope:${requestScope.user }<br>
</body>
</html>
结果:
success
sessionScope:name:crystal, age:23
requestScope:name:crystal, age:23
注意:如果在处理定义处标注了 @SessionAttributes(“xxx”),则会从回话中尝试获取该属性,并将其赋给入参,然后再用请求消息填充该入参对象,如果在回话中找不到对应的属性则会抛出 HttpSessionRequiredException 异常。
四、@ModelAttribute
作用:
①绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
②暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping 注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
③暴露@RequestMapping 方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。
4.1 绑定请求参数到指定对象 (参数)
public String test1(@ModelAttribute("user") UserModel user)
只是此处多了一个注解@ModelAttribute(“user”),它的作用是将该绑定的命令对象以“user”为名称添加到模型对象中供视图页面展示使用。我们此时可以在视图页面使用${user.username}来获取绑定的命令对象的属性。
如请求参数包含“?username=crystal&password=123&workInfo.city=bj”自动绑定到user 中的workInfo属性的city属性中。
4.2 暴露表单引用对象为模型数据 (方法)
Spring MVC 在调用目标处理方法之前会逐个调用在方法级上标注了@ModelAttribute 的方法。
@ModelAttribute
private User addUser() {
User user = new User();
user.setAge(23);
user.setName("crystal");
return user;
}
4.3 暴露@RequestMapping方法返回值为模型数据 (处理方法)
@RequestMapping("/testModelAttribute")
@ModelAttribute("user")
public String testModelAttribute(User user) {
System.out.println(user);
return "success";
}
返回值类型是命令对象类型,而且通过@ModelAttribute(“user”)注解,此时会暴露返回值到模型数据( 名字为user ) 中供视图展示使用
@ModelAttribute 注解的返回值会覆盖@RequestMapping 注解方法中的@ModelAttribute 注解的同名命令对象