JSP四大作用域分別為:page, request ,session, application 。
第一個作用域是page,他只在當前頁面有效,也就是用戶請求的頁面有效,當當前頁面關閉或轉到其他頁面時,page對象將在響應回饋給客戶端后釋放。
第二個作用域是request,他在當前請求中有效,request可以通過setAttribute()方法實現頁面中的信息傳遞,也可以通過forward()方法進行頁面間的跳轉,需要注意的是request是轉發不是重定向,轉發相對於瀏覽器來說是透明的,也就是無論頁面如何跳轉,地址欄上顯示的依舊是最初的地址。
第三個作用域是session,他在當前回話中有效。當一個台電腦上的同一瀏覽器對服務器進行多次訪問時,在這多次訪問之間傳遞的信息就是session作用域的范圍。它從瀏覽器發出第一個HTTP請求即可認為會話開始,但是會話結束的時間是不確定的,因為在瀏覽器關閉時並不會通知服務器,一般Tomcat設置的默認時間為120分鍾,也可以通過setMaxInactiveInterval(int)方法進行設置,或是通過invalidate()方法強制結束當前會話。
第四個作用域是application,他在所有的應用程序中都有效,也就是當服務器開始到服務器結束這段時間,application作用域中存儲的數據都是有效的,同樣可以通過setAttribute賦值和getAttribute取值。
1.page的屬性作用域
page,它只在當前頁面有效,也就是用戶請求的頁面有效。但是在使用page屬性范圍的時候必須注意的是,雖然習慣上將頁面范圍的屬性稱為page范圍,但是實際上操作的時候是使用pageContext內置對象完成的。
通過這里建立一個maven的web項目。
在index.jsp頁面:
<%@page contentType="text/html;charset=UTF-8"%> <%@page import="java.util.*"%> <% //此時設置的屬性只能夠在本頁中取得 pageContext.setAttribute("name","哈哈哈哈"); //設置屬性 pageContext.setAttribute("date",new Date()); //設置屬性 //注意:這里設置的兩個屬性的名字分別為name和date,這兩個是字符串類型的數據,但對應的屬性值MLDN和new Date這個兩個值卻不是字符串類型,而是兩個Object類型的數據。 %> <% //取得設置的屬性 String name = (String)pageContext.getAttribute("name"); //由於取得的值為Object類型,因此必須使用String強制向下轉型,轉換成String類型 Date date = (Date)pageContext.getAttribute("date"); %> <h1>姓名:<%=name%></h1> <h1>日期:<%=date%></h1>
運行結果:
頁設置的pageContext范圍屬性在本頁確實可以取得。
在index.jsp加上一句:
<jsp:forward page="WEB-INF/jsp/pageSecond.jsp" />
pageSecond.jsp頁面如下:
<%@page contentType="text/html;charset=UTF-8"%> <%@page import="java.util.*"%> <% String name = (String)pageContext.getAttribute("name"); Date date = (Date)pageContext.getAttribute("date"); %> <h1>姓名:<%=name%></h1> <h1>日期:<%=date%></h1>
結果:
頁面跳轉之后,獲取不到屬性了。如果現在希望跳轉到其他頁面之中,依然可以取得,則可以擴大屬性范圍,使用request屬性范圍即可。
2.request屬性作用域
request屬性范圍表示在一次服務器跳轉中有效,只要是服務器跳轉,則設置的request屬性可以一直傳遞下去。
index.jsp如下所示:
<%@page contentType="text/html;charset=UTF-8"%> <%@page import="java.util.*"%> <% //此時設置的屬性只能夠在本頁中取得 request.setAttribute("name","哈哈哈哈"); //設置屬性 request.setAttribute("date",new Date()); //設置屬性 //注意:這里設置的兩個屬性的名字分別為name和date,這兩個是字符串類型的數據,但對應的屬性值MLDN和new Date這個兩個值卻不是字符串類型,而是兩個Object類型的數據。 %> <% //取得設置的屬性 String name = (String)request.getAttribute("name"); //由於取得的值為Object類型,因此必須使用String強制向下轉型,轉換成String類型 Date date = (Date)request.getAttribute("date"); %> <h1>姓名:<%=name%></h1> <h1>日期:<%=date%></h1>
結果如圖:
跳轉到pageSecond.jsp之后,依然可以獲得屬性。不管多少個頁面。
但是如果,此時使用了超鏈接的方式傳遞的話,則屬性是無法向下繼續傳遞的。
3.session屬性作用域
session設置的屬性不管如何跳轉,都可以取得的。當然,session只針對一個用戶
不管是采用頁面跳轉,還是超鏈接(相當於客戶端跳轉),在別的頁面依然可以獲取第一個頁面的屬性。但是新打開一個瀏覽器,則無法獲取屬性。
4.application屬性作用域
因為application屬性范圍是在服務器上設置的一個屬性,所以一旦設置之后任何用戶都可以瀏覽到此屬性。
5.pageContext屬性作用域的進一步補充
PageContext類繼承了JspContext類,所以在PageContext類中實現了抽象的setAttribute方法:
public abstract void setAttribute(String name,Object value,int scope)
這個setAttribute()方法如果不寫后面的int類型的scope參數,則此參數默認為PAGE_SCOPE,則此時setAttribute()方法設置的就是page屬性范圍,如果傳遞過來的int類型參數scope為REQUEST_SCOPE,則此時setAttribute()方法設置的就是request屬性范圍,同理,傳遞的scope參數為SESSION_SCOPE和APPLICATION_SCOPE時,則表示setAttribute()方法設置的就是session屬性范圍和application屬性范圍。
比如index.jsp:
<%@page contentType="text/html;charset=UTF-8"%> <%@page import="java.util.*"%> <% //此時設置的屬性只能夠在本頁中取得 pageContext.setAttribute("name","哈哈哈哈",PageContext.REQUEST_SCOPE); //設置屬性 pageContext.setAttribute("date",new Date(),PageContext.REQUEST_SCOPE); //設置屬性 //注意:這里設置的兩個屬性的名字分別為name和date,這兩個是字符串類型的數據,但對應的屬性值MLDN和new Date這個兩個值卻不是字符串類型,而是兩個Object類型的數據。 %> <% //取得設置的屬性 String name = (String)pageContext.getAttribute("name"); //由於取得的值為Object類型,因此必須使用String強制向下轉型,轉換成String類型 Date date = (Date)pageContext.getAttribute("date"); %> <jsp:forward page="WEB-INF/jsp/pageSecond.jsp" />
pageSecond.jsp:
<%@page contentType="text/html;charset=UTF-8"%> <%@page import="java.util.*"%> <% String name = (String)pageContext.getAttribute("name",PageContext.REQUEST_SCOPE); Date date = (Date)pageContext.getAttribute("date",PageContext.REQUEST_SCOPE); %> <h1>姓名:<%=name%></h1> <h1>日期:<%=date%></h1>
跳轉之后依然可以獲取屬性,pageContext相當於request。
參考: 這里