SpringMVC提供了多种途径输出模型数据:
1、ModelAndView
控制器处理方法的返回值如果是ModelAndView,则其既包含视图信息,又包含模型数据信息,SpringMVC可以使用视图对模型数据进行渲染。
@RequestMapping(method = RequestMethod.POST)
public ModelAndView createUser(User user){
ModelAndView mv=new ModelAndView();
//添加模型数据
mv.addObject("user",user);
//设置逻辑视图名
mv.setViewName("user/createSuccess");
return mv;
}
2、@ModelAttribute
2.1、在方法入参标注该注解后,入参的对象就会放到数据模型中。
@RequestMapping(value ="/hand12",method = RequestMethod.POST)
public String hand12(@ModelAttribute("user")User user){
return "user/createSuccess";
}
SpringMVC将请求消息绑定到User对象中,然后再以user为键将User对象放到模型中。在准备对视图进行渲染前,SpringMVC还会进一步将模型中的数据转储到视图的上下文中并暴露给视图对象。
2.2、在方法定义中使用@ModelAttribute注解
SpringMVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute注解的方法,并将这些方法的返回值添加到模型中。
//访问任何一个处理方法前,都会事先执行标注了@ModelAttribute的方法,并将其返回值以user为键添加到模型中
@ModelAttribute("user")
public User getUser(){
User user=new User();
user.setUserName("china");
user.setPassword("3232");
return user;
}
@RequestMapping(value ="/hand12",method = RequestMethod.POST)
//如果此处方法是hand12(User user),那么之前模型中的数据会被覆盖
public String hand12(){
return "user/createSuccess";
}
3、Map及Model、ModelMap
SpringMVC内部使用org.springframework.ui.Model接口存储模型数据,它的功能类似java.util.Map。org.springframework.ui.ModelMap实现了Map接口。
SpringMVC在调用方法前会创建一个隐含的模型对象,作为模型数据的存储容器。如果处理方法的入参是Map或Model类型,则SpringMVC会将隐含模型中的引用传递给这些入参。在方法体内,可以通过这个入参对象访问模型中的所有数据,也可以向模型中添加新的属性数据。
@ModelAttribute("user")
public User getUser(){
User user=new User();
user.setUserName("china");
user.setPassword("3232");
return user;
}
@RequestMapping(value ="/hand12",method = RequestMethod.POST)
//一旦发现处理方法中有Map或Model类型的入参,就会将隐含模型对象传递给这些参数
public String hand12(ModelMap modelMap){
//可以获取模型中的数据
User user=(User)modelMap.get("user");
//也可以添加新的模型数据
modelMap.addAttribute("testAttr","valueAttr");
return "user/createSuccess";
}
4、@SessionAttributes
在多个请求之间共用某个模型数据,则可以在控制器类中标注一个@SessionAttributes,SpringMVC会将模型中对应的属性暂存到HttpSession中。
@Controller
@RequestMapping("/user")
//在控制器类处标注一个@SessionAttributes,会自动将本处理器中任何处理方法中属性名的user的模型属性存储到HttpSession中
@SessionAttributes("user")
public class UserController {
//1、在调用处理方法之前,会自动创建一个隐含的模型对象,作为存储器。
//2、调用所有标注了@ModelAttribute的方法,并将方法的返回值添加到隐含模型中
//3、查看HttpSession中是否有所指定的xxx属性,如果有,就添加到隐含模型中,如果隐含模型中也有xxx属性,那么会覆盖已有的属性值。
//4、对标注了@ModelAttribute处理方法的入参
// 4.1、如果隐含模型拥有该xxx属性,则将其赋给该入参,然后用请求消息填充或覆盖该入参对象,否则,转到4.2;
// 4.2、如果xxx是会话属性,也就是在类处标注了@SessionAttributes("xxx"),那么尝试从会话中获取该属性,并将其赋给入参,然后用请求消息填充或覆盖该入参对象。(因为在步骤3中,如果有该xxx属性就会添加到隐含模型中,因此4.1中如果没有找到该属性,那在会话中肯定也找不到该属性,那么就会抛出异常。)
//4.3、如果xxx不是会话属性,隐含模型也不存在,那么创建新的入参对象实例,然后用请求消息填充该入参对象
//避免抛出异常,先向隐含模型中添加该属性
@ModelAttribute("user")
public User getUser(){
User user=new User();
user.setUserName("china");
user.setPassword("3232");
return user;
}
//在执行属性填充之前,先查找隐含模型或HttpSession中是否存在该属性,如果有,就先填充,后覆盖,最后添加到隐含对象和HttpSession中
public String hand13(@ModelAttribute("user")User user){
return "user/success";
}
//隐含模型会从HttpSession中获取到这个模型属性,任何传递给这些入参
@RequestMapping(value ="/hand12",method = RequestMethod.POST)
public String hand12(ModelMap modelMap){
//可以获取模型中的数据
User user=(User)modelMap.get("user");
//也可以添加新的模型数据
modelMap.addAttribute("testAttr","valueAttr");
return "user/createSuccess";
}
}