您的位置:首页 > 编程语言 > Java开发

Spring MVC 传递模型数据到视图中方法总结

2017-05-13 16:16 597 查看

Spring MVC 传递模型数据到视图中的方法总结

一般来说,有如下的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

该注解即可注解在有返回值的方法上,无返回值的方法上,还可以注解在方法入参上,当入參标注该注解后, 入参的对象就会放到数据模型中,具体将在后面进行介绍。

下面将分别以例子的形式进行介绍。

ModelAndView

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}这三种写法效果是一样的,在不同的书籍/博客中所看到的都是其中的一种。

2、Model/Map/ModelMap

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一样。

经测试验证是可以正常工作的。

3、@SessionAttributes

若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @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<String,Object> 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 ,即可看到如下的输出结果:



4、@ ModelAttribute

前面谈到SpringMVC在每次调用请求处理方法时,都会创建Model类型的一个隐含实例对象。如果准备使用此实例,则可以在方法中添加一个Model类型的输入参数。事实上,还可以使用在方法中添加@ModelAttribute注释类型来访问Model实例。

  可以用@ModelAttribute来注释方法参数:带有@ModelAttribute注解的方法会将其输入或创建的参数对象添加到Model对象中(若方法中没有显式添加)。

  可以用@ModelAttribute标注一个非请求的处理方法(有返回值,无返回值):被@ModelAttribute注释的方法会在此controller每个方法执行前被执行。 

4.1 @ ModelAttribute注解在有返回值的方法上

@ 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>


测试结果如下:



4.2 @ModelAttribute注解在void返回值的方法上

@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";
}


测试结果如下:



小结,在实际项目中我们可能不会这么写,以上是纯属好奇测试了下,结论为:“谁靠前,谁做主”。

4.3 @ModelAttribute注解在方法的入參上

@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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: