SpringMVC處理模型數據

• Spring MVC提供了以下幾種途徑輸出模型數據:
§ ModelAndView:
□ 處理方法返回值類型爲ModelAndView時,方法體即可通過該對象添加模型數據。
§ Map及 Model:
□ 入參爲 org.springframework.ui.Model、org.springframework.ui.ModelMap或java.uti.Map時,處理方法返回時,Map中的數據會自動添加到模型中。
§ @SessionAttributes:
□ 將模型中某個屬性暫存到 HttpSession 中,以便多個請求之間可以共享這個屬性。
§ @ModelAttribute:
□ 方法中入參標註該註解後,入參的對象就會放到數據模型中。



1. ModelAndView:
a. 目標方法的返回值可以是ModelAndView類型,其中包含視圖和模型信息。
b. SpringMVC會把ModelAndView的model中數據放入到 request域對象中。(從域對象中取出的方式爲${requestScope.time}.)

c. 
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
String viewName = SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
// 添加模型數據到 ModelAndView 中.
modelAndView.addObject("time", new Date());
return modelAndView;
}
2. Model:
a. 目標方法可以添加map類型的參數
/**
*目標方法的入參可以是map類型
*@parammap
*@return

*/
@RequestMapping("/testMap")
publicStringtestMap(Map<String,Object>map){
System.out.println(map.getClass().getName());
map.put("names",Arrays.asList("Tom","Jerry","Mike"));
returnSUCCESS;
}
b. Arrays.asList()將一個數組轉化成一個List對象,這個方法會返回一個ArrayList類型的對象,這個ArrayList類並非java.util.ArrayList類,而是Arrays類靜態內部類!
3. SessionAttributes註解
a. 該註解可以設定將屬性值設置如 Session域中(實際上使用的是value屬性值)
b. 還可以通過模型屬性的對象類型指定哪些模型屬性需要放在會話中(實際上使用的是types屬性值)。
注意:該註解只能放在類上面,而不能修飾方法。
@SessionAttributes(value={"user"},types={String.class})
@RequestMapping("/springmvc")
@Controller
publicclassSpringMVCTest{

privatestaticfinalStringSUCCESS="success";

@RequestMapping("/testSessionAttributes")
publicStringtestSessionAttributes(Map<String,Object>map){
Useruser=newUser("Tom","123456","[email protected]",15);
map.put("user",user);
map.put("school","atguigu");
returnSUCCESS;
}
4. @ModelAttribute註解
a. 在方法定義上使用#ModelAttribute註解:SpringMVC在調用目標處理方法之前,會先逐個調用在方法級上標註了@ModelAttribute 的方法。
b. 在方法的入參前使用 @ModelAttribute 註解:
i. 可以從隱含對象中獲取隱含模型數據中獲取對象,再講請求參數綁定到對象中,在傳入入參。
ii. 將方法入參對象添加到模型中。
iii. 有@ModelAttribute 標記的方法,會子啊每個目標方法執行之前被SpringMVC調用!
iv. @ModelAttribute 註解也可以來修飾目標方法POJO類型的入參,其value屬性值有如下作用
1) SpringMVC 會使用 value 屬性值在 implicitModel 中查找對應的對象,若存在則會直接傳入到目標方法對應的入參中。
2) SpringMVC 會 value 爲 key POJO 類型的對象爲 value, 存入到 request中.
c. 例子:
@ModelAttribute
public void getUser(@RequestParams(value="id",required=false) Integer id, Map<String, Object> map){
System.out.println("modelAttribute method");
if(id != null){
//模擬從數據庫中獲取對象
User user = new User(1,"Tom","123456","[email protected]",12);
System.out.println("從數據庫中獲取一個對象:" +user);
//將新的 user 對象放入model中
map.put("user", user);
}
}

@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改: "+user);
return SUCCESS;
}

d. 運行流程:
i. 執行@ModelAttribute 註解修飾的方法:從數據庫中取出對象,把對象放入到 Map 中。鍵爲:user。
ii. SpringMVC 從 Map 中取出 User對象,並把表單請求參數賦值給 User 對象的對應屬性。
iii. SpringMVC 把上述對象傳入目標方法的參數。
iv. 注意:在 @ModelAttribute 修飾的方法張,放入到 Map 時的鍵需要和目標方法的入參類型的第一個字母小寫的字符串一致!
i. 源代碼分析的流程
1) 調用@ModelAttribute註解修飾的方法.實際上把@ModelAttribute方法中的Map 中的數據放在了 implicitModel中.
2) 解析請求處理器的目標參數,實際上該目標參數來自於WebDataBinder 對象的 target 屬性.
a) 創建WebDataBinder對象:
One. 確定ObjectName 屬性.若傳入的 attrName 屬性爲 “”,則objectName爲類名的第一個字母小寫,注意:attrName.若目標方法的 POJO 屬性使用了@ModelAttribute 來修飾,則attrName 值即爲ModelAttribute的屬性值。
Two. 確定 target 屬性.
1. 在implicitModel 中查找 attrName 對應的屬性值。若存在,ok
2. 若不存在:則驗證當前Handler 是否使用了 @SessionAttributes 進行修飾,若使用了,則嘗試從 Session 中獲取 attrName 所對應的屬性值。若 session 中沒有對應的屬性值,則拋出了異常。
3. 若 Handler 沒有使用 @SessionAttributes 進行修飾,或@SessionAttributes 中沒有使用 value 值指定的鍵和 attrName 相互匹配,則通過反射創建了 POJO 對象
b) SpringMVC 把表單的請求參數賦值給了 WebDataBinder 和target 對應的屬性。
c) *SpringMVC 會把 WebDataBinder 的 attrName 和 target 傳遞到 implicitModel,進而傳到 request 域對象中。
d) 把 WebDataBinder 的 target 作爲參數傳遞給入參。(注:implicit 爲隱含的意思) 
5. 小結:
i. SpringMVC 確定目標方法 POJO 類型入參的類型
i. 確定一個key:
1) 若目標方法 POJO 類型的參數沒有使用 @ModelAttribute 作爲修飾,則 Key 爲POJO 類名第一個字母的小寫。
2) 若使用了 @ModelAttribute 來修飾,則key爲@ModelAttribute 註解 value屬性值.
ii. 在ImplicitModel 中查找與 key 對應的對象,若存在,則作爲入參傳入
1) 若在@ModelAttribute 標記的方法中在 Map 中保存過,且 key 和 1 確定的 key 保持一致,則會獲取到。
iii. 若 implicitModel 中不存在 key 對應的對象,則檢查當前的 Handler 是否使用 @SessionAttributes 若使用了該註解,且@SessionAttributes 註解的 value 屬性值中包含了 key,則會從 HttpSession 中獲取 key 所對應的 value 值,若存在則直接傳入到目標方法的入參中. 若不存在則將拋出異常.
iv. 若 Handler 沒有標識 @SessionAttributes 註解或 @SessionAttributes 直接的value 值中不含key,則會通過反射來創建 POJO 類型的參數,傳入爲目標方法的參數。

v. SpringMVC 會把 key 和POJO 類型的對象保存到 implicitModel 中,進而會保存到 request 中。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章