1. 所谓处理模型数据:把 action 方法中返回的对象,集合如何放入到域对象中。
1). 域对象:pageContext, request, session, application
2. Spring MVC 提供了以下几种途径输出模型数据:
1)ModelAndView: 处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据
@RequestMapping("/testModelAndView" )
public ModelAndView testModelAndView(){
ModelAndView modelAndView = new ModelAndView(SUCCESS );
//添加模型数据到 ModelAndView 中
modelAndView.addObject( "time", new Date());
return modelAndView;
}
2). Map 及 Model: 入参为 org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
-------------------------------------------------------------------------------------------------------------------------
@RequestMapping("/testMap" )
public String testMap(Map<String,Object>
map){
System. out.println(map.getClass().getName());
map.put( "time", new Date());
return SUCCESS ;
}
==================================================================
/**
* 步骤:
* 1. 从数据库中取出对应的记录: [id=1, username=aa, email=aa@163.com, age=11]
* 2. SpringMVC 为其对应的属性赋值: [id=1, username=aa, email=bb@163.com, age=13]
* 3.页面传值执行修改: update: [id=1, username=aa, email=bb@163.com, age=13]
*/
@RequestMapping( "/testModelAttribute")
public String testModelAttribute(@ModelAttribute("user" )
User user){
System. out.println("update: " +
user);
return SUCCESS ;
}
·················································································································································
/**
* 可以模拟 Struts2 的 Prepare 拦截器!
*/
@ModelAttribute
public void getUser(@RequestParam (value="id" ,
required=false) Integer id,
Map<String, Object> map){
if(id != null ){
User user = userDao.getUser(id);
System. out.println(user);
map.put( "user", user);
System. out.println("getUser" );
}
}
解释:在 Spring MVC 中使用 @ModelAttribute() 注解,把该注解标记到一个有返回值的方法上:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了 @ModelAttribute 的方法, 并将这些方法的返回值添加到模型中。
==========================================================================
★@SessionAttributes:
将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性
示例:
@SessionAttributes(value={"username" ,"age" ,"user" },types={String.class})
◆使用 @SessionAttributes:
a. @SessionAttributes 注解只能标记在类的上边,而不能标记在方法上。
b. 作用:若方法中把模型数据以 key 的方式存入到 request 中,若在类的上面使用了 @SessionAttributes() 注解,且value 值中包括了 key,则 SpringMVC也会把该模型数据放入到 session 中。
◆@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中@SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”})
@SessionAttributes(types={User.class, Dept.class})
@SessionAttributes(value={“user1”, “user2”}, types={Dept.class})
◆关于 @SessionAttributes 奇葩的一个异常
org.springframework.web.HttpSessionRequiredException: Session attribute ‘user‘ required - not found in session
分析:
1- 若提交表单,目标方法的入参为和表单对应的 bean,则 Springmvc 会自动的把表单对应的 bean 放入到 request 中,且键:类名第一个字母小写,值:bean 实例
@RequestMapping("/testSessionAttributes3")
public String testSessionAttributes3(User user){
System.out.println(user);
return "success";
}
相当于:
@RequestMapping("/testSessionAttributes3")
public String testSessionAttributes3(User user, Map<String, Object> map){
System.out.println(user);
map.put("user", user);
return "success";
}
或
@RequestMapping("/testSessionAttributes3")
public String testSessionAttributes3(@ModelAttribute("user") User user){
System.out.println(user);
return "success";
}
2- 若此时在目标方法所在的类上面添加 @SessionAttributes 注解,且其键和目标方法 @ModelAttribute 的键相同,则在调用目标方法前, SpringMVC 会先
上 session 中获取属性值,并把该属性值赋给入参,若 session 中没有对应的属性,则抛出上述的异常。
3- 解决:使 @ModelAttribute 的键和 @SessionAttributes 的键不同;在调用目标方法前,使 Session 中有对应的属性,新定义一个方法,方法前添加 @ModelAttribute 注解,且键为 @SessionAttribute() 的 key
@SessionAttributes(value={"user"})
@Controller
public class CotrollerTest {
@ModelAttribute("user")
public User getUser(){
return new User();
}
@RequestMapping("/testSessionAttributes3")
public String testSessionAttributes3(@ModelAttribute("user") User user){
System.out.println(user);
return "success";
}
}
分析执行顺序:
调用 getUser 方法,返回 user,注解到该方法的 @ModelAttribute() 注解的值为 user, 且类上面的 @SessionAttributes() 的值也有 user, 则把返回值放入到 session 中!;调用目标方法,
注意到入参有 @ModelAttribute("user") 修饰,且 user 和类的 @SessionAttributes() 的值中匹配,则从 Sessioin中获取模型数据,然后传入到目标方法中。