JSP中四大做用域詳解

四大做用域

  爲了在頁面、請求、和用戶之間傳遞和共享數據,JSP提供了四個不一樣的做用域:page(頁面做用域)、request(請求做用域)、session(會話做用域)、application(應用程序做用域),這些做用域就規定了數據能夠傳遞和共享的範圍以及數據的存活時間。瀏覽器

page(頁面做用域)

  JSP默認的做用域是page,這個做用域中的對象只能在該頁面中使用,不容許在其餘頁面使用。咱們能夠經過調用pageContext這個隱含的對象的getAttribute()和setAttribute()方法去獲取和設置須要傳遞、共享具備這種範圍類型的數據。(pageContext對象還提供了訪問其餘範圍對象的getAttribute方法)。page範圍內的對象,在客戶端每次請求JSP頁面時建立,在頁面向客戶端發送迴響應或請求被轉發(forward)到其餘的資源後被刪除。JSP最終會被編譯成Servlet文件。在Servlet容器中,每一個Servlet都只存在一個實例。可是對於page做用域的屬性來講,在當前頁面設置的屬性只在本次訪問該頁面有效,當你再次訪問該頁面時,又會從新初始化頁面的屬性。tomcat

1 <%
2 out.print(pageContext.getAttribute("SiteName")); // 輸出null
3 pageContext.setAttribute("SiteName", "博客園");
4 %>

  當我在瀏覽器訪問該頁面時會輸出null;當我再從新打開一個該頁面時,還會輸出null,並不會輸出」博客園」。也就是說,page做用域範圍的不會存在線程安全的問題,每一次訪問同一個頁面,設置的page做用域的屬性都是不同的。安全

request(請求做用域)

  request在一次請求的全過程當中有效,即從http請求到服務器處理結束,返回響應的整個過程,存放在HttpServletRequest對象中。一次請求的生命週期從客戶端發起到服務器接收並響應該請求,或者將該請求forward到另外一個頁面或者Servlet進行處理而結束。在此期間,本次請求的參數,屬性都是有效的;一旦客戶端刷新瀏覽器,從新發起請求,則以前的請求參數和屬性都將失效。須要注意的是,當咱們使用<jsp:forward .../>動做將當前請求轉向另外一個頁面或者Servlet的時候,該請求的參數和屬性也一併轉過去,並不會由於<jsp:forward .../>動做而丟失request的參數和屬性。

session(會話做用域)

  當咱們向服務器發送第一個請求開始,只要頁面不關閉,或者會話未過時(默認30分鐘),或者未調用HttpSession的invalidate()方法,接下來的操做都屬於同一次會話的範疇。在JSP中,每當向服務器發送一個請求,服務器響應這個請求的時候,會在客戶端的Cookie中寫一個session id值。每次發送請求的時候,會將該session id值一塊兒發送到服務器端,服務器端根據該session id值來判斷每次請求是否屬於同一個session的範疇以內。其存放在HttpSession對象中。

application(應用程序做用域)

  application的做用域是最廣的,它表明着整個Web應用的全局變量,對每個頁面,每個Servlet都是有效的。當咱們在application中設置屬性時,這個屬性在任意的一個頁面都是能夠訪問的。在application做用域中設置的屬性若是不手動調用removeAttribute函數進行刪除的話,它們就一直可使用,若是Web容器發生重啓,此時application範圍內的全部屬性都將丟失。服務器

注意:根據jsp規範,用於某個對象的名稱必須在全部做用域中都是惟一的。也就是說,若是application做用域中有一個名爲user的對象,並且在request做用域中用相同的名稱保存着另外一個對象,那麼容器可能會移除第一個對象,儘管不多有容器會執行這項規則,可是爲了使您的項目更加完善,仍是應該確保在任何地方都是用惟一的名稱,除非所保存的對象爲同一個。session

