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

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

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

1. 前言

本節(jié)課,將和大家一起聊聊 Spring MVC 在不同的作用域中如何封裝數(shù)據(jù)。

繼續(xù)之前,先理解本節(jié)課程提出的數(shù)據(jù)模型概念:Spring MVC 提供的在特定作用域內(nèi)封裝數(shù)據(jù)的組件。掌握理解數(shù)據(jù)模型組件的使用便是全文重點(diǎn)。

2. 請(qǐng)求作用域

WEB 程序的應(yīng)用層使用的是 HTTP 協(xié)議,HTTP 協(xié)議有一個(gè)特點(diǎn),無(wú)狀態(tài)。

所謂無(wú)狀態(tài)指上一次請(qǐng)求與下一次請(qǐng)求之間是隔離的,沒有內(nèi)在的聯(lián)系。更通俗的講,可理解為一個(gè)患有健忘癥的人,只記得當(dāng)前自己在做什么,不記得自己曾經(jīng)做過(guò)什么,更不會(huì)知道自己將來(lái)要做什么。

HTTP 協(xié)議的這種無(wú)狀態(tài),最初設(shè)計(jì)時(shí)是從安全角度考慮。但是,在某些應(yīng)用場(chǎng)景下,如購(gòu)物車的應(yīng)用場(chǎng)景下,卻顯得無(wú)能為力。購(gòu)物車中的商品不一定是一次請(qǐng)求下的結(jié)果,往往是多次請(qǐng)求下的結(jié)果。

也就是說(shuō),購(gòu)物車需要保存每一次請(qǐng)求獲取到的數(shù)據(jù)。顯然,直接使用 HTTP 協(xié)議是無(wú)法做到的。就需從技術(shù)層面上提供解決方案。

原生 Servlet 提供了 3 個(gè)作用域,可以根據(jù)用戶的需要來(lái)保存每一次請(qǐng)求過(guò)程中產(chǎn)生的數(shù)據(jù)。

  • 請(qǐng)求作用域: 使用 HttpServletRequest 組件存儲(chǔ)的數(shù)據(jù)可以在每一次的請(qǐng)求周期內(nèi)存在。 請(qǐng)求結(jié)束,數(shù)據(jù)也將消失;
  • 會(huì)話作用域: 使用 HttpSession 組件保存的數(shù)據(jù)能在整個(gè)會(huì)話生命周期內(nèi)存在。如購(gòu)物車就可以保存在會(huì)話作用域中;
  • 應(yīng)用程序作用域: 使用 ServletContext 組件保存的數(shù)據(jù)在整個(gè)應(yīng)用程序生命周期之內(nèi)存在。

Spring MVC 中,把數(shù)據(jù)保存在請(qǐng)求作用域,或是說(shuō)在整個(gè)請(qǐng)求過(guò)程中數(shù)據(jù)都有效。有 2 種解決方案

  • 直接使用 HttpServletRequest 組件;
  • 使用 Spriing MVC 提供的高級(jí)數(shù)據(jù)模型組件。

2.1 使用原生 HttpServletRequest

先設(shè)定一個(gè)需要請(qǐng)求作用域的需求場(chǎng)景:

需求說(shuō)明: 用戶登錄成功后,在登錄成功后的頁(yè)面中顯示登錄者的信息。

操作流程:

  1. 準(zhǔn)備好 3 個(gè)靜態(tài)頁(yè)面;
  • login.html: 登錄頁(yè)面,接收用戶輸入的用戶名、密碼等與登錄相關(guān)的信息;
  • index.html: 登錄成功后跳轉(zhuǎn)到的頁(yè)面;
  • fail.html: 登錄失敗后跳轉(zhuǎn)到的頁(yè)面。
  1. 編寫 login.html 頁(yè)面中的登錄表單;
<form action="user/login" method="post">
   	姓名:<input name="userName" value="" type="text"> <br />
    密碼:<input name="userPassword" value="" type="password">
       <br />
       <input name="btnLogin" value="登錄" type="submit">
       <input name="btnRe" value="重置" type="reset">
</form>
  1. 編寫響應(yīng)控制器;
@RequestMapping("/login")
public String login(User user,HttpServletRequest request) {
   	if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
   		//請(qǐng)求作用域	
	    request.setAttribute("loginUser", user);
	   	return "index";
   	}
   	return "fail";
}

login()方法有 2 個(gè)參數(shù):

  • user 參數(shù):OOP 的方式綁定請(qǐng)求包中傳過(guò)來(lái)的數(shù)據(jù);
  • request 參數(shù): 注入原生 HttpServletRequest 組件。Spring 的注入功能很厲害的,只要你需要,它便能幫你拿到。登錄者的信息保存在 HttpServletRequest 對(duì)象中。

Tips: HttpServletRequest 組件具有服務(wù)器端數(shù)據(jù)存儲(chǔ)功能,本質(zhì)是內(nèi)部維護(hù)有一個(gè) map 對(duì)象。HttpServletRequest 的生命周期較短,從請(qǐng)求開始到請(qǐng)求結(jié)束。所以,其保存的數(shù)據(jù)也只能在整個(gè)請(qǐng)求范圍內(nèi)有效。

  1. 編寫 index.html 和 fail.html 頁(yè)面。
  • idnex.html 頁(yè)面內(nèi),使用 EL 表達(dá)式,讀取請(qǐng)求作用域中的登錄者信息;
