首页 > 代码库 > SpringMVC处理模型数据

SpringMVC处理模型数据

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=http://www.mamicode.com/"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=http://www.mamicode.com/{"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=http://www.mamicode.com/{“user1”, “user2”})
@SessionAttributes(types={User.class, Dept.class})
@SessionAttributes(value=http://www.mamicode.com/{“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=http://www.mamicode.com/{"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中获取模型数据,然后传入到目标方法中。


SpringMVC处理模型数据