第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Spring MVC 入門教程 Spring MVC 入門教程 Spring MVC 數(shù)據(jù)模型(下)

Spring MVC 數(shù)據(jù)模型(下)

1. 前言

Spring MVC 為了解決 HTTP 協(xié)議的無狀態(tài)性,提供了很多能適用于不同作用域需求的模型對象,從而保證程序中的數(shù)據(jù)能在開發(fā)者需要的地方出現(xiàn)。

本節(jié)課繼續(xù)和大家聊聊 Spring MVC 中的數(shù)據(jù)模型組件。

  • Model;
  • ModelMap;
  • ModelAndView。

2. 更多數(shù)據(jù)模型

模型是一個用的很廣的概念。本課程中數(shù)據(jù)模型應(yīng)該有 2 層含義:

  • WEB 程序中封裝數(shù)據(jù)的組件;
  • 此模型對象會有自己特定作用域。

上一小節(jié)中,向大家介紹了 Map 模型對象,其本質(zhì)是對 HttpServletRequest 對象中的存儲功能的引用。Map 還是比較原始和天然的。Spring MVC 為了展現(xiàn)自己的特色服務(wù),對 Map 進(jìn)行了多層面的封裝,提供了更豐富的數(shù)據(jù)模型對象。

Tips: 重要的事情強調(diào)一下,你將認(rèn)識或使用到的數(shù)據(jù)模型會很多,但其本質(zhì)是:

  • 如果是請求作用域,你只是在間接使用 HttpServletRequest 對象;
  • 如果是會話作用域,你只是在間接使用 HttpSession 對象。

2.1 Model

這個字面意思很明顯,咱就是一個模型組件。

Model 是一個接口類型,Model 接口中提供了標(biāo)準(zhǔn)的保存數(shù)據(jù)的方法。

Model addAttribute(String attributeName, @Nullable Object attributeValue);

Model 使用起來很簡單,將 Model 設(shè)為控制器方法的參數(shù)便可 ,其它的交給 Spring MVC,因為 Model 是一個接口類型,Spring MVC 會為我們辨明身份,注入一個具體的實例對象。

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login01(User user,Model map) {
	if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
		map.addAttribute("loginUser", user);
		return "index";
	}
	return "fail";
}

Model 接口中還有其它的方法,但都不常用,感興趣的話大家可以查閱其源代碼或 API 文檔。

2.2 ModelMap

這個組件的字面意思是說,我是用 Map 存儲數(shù)據(jù)的模型??梢圆殚喴幌缕湓创a結(jié)構(gòu).,本質(zhì)上還就是一個鏈表實現(xiàn)的 Map,都是一家人呀。

Map、Map …… 又見 Map。

ModelMap 中提供的方法和 Model 接口差不多,不同之處在于有自己的實現(xiàn)。

public class ModelMap extends LinkedHashMap<String, Object> {
	public ModelMap addAttribute(String attributeName, @Nullable Object attributeValue) {
		Assert.notNull(attributeName, "Model attribute name must not be null");
		put(attributeName, attributeValue);
		return this;
	} 
}

如何使用?

Spring MVC 的世界,會讓你感覺到自己的多余,因為很多事情 Spring MVC 都幫你溫柔的解決。一樣的,只需要設(shè)定為控制器方法的參數(shù)就可以了。

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login01(User user,ModelMap map) {	
	if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
		map.addAttribute("loginUser", user);
		return "index";
	}
	return "fail";
}

會發(fā)現(xiàn),大家除了名字不一樣外,其它好像也沒有什么不一樣。

2.3 ModelAndView

從字面上了解這個組件,應(yīng)該是除了充當(dāng)模型的功能外,還與視圖有關(guān)系。想要徹底看透它,很簡單,查閱一下源代碼結(jié)構(gòu)。

public class ModelAndView {
@Nullable
private Object view;
@Nullable
private ModelMap model;
//……
}

圖片描述