<body>
我是首頁(yè)
<br/>
當(dāng)前登錄者:${loginUser.userName}
</body>

Tips: 這里有一個(gè)坑,需要提醒一下。通過(guò) maven 創(chuàng)建的 WEB 項(xiàng)目的 web.xml 文件的頭信息版本偏低,使用 EL 表達(dá)式時(shí),可能會(huì)在頁(yè)面中出現(xiàn)紅色的錯(cuò)誤提示,其實(shí)并不影響發(fā)布。但終究讓人看的煩心。可以找到 tomcat 服務(wù)器端的 web.xml 文件,用其頭信息替換下。

  • fail.html 頁(yè)面簡(jiǎn)單地加入一條 “失敗” 提示語(yǔ)就可以了。

看一下最后的項(xiàng)目結(jié)構(gòu)吧:

圖片描述

  1. 最后的測(cè)試。
  • 啟動(dòng)瀏覽器,在地址欄中輸入 http://localhost:8888/sm-demo/login.html 。打開登錄頁(yè)面;

  • 在登錄頁(yè)面中輸入用戶名和密碼,點(diǎn)擊登錄按鈕。

Tips: 登錄的邏輯驗(yàn)證使用了硬代碼,用戶名:mk,密碼:123。

登錄成功后,會(huì)轉(zhuǎn)到首頁(yè),且在首頁(yè)中顯示出登錄者的信息。

圖片描述

2.2 使用 Spring MVC 模型組件

直接使用 HttpServletRequest 封裝請(qǐng)求作用域級(jí)別的數(shù)據(jù),不能說(shuō)不好。但是,Spring MVC 存在的目的,就是為了簡(jiǎn)化開發(fā)者的工作,動(dòng)不動(dòng)就要 Spring 把底層的原生 API 弄出來(lái),Spring MVC 存在的意義就不大了。

HttpServletRequest 的功能是全方面的,存儲(chǔ)數(shù)據(jù)可以說(shuō)是它的副業(yè),為了一個(gè)數(shù)據(jù)存儲(chǔ),把它搬出來(lái),好像有點(diǎn)大材小用。

其實(shí),你可以告訴 Spring MVC ,我只要 HttpServletRequest 的存儲(chǔ)功能。也就是說(shuō),只要 Spring MVC 引用出 HttpServletRequest 內(nèi)置的 map 對(duì)象就可以了。

圖片描述

好了!現(xiàn)在重構(gòu)一下上面的實(shí)例,僅僅修改控制器 login()方法的代碼。

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

還是 2 個(gè)參數(shù),user 參數(shù)就不啰嗦了。

map 參數(shù)則是一個(gè)神奇的存在。在方法中一站,等于通知 Spring MVC ,幫我把某個(gè)作用域中的 map 對(duì)象引用出來(lái)。

如前言中所述,作用域有 3 個(gè)級(jí)別,Spring MVC 怎么知道你要哪一個(gè)層面的作用域。既然沒有明說(shuō),Spring MVC 引用出來(lái)的是請(qǐng)求作用域也就是 HttpServletRequest 的內(nèi)置 map 對(duì)象。

好了,你可以放心的和前面一樣測(cè)試代碼,在 index.html 頁(yè)面中你將看到登錄者的信息。

搞了半天了,其實(shí)本質(zhì)上是一樣:一個(gè)直接把 HttpServletRequest 交給你用,一個(gè)僅僅只是把實(shí)現(xiàn)了存儲(chǔ)的那一部分功能交給你。

有句話叫做透過(guò)現(xiàn)象看本質(zhì),Spring MVC 只是對(duì)原生 Servlet 開發(fā)做了高級(jí)封裝。如同端午節(jié)吃棕子,禮品盒再怎么高級(jí)、漂亮,打開后還是棕子。

3. 小結(jié)

本節(jié)課和大家一起學(xué)習(xí)了 Spring MVC 中的數(shù)據(jù)模型。所謂數(shù)據(jù)模型,就是用來(lái)裝數(shù)據(jù)的組件,當(dāng)然,因 WEB 應(yīng)用程序的特殊性,更多是要討論存放在這個(gè)組件中的數(shù)據(jù)在一個(gè)什么樣的范圍之內(nèi)能夠被使用。

本節(jié)課學(xué)習(xí)到了,可以直接使用原生的 HttpServletRequest 完成請(qǐng)求作用域數(shù)據(jù)的存儲(chǔ),觸類旁通,當(dāng)然,你也可以直接使用原生 HttpSession 對(duì)象,保存會(huì)話作用域級(jí)別數(shù)據(jù)的保存。

有時(shí),不需要為了吃一個(gè)桃子,砍掉一棵樹。開發(fā)者可以使用 Spring MVC 引用出內(nèi)部的存儲(chǔ)對(duì)象,這樣更小巧實(shí)用。是的,本節(jié)課程中出現(xiàn)的 map 是 Spring MVC 中的數(shù)據(jù)模型組件。