SpringMVC處理模型資料

TZQ_DO_Dreamer發表於2014-12-04
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中獲取模型資料,然後傳入到目標方法中。


相關文章