request、session、application學(xué)習08-11-16 23:03 發(fā)表于:《
生活點(diǎn)滴》 分類(lèi):未分類(lèi)
好像最近發(fā)現自己挺多最基本的知識都沒(méi)有掌握牢固,哎。。。。
幾乎所有的Web開(kāi)發(fā)語(yǔ)言都支持Session功能,Servlet也不例外。 Servlet/JSP中的Session功能是通過(guò)作用域(scope)這個(gè)概念來(lái)實(shí)現的。
作用域分為四種,分別為:
page 在當前頁(yè)面有效(僅用于JSP中)
request 在當前請求中有效
session 在當前會(huì )話(huà)中有效
application 在所有應用程序中有效
是不是看不太明白?page因為僅用于JSP中,這里只講述其他三種作用域。 首先要聲明的一點(diǎn),所謂“作用域”就是“信息共享的范圍”,也就是說(shuō)一個(gè)信息能夠在多大的范圍內有效。
話(huà)說(shuō)武松一日來(lái)到景陽(yáng)崗,見(jiàn)一旗幟迎風(fēng)飄揚,旗子上書(shū)五個(gè)大字“三碗不過(guò)崗”。 武松叫道:“店家,拿三碗酒來(lái),再切兩斤熟牛肉!”店小二應聲道:“三碗好酒,二斤熟牛肉啰~~”里面廚師趕忙當當當當切好牛肉,店小二倒上三碗酒,店小二端上前來(lái)。
武松咕咚咕咚連干三碗,叫一聲“好酒!店家,再來(lái)三碗!”小二忙又倒上三碗好酒, 武松一飲而盡。就這樣前前后后武松一共喝了十八大腕。付了帳剛要走,店小二道: “客官,這前面山上有大蟲(chóng),客官剛剛喝完十八碗酒恐怕過(guò)不得崗,不如在小店暫住一夜, 待明天和獵戶(hù)一同過(guò)崗豈不是好?”
之后武松說(shuō)什么就留待各位看官自己去回憶啦。在這段武松打虎中, 大家有沒(méi)有看到些熟悉的東西?
武松: 瀏覽器。
酒館: 服務(wù)器。
店小二、廚師: Servlet或者JSP。
來(lái)三碗好酒!: 瀏覽器向服務(wù)器發(fā)出HTTP請求。
店小二上酒: 服務(wù)器的響應。
武松從進(jìn)店到離開(kāi): 一個(gè)HTTP對話(huà)。
我們可以看到,Web交互的最基本單位為HTTP請求(武松點(diǎn)菜)。 每個(gè)用戶(hù)從進(jìn)入網(wǎng)站到離開(kāi)網(wǎng)站這段過(guò)程稱(chēng)為一個(gè)HTTP會(huì )話(huà) (武松進(jìn)店到出店),一個(gè)服務(wù)器的運行過(guò)程中會(huì )有多個(gè)用戶(hù)訪(fǎng)問(wèn), 就是多個(gè)HTTP會(huì )話(huà)(酒館當然不可能只接待武松一個(gè)客人)。那么作用域就可以理解為:
request HTTP請求開(kāi)始到結束這段時(shí)間
session HTTP會(huì )話(huà)開(kāi)始到結束這段時(shí)間
application 服務(wù)器啟動(dòng)到停止這段時(shí)間
request
一個(gè)HTTP請求的處理可能需要多個(gè)Servlet合作(武松點(diǎn)菜時(shí)店小二就要吩咐廚房做菜), 幾個(gè)Servlet之間可以通過(guò)某種方式傳遞信息(店小二就用吆喝的方式通知廚房),但這個(gè)信息在請求結束后就無(wú)效了(廚房在做完菜之后就不用再管這道菜的事兒了)。
Servlet之間的信息共享是通過(guò)HttpServletRequest接口的兩個(gè)方法來(lái)實(shí)現的:
void setAttribute(String name, Object value) 將對象 value 以 name 為名稱(chēng)保存到request作用域中。
Object getAttribute(String name) 從request作用域中取得指定名字的信息。
doGet()、doPost()函數的第一個(gè)參數就是 HttpServletRequest 對象, 使用這個(gè)對象的 setAttribute 即可傳遞信息。
那么設置好信息之后,如何將信息傳給其他Servlet? 這就要用到 RequestDispatcher 接口的 forward 方法,將請求轉發(fā)給其他Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path) 取得Dispatcher以便轉發(fā)。path為轉發(fā)的目的Servlet。
void RequestDispatcher.forward(ServletRequest request, ServletResponse response) 將request和response轉發(fā)。
因此,只要在當前Servlet中先 setAttribute,然后forward,最后在forward到的Servlet中 getAttribute即可實(shí)現信息傳遞。
PHP的程序員可能不太好理解這一段,因為PHP中沒(méi)有轉發(fā)的概念, 一個(gè)請求只能由一個(gè)PHP文件來(lái)處理,所以PHP中根本沒(méi)有request作用域的概念。而Servlet則不同,請求可以在應用程序中任意轉發(fā),所以用request作用域在不同Servlet之間傳遞信息。 需要注意兩點(diǎn):
轉發(fā)不是重定向,轉發(fā)是在Web應用內部進(jìn)行的。PHP支持重定向但沒(méi)有轉發(fā)。
轉發(fā)對瀏覽器是透明的,也就是說(shuō),無(wú)論在服務(wù)器上如何轉發(fā),瀏覽器地址欄中顯示的仍然是最初那個(gè)Servlet的地址。
session
session作用域比較容易理解,同一瀏覽器訪(fǎng)問(wèn)多次,在這多次訪(fǎng)問(wèn)之間傳遞信息,就是session作用域。 ('''武松每次點(diǎn)菜帳房先生都要記一筆賬,等武松走之前結帳用。這筆帳在武松吃飯過(guò)程中始終有效,即位于session作用域中''')
session是通過(guò)HttpSession接口實(shí)現的。
Object HttpSession.getAttribute(String name) 從session中獲取信息
void HttpSession.setAttribute(String name, Object value) 向session中保存信息
而通過(guò)HttpServletRequest.getSession()方法可以獲得HttpSession對象。
HttpSession HttpServletRequest.getSessio() 獲取當前請求所在的session的對象。
session的開(kāi)始容易判斷(瀏覽器發(fā)出第一個(gè)HTTP請求即可認為會(huì )話(huà)開(kāi)始), 但結束就不好判斷了(因為瀏覽器關(guān)閉時(shí)不會(huì )通知服務(wù)器“我關(guān)了,會(huì )話(huà)可以結束了”),所以只能通過(guò)這種方法判斷:如果一定的時(shí)間內客戶(hù)端沒(méi)有反應,則認為會(huì )話(huà)結束。 Tomcat的默認值為120分鐘,但這個(gè)值也可以通過(guò) HttpSession 的 setMaxInactiveInterval 方法來(lái)設置。
void setMaxInactiveInterval(int interval) 設置繪畫(huà)的超時(shí)值。
如果想主動(dòng)讓會(huì )話(huà)結束,如用戶(hù)單擊“注銷(xiāo)”的時(shí)候,可以使用 HttpSession 的 invalidate 方法:
vooid invalidate() 強制結束當前session。
application
application作用域就是服務(wù)器啟動(dòng)到關(guān)閉的整段時(shí)間, 在這個(gè)作用域內設置的信息可以被所有應用程序使用。 (餐館打烊后結帳,用到的即是開(kāi)張到打烊之間的所有信息。)
還記得上一節提到的ServetContext嗎? application作用域上的信息傳遞就是通過(guò)ServetContext實(shí)現的。
Object getAttribute(String name) 從application中獲取信息。
void setAttribute(String name, Object value) 向application作用域中設置信息。
總結
可以看到,每個(gè)作用域除了實(shí)現接口不同、意義不同之外,它們的使用方法和作用都是相同的, 都是通過(guò) getAttribute 和 setAttribute 方法進(jìn)行信息傳遞。
作用域 意義 實(shí)現接口
request HTTP請求內 HttpServletRequest
session HTTP會(huì )話(huà)內 HttpSession
application 服務(wù)器生命周期內 ServletContext