pageContext:數據只在當前自身的頁面有效;
request:數據在一次請求中有效;
session:數據在一次會話中有效;若是新開瀏覽器,則無效;
application:數據在當前Wed項目有效,可供所有用戶共享。
下面結合具體例子來說明:
【Index.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<% pageContext.setAttribute("p","pagestr");
request.setAttribute("r","requeststr");
session.setAttribute("s","sessionstr");
application.setAttribute("a","applicationstr");%>
<%out.print(pageContext.getAttribute("p")+"<br/>");
out.print(request.getAttribute("r")+"<br/>");
out.print(session.getAttribute("s")+"<br/>");
out.print(application.getAttribute("a"));%>
【結果】
(1)pageContext作用域
因爲pageContext對象中的屬性的作用域是“在當前自身的頁面內有效”,而以上均在同一個頁面中增加或輸出,所以能夠正常顯示。但將上面的頁面做修改,將屬性添加放在one.jsp中執行,再通過請求轉發跳轉到two.jsp頁面,並在6_2.jsp中顯示屬性的值。
【Index.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<% request.setAttribute("p","pagestr"); request.getRequestDispatcher("6_2.jsp").forward(request, response); %>
【6_2.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%=request.getAttribute("p") %>
【結果】
因爲從index.jsp到6_2.jsp的跳轉是“請求轉發”,即仍然是同一次請求,而request的作用域範圍就是“在一次請求中有效”。
但要注意,如果將上例的“請求轉發”改爲"重定向"或超鏈接形式的跳轉,則不會再獲取到數據,如下:
【Index.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<% request.setAttribute("p","pagestr");
%><a href="6_2.jsp">點我跳轉</a>
【6_2.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%=request.getAttribute("p") %>
【結果】
【點擊跳轉之後】
因爲request的作用範圍是“一次請求中有效”,而“重定向”或超鏈接形式的跳轉,都是在跳轉時重新發送了一次新的請求(重新去請求6_2.jsp),因此是獲取不到數據的。
(3)session作用域
如果希望在增加屬性之後,能夠在跳轉後的任何頁面(無論是請求轉發、重定向或超鏈接跳轉),甚至是項目中任何一個頁面都能獲取到該屬性值,就可以使用session的作用域來實現:
【Index.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<% session.setAttribute("p","pagestr");
response.sendRedirect("6_2.jsp");
%>
【6_2.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%=session.getAttribute("p") %>
【結果】
雖然“重定向”或超鏈接形式的跳轉,會重新向服務器發送一次請求(重新去請求6_2.jsp),但仍然可以從session的作用域中獲取到屬性值。當然,如果通過請求轉發實現的跳轉,也能通過session獲取到屬性值。
此外,可重新打開同一個瀏覽器(相同瀏覽器),然後在新標籤裏直接輸入並執行http://localhost:8080/_war_exploded/6_2.jsp
(執行了http://localhost:8080/_war_exploded/index.jsp後),也能獲取到數據。但如果換了一個瀏覽器(不同的瀏覽器),在直接輸入http://localhost:8080/_war_exploded/6_2.jsp 並執行(在另一個瀏覽器執行了http://localhost:8080/_war_exploded/index.jsp後),結果:
也就是說,只要index.jsp中將屬性添加到session後,凡是同一個瀏覽器都可以取到session中的該屬性值;但如果換成其他瀏覽器,則就不能再在session中獲取到該屬性值了。
(4)application作用域
如果想實現這樣一個功能“只要在一個頁面中增加了屬性,那麼即使重新換一個瀏覽器,也要能訪問到該屬性值”,該如何實現?答案就是application的作用域。將上例修改:
【Index.jsp】
【6_2.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%=application.getAttribute("p") %>
【結果】
換一個瀏覽器輸入http://localhost:8080/_war_exploded/6_2.jsp(在另一個瀏覽器執行http://localhost:8080/_war_exploded/index.jsp後)並執行,也能獲取到數據:
只要運行過一次index.jsp後,無論是一個瀏覽器標籤,或者是更換新的瀏覽器,直接再運行6_2.jsp都能獲取到數據。即只要是通過application.setAttribute()設置的屬性,那麼任何瀏覽器的任何頁面都可以獲取到該屬性值,但是如果將tomcat服務器關閉,則application中的屬性值就全部消失了。
可以利用application作用域的這一特性,來實現一個網頁計數器功能,任何的瀏覽器都能訪問,並統計次數:
【Index.jsp】
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%Integer count=(Integer)application.getAttribute("count");
if(count==null){
count=1;
}else{
count=count+1;
}
application.setAttribute("count",count);
out.print("親~~您是第"+application.getAttribute("count")+"個訪問本網頁的用戶^_^");%>
之後,無論是刷新當前頁,還是打開一個瀏覽器標籤,或者打開一個其他瀏覽器再次訪問,每訪問一次,訪問次數就會累加一次。
【特別注意】
雖然四種作用域的大小依次是pageContext<request<session<application,但不能爲了方便就隨隨便便使用範圍大的範圍對象,因爲範圍大造成的性能損耗就越大。因此,如果多個作用域都能完成相同的功能,一般會使用小的那個對象。