如何使用

  • page裏的變量無法從index.jsp傳遞到test.jsp。只要頁面跳轉了,它們就不見了。  
  • request裏的變量能夠跨越forward先後的兩頁。可是隻要刷新頁面,它們就從新計算了。  
  • session的變量一直在累加,開始還看不出區別,只要關閉瀏覽器,再次重啓瀏覽器訪問這頁,session裏的變量就從新計算了。  
  • application裏的變量一直在累加,除非你重啓tomcat,不然它會一直變大。  
  • 若是把變量放到pageContext裏,就說明它的做用域是page,它的有效範圍只在當前jsp頁面裏。 從把變量放到pageContext開始,到jsp頁面結束,你均可以使用這個變量。  
  • 若是把變量放到request裏,就說明它的做用域是request,它的有效範圍是當前請求週期。 所謂請求週期,就是指從http請求發起,到服務器處理結束,返回響應的整個過程。在這個過程當中可能使用forward的方式跳轉了多個jsp頁面,在這些頁面裏你均可以使用這個變量。 
  • 若是把變量放到session裏,就說明它的做用域是session,它的有效範圍是當前會話。 所謂當前會話,就是指從用戶打開瀏覽器開始,到用戶關閉瀏覽器這中間的過程。這個過程可能包含多個請求響應。也就是說,只要用戶不關瀏覽器,服務器就有辦法知道這些請求是一我的發起的,整個過程被稱爲一個會話(session),而放到會話中的變量,就能夠在當前會話的全部請求裏使用。 
  • 若是把變量放到application裏,就說明它的做用域是application,它的有效範圍是整個應用。 整個應用是指從應用啓動,到應用結束。沒有說「從服務器啓動,到服務器關閉」,是由於一個服務器可能部署多個應用,固然你關閉了服務器,就會把上面全部的應用都關閉了。 application做用域裏的變量,它們的存活時間是最長的,若是不進行手工刪除,它們就一直可使用。與上述三個不一樣的是,application裏的變量能夠被全部用戶共用。若是用戶甲的操做修改了application中的變量,用戶乙訪問時獲得的是修改後的值。這在其餘scope中都是不會發生的,page, request, session都是徹底隔離的,不管如何修改都不會影響其餘人的數據。

舉例說明

  假如一個網站WebSite,其包含7個jsp頁面,分別爲master.jsp、top.jsp、main.jsp、foot.jsp、login.jsp、success.jsp和news.jsp。master.jsp頁面經過<include>指令包含top.jsp、main.jsp、foot.jsp三個頁面,當用戶經過login.jsp登陸成功後,進入success.jsp頁面而後經過此頁面的<forward>標籤跳轉到master.jsp頁面中。
咱們在success.jsp頁面中加入以下代碼(用到jstl標籤) 
1 <span style="font-family:'微軟雅黑', 'Microsoft YaHei';">
2 <c:set value="aaa" var="test1" scope="page" />  
3 <c:set value="aaa" var="test2" scope="request" />  
4 <c:set value="aaa" var="test3" scope="session" />  
5 <c:set value="aaa" var="test4" scope="application"/>  
6 <jsp:forward page="master.jsp"/ >這裏跳轉  
7 </span>
  1. 變量 test1 只在success.jsp內有效;
  2. 變量 test2 在success.jsp、master.jsp、top.jsp、main.jsp、foot.jsp中有效;
  3. 變量 test3 在7個頁面中都有效(包括login.jsp和news.jsp);
  4. 變量 test4 在整個網站,當前也就是7個頁面中都有效(包括login.jsp和news.jsp)。
  Test3和test4有效範圍同樣,有什麼區別呢?說明一點,假如此時又有另外一個用戶訪問master.jsp頁面,那麼test3相對於這個用戶來講就無效,而test4倒是有效的。或者當第一個登陸的用戶關閉瀏覽器後,再從新訪問master.jsp時,test3就無效,而test4卻有效。
相關文章
相關標籤/搜索