@ModelAttribute 綁定值
在controller執(zhí)行之前先執(zhí)行的方式,可以使用@RequestParam注解獲取傳入的值劝枣,當(dāng)定義該注解后該類的所以請(qǐng)求都會(huì)先執(zhí)行
/**
* 1. 有 @ModelAttribute 標(biāo)記的方法, 會(huì)在每個(gè)目標(biāo)方法執(zhí)行之前被 SpringMVC 調(diào)用!
* 2. @ModelAttribute 注解也可以來修飾目標(biāo)方法 POJO 類型的入?yún)? 其 value 屬性值有如下的作用:
* 1). SpringMVC 會(huì)使用 value 屬性值在 implicitModel 中查找對(duì)應(yīng)的對(duì)象, 若存在則會(huì)直接傳入到目標(biāo)方法的入?yún)⒅?
* 2). SpringMVC 會(huì)一 value 為 key, POJO 類型的對(duì)象為 value, 存入到 request 中.
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id,
Map<String, Object> map){
System.out.println("modelAttribute method");
if(id != null){
//模擬從數(shù)據(jù)庫中獲取對(duì)象
User user = new User(1, "Tom", "123456", "tom@atguigu.com", 12);
System.out.println("從數(shù)據(jù)庫中獲取一個(gè)對(duì)象: " + user);
map.put("user", user);
}
}
/**
* 運(yùn)行流程:
* 1. 執(zhí)行 @ModelAttribute 注解修飾的方法: 從數(shù)據(jù)庫中取出對(duì)象, 把對(duì)象放入到了 Map 中. 鍵為: user
* 2. SpringMVC 從 Map 中取出 User 對(duì)象, 并把表單的請(qǐng)求參數(shù)賦給該 User 對(duì)象的對(duì)應(yīng)屬性.
* 3. SpringMVC 把上述對(duì)象傳入目標(biāo)方法的參數(shù).
*
* 注意: 在 @ModelAttribute 修飾的方法中, 放入到 Map 時(shí)的鍵需要和目標(biāo)方法入?yún)㈩愋偷牡谝粋€(gè)字母小寫的字符串一致!
*
* SpringMVC 確定目標(biāo)方法 POJO 類型入?yún)⒌倪^程
* 1. 確定一個(gè) key:
* 1). 若目標(biāo)方法的 POJO 類型的參數(shù)木有使用 @ModelAttribute 作為修飾, 則 key 為 POJO 類名第一個(gè)字母的小寫
* 2). 若使用了 @ModelAttribute 來修飾, 則 key 為 @ModelAttribute 注解的 value 屬性值.
* 2. 在 implicitModel 中查找 key 對(duì)應(yīng)的對(duì)象, 若存在, 則作為入?yún)魅? * 1). 若在 @ModelAttribute 標(biāo)記的方法中在 Map 中保存過, 且 key 和 1 確定的 key 一致, 則會(huì)獲取到.
* 3. 若 implicitModel 中不存在 key 對(duì)應(yīng)的對(duì)象, 則檢查當(dāng)前的 Handler 是否使用 @SessionAttributes 注解修飾,
* 若使用了該注解, 且 @SessionAttributes 注解的 value 屬性值中包含了 key, 則會(huì)從 HttpSession 中來獲取 key 所
* 對(duì)應(yīng)的 value 值, 若存在則直接傳入到目標(biāo)方法的入?yún)⒅? 若不存在則將拋出異常.
* 4. 若 Handler 沒有標(biāo)識(shí) @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 則
* 會(huì)通過反射來創(chuàng)建 POJO 類型的參數(shù), 傳入為目標(biāo)方法的參數(shù)
* 5. SpringMVC 會(huì)把 key 和 POJO 類型的對(duì)象保存到 implicitModel 中, 進(jìn)而會(huì)保存到 request 中.
*
* 源代碼分析的流程
* 1. 調(diào)用 @ModelAttribute 注解修飾的方法. 實(shí)際上把 @ModelAttribute 方法中 Map 中的數(shù)據(jù)放在了 implicitModel 中.
* 2. 解析請(qǐng)求處理器的目標(biāo)參數(shù), 實(shí)際上該目標(biāo)參數(shù)來自于 WebDataBinder 對(duì)象的 target 屬性
* 1). 創(chuàng)建 WebDataBinder 對(duì)象:
* ①. 確定 objectName 屬性: 若傳入的 attrName 屬性值為 "", 則 objectName 為類名第一個(gè)字母小寫.
* *注意: attrName. 若目標(biāo)方法的 POJO 屬性使用了 @ModelAttribute 來修飾, 則 attrName 值即為 @ModelAttribute
* 的 value 屬性值
*
* ②. 確定 target 屬性:
* > 在 implicitModel 中查找 attrName 對(duì)應(yīng)的屬性值. 若存在, ok
* > *若不存在: 則驗(yàn)證當(dāng)前 Handler 是否使用了 @SessionAttributes 進(jìn)行修飾, 若使用了, 則嘗試從 Session 中
* 獲取 attrName 所對(duì)應(yīng)的屬性值. 若 session 中沒有對(duì)應(yīng)的屬性值, 則拋出了異常.
* > 若 Handler 沒有使用 @SessionAttributes 進(jìn)行修飾, 或 @SessionAttributes 中沒有使用 value 值指定的 key
* 和 attrName 相匹配, 則通過反射創(chuàng)建了 POJO 對(duì)象
*
* 2). SpringMVC 把表單的請(qǐng)求參數(shù)賦給了 WebDataBinder 的 target 對(duì)應(yīng)的屬性.
* 3). *SpringMVC 會(huì)把 WebDataBinder 的 attrName 和 target 給到 implicitModel.
* 近而傳到 request 域?qū)ο笾?
* 4). 把 WebDataBinder 的 target 作為參數(shù)傳遞給目標(biāo)方法的入?yún)?
*/
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改: " + user);
return SUCCESS;
}