国产日产欧产精品网站|2022仙踪林官网老狼信息|天天澡天天揉揉Av在线|国产精品成人久久久久久久

SpringMVC框架 第5章 處理響應數據

第5章 處理響應數據

5.1 SpringMVC 輸出模型數據概述

5.1.1提供了以下幾種途徑輸出模型數據

  • ModelAndView: 處理方法返回值類型為 ModelAndView 時, 方法體即可通過該對象添加模型數據
  • Map 及 Model: 入參為 springframework.ui.Model、

org.springframework.ui.ModelMap 或 java.uti.Map 時,處理方法返回時,Map 中的數據會自動添加到模型中。

  • @SessionAttributes: 將模型中的某個屬性暫存到 HttpSession 中,以便多個請求之間可以共享這個屬性
  • @ModelAttribute: 方法入參標注該注解后, 入參的對象就會放到數據模型中

 

5.2處理模型數據之 ModelAndView

5.2.1?ModelAndView介紹

  • 控制器處理方法的返回值如果為 ModelAndView, 則其既包含視圖信息,也包含模型

數據信息。

2)添加模型數據:

MoelAndView addObject(String attributeName, Object attributeValue)

ModelAndView addAllObject(Map<String, ?> modelMap)

3)設置視圖:

void setView(View view)

void setViewName(String viewName)

5.2.2 實驗代碼

  • 增加控制器方法

  • 斷點調試

5.2.2 源碼解析

5.3 處理模型數據之 Map

5.3.1?Map介紹

1)Spring MVC 在內部使用了一個 org.springframework.ui.Model 接口存儲模型數據

具體使用步驟

2)Spring MVC 在調用方法前會創建一個隱含的模型對象作為模型數據的存儲容器

3)如果方法的入參為 Map 或 Model 類型,Spring MVC 會將隱含模型的引用傳遞給這些入參。

4)在方法體內,開發者可以通過這個入參對象訪問到模型中的所有數據,也可以向模型中添加新的屬性數據

5.3.2 實驗代碼

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?4)顯示結果截圖

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?5)? 注意問題:Map集合的泛型,key為String,Value為Object,而不是String??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 6) 測試參數類型

? ?7)? 類層次結構

? 8)? 推薦:Map, ?便于框架移植。

? 9)? 源碼參考

5.4 處理模型數據之 SessionAttributes 注解【了解】

  • 若希望在多個請求之間共用某個模型屬性數據,則可以在控制器類上標注一個 @SessionAttributes, Spring MVC 將在模型中對應的屬性暫存到 HttpSession 中。
  • @SessionAttributes 除了可以通過屬性名指定需要放到會話中的屬性外,還可以通過模型屬性的對象類型指定哪些模型屬性需要放到會話中

例如:

  • @SessionAttributes(types=User.class) 會將隱含模型中所有類型為 User.class 的屬性添加到會話中。
  • @SessionAttributes(value={“user1”, “user2”})
  • @SessionAttributes(types={User.class, Dept.class})
  • @SessionAttributes(value={“user1”, “user2”}, types={Dept.class})?

5.4.1 @SessionAttributes 源碼

5.4.2 實驗代碼

5.5 @ModelAttribute注解

5.5.1 @ModelAttribute注解之使用場景【了解】 ?

5.5.2@ModelAttribute注解之示例代碼

? ?1)? 在方法定義上使用 @ModelAttribute 注解:Spring MVC 在調用目標處理方法前,會先逐個調用在方法級上標注了 @ModelAttribute 的方法。

? ?2)? 在方法的入參前使用 @ModelAttribute 注解:可以從隱含對象中獲取隱含的模型數據中獲取對象,再將請求參數綁定到對象中,再傳入入參

? 3)? 將方法入參對象添加到模型中

? 4)? 示例代碼

  • 頁面表單

  • 增加@ModelAttribute注解

  • 測試

  • 異常

//org.springframework.web.HttpSessionRequiredException: Session attribute 'user' required - not found in session

//出現這個異常,是@SessionAttributes(value={"user"},types={String.class})導致的,去掉類上的這個注解

5.5.3 @ModelAttribute源碼參考

