Spring MVC提供了以下几种方式输出模型数据:
1.使用ModelAndView输出模型数据,代码如下:
<a href="TestRequestMapping/TestModelAndView">TestModelAndView</a>
/**
* 使用ModelAndView处理模型数据
* 该方法的返回值类型是ModelAndView类型,其中包含了视图和数据模型信息
* Spring MVC会把ModelAndView中Model中的数据放到request域对象中
* @return
*/
@RequestMapping("TestModelAndView")
public ModelAndView testModelAndView()
{
String viewName="success";
ModelAndView modelAndView=new ModelAndView(viewName);
//将模型数据添加到ModelAndView中
modelAndView.addObject("time", new Date());
return modelAndView;
}
2.使用map作为方法的入参处理数据模型:
<a href="TestRequestMapping/TestMap">TestMap</a>
/**
* 使用map作为方法的入参处理数据模型
* map中的数据也会被放到目标页面的请求域对象中
* @param map
* @return
*/
@RequestMapping("TestMap")
public String testMap(Map<String, Object> map)
{
map.put("name", "Tom");
return "success";
}
3.使用@SessionAttributes将模型数据放入Session域对象中:
首先在控制器类的上边添加一个@SessionAttributes注解
@SessionAttributes(value={"user"})
其中value=“xxx”表示将名为xxx的模型数据放入Session域对象中
接下来上代码
<a href="TestRequestMapping/TestSessionAttributes">TestSessionAttributes</a>
/**
* @SessionAttributes除了可以通过属性名指定需要放到会话中的属性外(使用value属性),
* 还可以通过模型属性的对象类型来指定哪些模型属性需要放到会话中(使用types属性)
* 该注解只能放在类上边不能放在方法上边
* @param map
* @return
*/
@RequestMapping("TestSessionAttributes")
public String testSessionAttributes(Map<String, Object> map)
{
User user=new User();
user.setUserName("zhangsan");
user.setAge(21);
user.setEmail("517850233@qq.con");
map.put("user", user);
return "success";
}
4.@ModelAttribute注解(较难理解)
由于该例子较难理解,我自己也不是太懂,因此暂且先记下
<form action="TestRequestMapping/TestModelAttribute" method="post">
username:<input type="text" name="userName" value="Tom">
<br>
id:<input type="text" name="id" value="1">
<br>
email:<input type="text" name="email" value="Tom@atguigu.com">
<br>
age:<input type="text" name="age" value="12">
<br>
<input type="submit" value="Submit">
</form>
/**
* 运行流程:
* 1.执行@ModelAttribute修饰的方法:从数据库中取出对象,并放入Map中,键为user
* 2.Spring MVC从Map中取出User对象,并把表单请求参数赋给该User对象的对应属性
* 3.Spring MVC把上述对象传入到目标方法的参数中
* @param user
* @return
*/
@RequestMapping("TestModelAttribute")
public String testModelAttribute(User user)
{
System.out.println("修改:"+user);
return "success";
}
/**
* 具有@ModelAttribute的方法在任何目标方法被调用之前被SpringMVC调用
* @param id
* @param map
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id,
Map<String,Object> map)
{
if(id!=null)
{
//模拟从数据库中取出一个id为1的对象
User user =new User(1, "Tom","123456", "Tom@atguigu.com", 12);
map.put("user", user);
}
}
接下来写一些通过源码分析的结论,由于自己还不是很理解,因此暂且直接将结论记下:
Spring MVC确定目标方法POJO类型入参的过程
1.确定一个key
(1)若目标方法的类型参数没有使用@ModelAttribute作为修饰,则key为POJO类名的第一个字母小写
(2)若使用了@ModelAttribute作为修饰,则key为@ModelAttribute注解的value属性值
2.在implicitModel中查找key对应的的对象,若存在,则作为入参
(1)若在@ModelAttribute标记的方法中在Map中保存过,且key和1确定的key一致,则会获取到
3.在implicitModel查找key对应的对象,若不存在,则检查当前的Handler是否使用了@SessionAttributes注解修饰,若使用了该注解,且SeesionAttributes中的value值中包含了key,则从HttpSession中获取key所对应的value,若存在则作为入参传入目标方法,若不存在则抛出异常
4.若Handler没有表示@SessionAttributes注解,或者@SessionAttributes注解中的value不包含key,则会通过反射机制创建POJO对象传入为目标方法的参数
5.SpringMVC会把key和POJO类型保存到implicitModel中,进而保存到request域中