Tips: 搞了半天,會發(fā)現(xiàn),ModelAndView 其實就是封裝了 ModelMap 外加一個用來保存視圖相關(guān)信息的 view 對象。

其實,大家都是一家人,根源是相同的,具有共同的遺傳基因,當(dāng)然,還會有只屬于自己的獨有功能。

ModelAndView 和其它的數(shù)據(jù)模型使用起來稍有一點不同,往往是作為控制器方法的返回值。

@RequestMapping(value="/login",method=RequestMethod.POST)
public ModelAndView login01(User user) {
	ModelAndView mv=new ModelAndView();
	if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
		mv.addObject("loginUser", user);
		mv.setViewName("index");
		return mv;
	}
	mv.setViewName("fail");
	return mv;
}

Tips: ModelAndView 把數(shù)據(jù)模型和視圖拼在了一起,便于一次性交給前端控制器處理。

3. 會話作用域

Map、Model 、ModelMap、ModelAndView 這幾個數(shù)據(jù)模型組件,默認(rèn)情況下,其中所保存的數(shù)據(jù)都是請求作用域級別的。

在很多應(yīng)用場景下,需要數(shù)據(jù)在整個會話過程中都能訪問到。比如登錄者信息、購物車信息等。

面對這種數(shù)據(jù)需求時,Spring MVC 又如何實現(xiàn)?

你能想到的,Spring MVC 早就想到了。使用 @SessionAttributes 注解即可。

@SessionAttributes 注解是類級別的注解,需要添加在控制器類的前面。

@Controller
@RequestMapping("/user")
@SessionAttributes("loginUser")
public class UserAction {
@RequestMapping(value="/login",method=RequestMethod.POST)
	public ModelAndView login01(User user) {
	ModelAndView mv=new ModelAndView();
	if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
		mv.addObject("loginUser", user);
		mv.setViewName("index");
		return mv;
	}
	mv.setViewName("fail");
	return mv;
}
}

Tips: @SessionAttributes(“l(fā)oginUser”) 中的屬性名 loginUser 必須保持和 mv.addObject(“l(fā)oginUser”, user); 中的 loginUser 名一樣。

從底層思維來講, Spring MVC 即把數(shù)據(jù)保存到請求作用域中、也保存到會話作用域中。

測試時,只需要在 index.jsp 中添加如下面的 EL 表達(dá)式,指明數(shù)據(jù)的作用域。

<body>
 我是首頁
 <br/>
 請求作用域中得到當(dāng)前登錄者:${requestScope.loginUser.userName}
 <br/>
 會話作用域中得到當(dāng)前登錄者:${sessionScope.loginUser.userName}
</body>

啟動瀏覽器,打開登錄頁面,輸入登錄名、登錄密碼、點擊登錄,然后在瀏覽器中會看到無論是請求作用域、還是會話作用域中都可以獲取到登錄者的信息。

圖片描述

4. 小結(jié)

本節(jié)課程和大家一起講解了 Model 、ModelMap、ModelAndView 數(shù)據(jù)模型,并講解了可以使用 @SessionAttributes 注解提升數(shù)據(jù)模型的作用域。

從功能層面上講,所有數(shù)據(jù)模型組件的功能是一樣的。從底層上講,區(qū)別在于實現(xiàn) Map 的數(shù)據(jù)結(jié)構(gòu)。

  • 直接使用 Map 做數(shù)據(jù)模型時, Spring MVC 注入的是一個 LinkedHashMap 實例。
  • ModelMap 是 LinkedHashMap 的子類,本質(zhì)還是 LinkedHashMap,只是封裝了 put 方法,讓其顯得高級一點。
  • Model 是接口,Spring MVC 注入的也是 LinkedHashMap 實例。

所以,無論是使用 Map 、Model 還是 ModelMap 其實都是在借助 LinkedHashMap 完成數(shù)據(jù)的存儲。其區(qū)別在于應(yīng)用場景,有時,需要接口注入,有時可能需要類注入。當(dāng)然,還會有自己的功能實現(xiàn)。