一般来说,有如下的4种方法来传递模型数据到视图中
1、ModelAndView
要求:处理方法返回值类型为 ModelAndView。在方法体中我们通过该ModelAndView对象添加模型数据。
2、Model/Map/ModelMap
要求:使用org.springframework.ui.Model、org.springframework.ui.ModelMap 或 Java.uti.Map 作为处理方法的入參时,当处理方法返回时,Map中的数据会自动添加到模型中,具体实例将在后面介绍。
3、@SessionAttributes
使用该注解来注解某个类,使得将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性。
4、@ModelAttribute
该注解即可注解在有返回值的方法上,无返回值的方法上,还可以注解在方法入参上,当入參标注该注解后, 入参的对象就会放到数据模型中,具体将在后面进行介绍。
下面将分别以例子的形式进行介绍。
1、创建ModelAndView,并传入模型数据
@Controller
public class HelloController {
@RequestMapping(value = "/testModelAndView.do",method = RequestMethod.GET)
public ModelAndView testModelAndView(){
String viewName = "hello";//视图名
ModelAndView modelAndView = new ModelAndView(viewName);
modelAndView.addObject("time",new Date());
modelAndView.addObject("name","ModelAndView");
return modelAndView;
}
}
该处理方法返回的是一个ModelAndView对象,且在方法体中添加了以“time”和“name”为key的数据。
2、编写JSP
编写名为:“hello.jsp”,内容如下:
<html>
<body>
<h2>method:${requestScope.name}h2>
${requestScope.time}<br>
${requestScope.get("time")}<br>
${time}
body>
html>
这样,在浏览器中输入:localhost:8080/testModelAndView.do ,即可看到如下的输出结果:
注意:
requestScope.time, {requestScope.get(“time”)},${time}这三种写法效果是一样的,在不同的书籍/博客中所看到的都是其中的一种。
Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,我们可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
Model和Map使用上基本一样,具体实现代码如下图所示。
@RequestMapping(value = "/testModel.do",method = RequestMethod.GET)
public String testModel(Model model){
model.addAttribute("time",new Date());
model.addAttribute("name","Model");
return "hello";
}
@RequestMapping(value = "/testMap.do",method = RequestMethod.GET)
public String testMap(Map<String,Object> map){
map.put("time",new Date());
map.put("name","Map");
return "hello";
}
上面代码所对应的hello.jsp与上面ModelAndView的hello.jsp一样。
经测试验证是可以正常工作的。
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes,Spring MVC将在模型中对应的属性暂存到 HttpSession 中。
注意:@SessionAttributes这个注解只能放到类的上面
如下代码为:首先使用Map将模型数据存到模型对象中,然后在类定义处使用@SessionAttributes,拷贝到Session中
@SessionAttributes({"name","time"})
@Controller
public class HelloController {
@RequestMapping(value = "/testSessionAttribute.do",method = RequestMethod.GET)
public String testSessionAttribute(Map map){
map.put("time",new Date());
map.put("name","SessionAttribute");
return "sessionAttribute";
}
}
sessionAttribute.jsp的内容如下:
<html>
<body>
<h2>method:${requestScope.name}h2>
${requestScope.time}<br>
${requestScope.get("time")}<br>
${time} <br>
sessionScope.time:${sessionScope.time}
body>
html>
这样,在浏览器中输入:localhost:8080/testSessionAttribute.do ,即可看到如下的输出结果:
前面谈到SpringMVC在每次调用请求处理方法时,都会创建Model类型的一个隐含实例对象。如果准备使用此实例,则可以在方法中添加一个Model类型的输入参数。事实上,还可以使用在方法中添加@ModelAttribute注释类型来访问Model实例。
可以用@ModelAttribute来注释方法参数:带有@ModelAttribute注解的方法会将其输入或创建的参数对象添加到Model对象中(若方法中没有显式添加)。
可以用@ModelAttribute标注一个非请求的处理方法(有返回值,无返回值):被@ModelAttribute注释的方法会在此controller每个方法执行前被执行。
@ ModelAttribute注解在有返回值的方法上,则该返回值会被添加到模型对象中。
@ModelAttribute
public User addUser(User user){//
user.setName("Model Attribute in Mehtod ,this method has return value");
return user;
}
@RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
public String testModelAttributeInReturnValueMethod(){
return "modelAttributeInRVMethod";
}
即使addUser方法的方法体中并没有显示的将模型数据添加到Model中,由于使用了@ModelAttribute注解,它会帮我们完成添加。
modelAttributeInRVMethod.jsp的内容如下:
<html>
<body>
<h2>name:${user.name}h2>
body>
html>
测试结果如下:
还有一点需要说明的是:返回User对象,model属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个model属性的名称是user,因此,在如上的jsp文件中就可以使用 user.name来访问,如果指定属性的名称,例如:@ModelAttribute(value="myUser"),则在jsp中就需要使用 {myUser.name}来访问
看一个指定属性名称的例子:
/**
* 对象合并指定对象名称
* */
@RequestMapping(value = "/testModelAttribute4.do",method = RequestMethod.GET)
public String testModelAttribute4(@ModelAttribute("myUser") User user ){
//对模型对象中的对象user进行更改
user.setAge(20);
return "modelAttribute4";
}
@ModelAttribute(value = "myUser")//指定对象名称,并添加到模型对象中
public User myUser(){
User user = new User();
user.setName("wojiushimogui");
return user;
}
相应的jsp文件内容如下:
<html>
<body>
<h2>name:${myUser.name}h2>
<h2>name:${myUser.age}h2>
body>
html>
测试结果如下:
@ModelAttribute注解在void返回值的方法上,与注解在有返回值的方法上不同的时,需要显示的添加模型数据到Model对象中。
/**
* @ModelAttribute注解void返回值的方法
* */
@ModelAttribute
public void addUser(User user,Model model){
user.setName("Model Attribute in Mehtod ,this method not return value");
model.addAttribute("user",user);
}
@RequestMapping(value = "/testModelAttributeInNonReturnValueMethod.do",method = RequestMethod.GET)
public String testModelAttributeInNonReturnValueMethod(){
return "modelAttributeInNonRVMethod";
}
modelAttributeInNonRVMethod.jsp的内容与modelAttributeInRVMethod.jsp的内容完全一样,这里不再贴出。
运行结果如下:
有趣的是,如果在一个控制器HelloController.java文件中(如下所示),即存在@ModelAttribute注解在有返回的方法上,也注解在void返回值方法上,且模型中包括的模型数据名称一致,会出现什么结果呢??看如下的程序代码
@Controller
public class HelloController {
/**
* 将@ModelAttribute 注解在有返回值的方法上,
*
* */
@ModelAttribute
public User addUser(User user){
user.setName("Model Attribute in Mehtod ,this method has return value");
return user;
}
/**
* @ModelAttribute注释void返回值的方法
* */
@ModelAttribute
public void addUser(User user,Model model){
user.setName("Model Attribute in Mehtod ,this method not return value");
model.addAttribute("user",user);
}
@RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
public String testModelAttributeInReturnValueMethod(){
return "modelAttributeInRVMethod";
}
}
运行结果为:
猜想可不可能与两个使用了@ModelAttribute前后位置有关系,交换位置测试了下,确实有关系。交换后的代码如下:
@ModelAttribute
public void addUser(User user,Model model){
user.setName("Model Attribute in Mehtod ,this method not return value");
model.addAttribute("user",user);
}
@ModelAttribute
public User addUser(User user){
user.setName("Model Attribute in Mehtod ,this method has return value");
return user;
}
@RequestMapping(value = "/testModelAttributeInReturnValueMethod.do",method = RequestMethod.GET)
public String testModelAttributeInReturnValueMethod(){
return "modelAttributeInRVMethod";
}
测试结果如下:
小结,在实际项目中我们可能不会这么写,以上是纯属好奇测试了下,结论为:“谁靠前,谁做主”。
@ModelAttribute注解在方法的入參上的例子代码如下:
/**
* 此方法可以,在页面中使用${user.name}即可访问
* */
@RequestMapping(value = "/testModelAttribute.do",method = RequestMethod.GET)
public String testModelAttribute(@ModelAttribute("user") User user ){
user.setName("wojiushimogui");
return "modelAttribute";
}
modelAttribute.jsp内容如下:
<html>
<body>
<h2>name:${user.name}h2>
body>
html>
测试结果如下:
当入參是String类型对象时,如下所示:
/**
* 此方法不行,在页面中使用${name}不能访问
* */
@RequestMapping(value = "/testModelAttribute2.do",method = RequestMethod.GET)
public String testModelAttribute(@ModelAttribute("name") String name ){
name="wojiushimogui2";
return "modelAttribute2";
}
modelAttribute2.jsp内容如下:
<html>
<body>
<h2>name:${name}h2>
body>
html>
当运行时,结果如下:
从结果可以看出,name为空,原因目前不知道是需要显示的将String类型的name保存在模型对象中,还是应为name是字符串的原因所导致.
最后看下如何将接受到的参数写入到视图中
实现代码,使用@ModelAttribute注解如下:
@ModelAttribute
public void para(@RequestParam("name") String name,Model model){
model.addAttribute("name",name);
}
@RequestMapping(value = "/testModelAttribute3.do",method = RequestMethod.GET)
public String testModelAttribute2(){
return "modelAttribute2";
}
相应的jsp文件核心内容为:${name}
测试结果如下:
以上就是关于集中Spring mvc中传递模型数据到视图中的几种方法介绍。 完整的工程代码可以在这里获取:https://github.com/wojiushimogui/springmvcmodel
1、http://blog.csdn.net/u010785025/article/details/52770509
2、http://www.cnblogs.com/MrSaver/p/6395684.html
3、http://blog.csdn.net/hejingyuan6/article/details/49995987
5、https://my.oschina.net/u/2321816/blog/546964