@Target({ElementType.PARAMETER, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface ModelAttribute {

/**

?* The name of the model attribute to bind to.

?* <p>The default model attribute name is inferred from the declared

?* attribute type (i.e. the method parameter type or method return type),

?* based on the non-qualified class name:

?* e.g. "orderAddress" for class "mypackage.OrderAddress",

?* or "orderAddressList" for "List<mypackage.OrderAddress>".

?*/

String value() default "";?

}

5.5.4 @ModelAttribute注解之運行原理

  • 執行@ModelAttribute注解所修飾的方法,將從數據庫中獲取的對象存放到Map集合中,key為user
  • SpringMVC從Map集合中獲取 user對象,將表單數據封裝到與參數名稱對應的user對象屬性上
  • SpringMVC將user對象作為參數,傳遞給目標方法。
  • 注意:@ModelAttribute 注解修飾的方法中,放入到Map集合中的key值,應該和目標方法參數類型的類名稱首字母小寫一致。

5.5.5 @ModelAttribute注解之源碼分析

  • 調用 @ModelAttribute 注解修飾的方法. 實際上把 @ModelAttribute 方法中 Map 中的數據放在了 implicitModel 中.
  • 解析請求處理器的目標參數, 實際上該目標參數來自于 WebDataBinder 對象的 target 屬性
  • 創建 WebDataBinder 對象
  • 確定 objectName 屬性: 若傳入的 attrName 屬性值為 "", 則 objectName 為類名第一個字母小寫.

???????????注意: attrName. 若目標方法的 POJO 屬性使用了 @ModelAttribute 來修飾,

則 attrName 值即為 @ModelAttribute 的 value 屬性值 ??

  • 確定 target 屬性:
  • 在 implicitModel 中查找 attrName 對應的屬性值.
  • 若存在, ok
  • 若不存在: 則驗證當前Handler 是否使用了@SessionAttributes 進行修飾,
  • 若使用了, 則嘗試從 Session 中獲取 attrName 所對應的屬性值.
  • 若 session 中沒有對應的屬性值, 則拋出了異常.
  • 若Handler 沒有使用 @SessionAttributes 進行修飾, 或 @SessionAttributes 中沒有使用 value 值指定的 key和 attrName 相匹配, 則通過反射創建了 POJO 對象 ?

3)??SpringMVC 把表單的請求參數賦給了 WebDataBinder 的 target 對應的屬性.

4) ?SpringMVC 會把 WebDataBinder 的 attrName 和 target 給到 implicitModel. 進

?而傳到 request 域對象中.

  • 把 WebDataBinder 的 target 作為參數傳遞給目標方法的入參.

5.5.6 SpringMVC 確定目標方法 POJO 類型入參的過程

  • 確定一個 key:
  • 若目標方法的 POJO 類型的參數木有使用 @ModelAttribute 作為修飾,

??則 key 為 POJO 類名第一個字母的小寫

  • 若使用了@ModelAttribute 來修飾, 則 key 為 @ModelAttribute 注解的

??value 屬性值.

  • 在 implicitModel 中查找 key 對應的對象, 若存在, 則作為入參傳入

???????若在 @ModelAttribute 標記的方法中在 Map 中保存過, 且 key 和 1) 確定的 key

???一致, 則會獲取到.

  • 若 implicitModel 中不存在 key 對應的對象, 則檢查當前的 Handler 是否使用 @SessionAttributes 注解修飾,
  • 若使用了該注解, 且 @SessionAttributes 注解的 value 屬性值中包含了 key, 則會從 HttpSession 中來獲取 key 所對應的 value 值, 若存在則直接傳入到目標方法的入參中. 若不存在則將拋出異常.
  • 若 Handler 沒有標識 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 則會通過反射來創建 POJO 類型的參數, 傳入為目標方法的參數
  • SpringMVC 會把 key 和 POJO 類型的對象保存到 implicitModel 中, 進而會保存到 request 中.

5.5.7@ModelAttribute注解修飾POJO類型的入參

5.5.8@sessionAttributes注解引發的異常

  • 由@SessionAttributes引發的異常

  • 如果在處理類定義處標注了@SessionAttributes(“xxx”),則嘗試從會話中獲取該屬性,并將其賦給該入參,然后再用請求消息填充該入參對象。如果在會話中找不到對應的屬性,則拋出 HttpSessionRequiredException 異常

 

 

湖南省| 大冶市| 阿荣旗| 新兴县| 德阳市| 赤城县| 信宜市| 湘乡市| 巢湖市| 定兴县| 山西省| 秦安县| 小金县| 绍兴县| 西宁市| 通海县| 萍乡市| 广汉市| 阳泉市| 五常市| 承德县| 百色市| 乐东| 讷河市| 彭泽县| 乐陵市| 乌苏市| 太谷县| 长子县| 晋中市| 玉门市| 德昌县| 兴义市| 榕江县| 洞口县| 鞍山市| 龙里县| 新昌县| 平远县| 娄烦县| 睢宁县|