標籤:
javaweb學習總結(十八)——JSP屬性範圍
所謂的屬性範圍就是一個屬性設定之後,可以經過多少個其他頁面後仍然可以訪問的儲存範圍。
一、JSP屬性範圍
JSP中提供了四種屬性範圍,四種屬性範圍分別指以下四種:
- 當前頁:一個屬性只能在一個頁面中取得,跳轉到其他頁面無法取得
- 一次伺服器請求:一個頁面中設定的屬性,只要經過了伺服器跳轉,則跳轉之後的頁面可以繼續取得。
- 一次會話:一個使用者佈建的內容,只要是與此使用者相關的頁面都可以訪問(一個會話表示一個人,這個人設定的東西只要這個人不走,就依然有效)
- 上下文中:在整個伺服器上設定的屬性,所有人都可以訪問
二、屬性的操作方法
既然JSP中提供了四種屬性範圍,則四種屬性範圍中都將包含以下的屬性操作方法。
No. |
方法 |
描述 |
1 |
public void setAttribute(String name,Object value) |
設定屬性 |
2 |
public object getAttribute(String name) |
取得屬性 |
3 |
public void removeAttribute(String name) |
刪除屬性 |
屬性的操作無外乎就是增加、取得和刪除這個幾個操作。
單詞Attribute的意思是“屬性”,setAttribute(String name,Object value)從單詞的組合來看就可以知道是這個方法的是設定屬性,設定屬性的名字和屬性的值,名字(name)為String類型,值(value)為Object類型,由於值為Object類型,這表示可以設定任意類型的資料作為值,因為所有的類都是從Object類型繼承而來。因此設定屬性值的時候可以是任意類型的資料。getAttribute(String name)方法是根據屬性的名字取得屬性,removeAttribute(String name)方法是根據屬性的名字刪除屬性。
三、JSP四種屬性範圍的具體介紹3.1、page屬性範圍(pageContext)
page屬性範圍相對好理解一些:在一個版面設定的屬性,跳轉到其他頁面就無法訪問了。但是在使用page屬性範圍的時候必須注意的是,雖然習慣上將頁面範圍的屬性稱為page範圍,但是實際上操作的時候是使用pageContext內建對象完成的。
pageContext屬性範圍操作流程圖
pageContext從字面上的定義,可以發現,是表示一個頁面(page)的上下文(Context),可以表示一個頁面中的所有內容。
從操作流程圖來看,在第一個版面設定的屬性經過伺服器端跳轉到第二個頁面以後,在第二個頁面是無法取得在第一個頁面中設定的屬性的,就好比現在坐著的桌子上有一支筆,但一旦離開了這張桌子,坐到別的桌子上時,筆就沒有了。
下面通過代碼來觀察此範圍的屬性
範例:pageContextDemo01.jsp
在頁面中設定兩個屬性
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <% 4 //此時設定的屬性只能夠在本頁中取得 5 pageContext.setAttribute("name","孤傲蒼狼"); //設定屬性 6 pageContext.setAttribute("date",new Date()); //設定屬性 7 //注意:這裡設定的兩個屬性的名字分別為name和date,這兩個是字串類型的資料,但對應的屬性值MLDN和new Date這個兩個值卻不是字串類型,而是兩個Object類型的資料。 8 %> 9 <%10 //取得設定的屬性11 String refName = (String)pageContext.getAttribute("name"); 12 //由於取得的值為Object類型,因此必須使用String強制向下轉型,轉換成String類型13 Date refDate = (Date)pageContext.getAttribute("date");14 %>15 <h1>姓名:<%=refName%></h1>16 <h1>日期:<%=refDate%></h1>
程式運行結果如下:
這說明了在本頁設定的pageContext範圍屬性在本頁確實可以取得,下面使用跳躍陳述式,觀察跳轉之後是否還可以取得屬性。
範例:pageScopeDemo02.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 pageContext.setAttribute("name","孤傲蒼狼"); 5 pageContext.setAttribute("date",new Date()); 6 %>7 <%--使用jsp:forward標籤進行伺服器端跳轉--%>8 <jsp:forward page="/pageScopeDemo03.jsp" />
範例:pageScopeDemo03.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 String refName = (String)pageContext.getAttribute("name"); 5 Date refDate = (Date)pageContext.getAttribute("date");6 %>7 <h1>姓名:<%=refName%></h1>8 <h1>日期:<%=refDate%></h1>
在以上程式中的pageScopeDemo02.jsp只是設定了兩個屬性,跳轉到pageScopeDemo03.jsp之後再在pageScopeDemo03.jsp中取在pageScopeDemo02.jsp設定的page屬性。此時,運行結果如下:
使用了伺服器端跳轉,但是發現內容並不能取得,證明page範圍的屬性只能在本頁中取得,跳轉到其他頁面之中不能取得。如果現在希望跳轉到其他頁面之中,依然可以取得,則可以擴大屬性範圍,使用request屬性範圍即可。
3.2、request屬性範圍
request屬性範圍表示在一次伺服器跳轉中有效,只要是伺服器跳轉,則設定的request屬性可以一直傳遞下去。
範例:requestScopeDemo01.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 request.setAttribute("name","孤傲蒼狼"); 5 request.setAttribute("date",new Date()); 6 %>7 <%--使用jsp:forward標籤進行伺服器端跳轉--%>8 <jsp:forward page="/requestScopeDemo02.jsp" />
範例:requestScopeDemo02.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 //取得requestScopdemo01.jsp設定的屬性5 String refName = (String)request.getAttribute("name"); 6 Date refDate = (Date)request.getAttribute("date");7 %>8 <h1>姓名:<%=refName%></h1>9 <h1>日期:<%=refDate%></h1>
運行結果如下:
從運行結果來看,程式跳轉了,但是與page範圍相比,內容可以向下繼續傳遞,即在第一個版面設定的屬性跳轉到第二個頁面後在第二個頁面中依然可以取得第一個版面設定的屬性。
如果現在有第三個頁面了,則也可以繼續向後傳遞
範例:修改requestScopeDemo02.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%--使用jsp:forward標籤進行伺服器端跳轉--%>4 <jsp:forward page="/requestScopeDemo03.jsp" />
範例:requestScopeDemo03.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 //取得requestScopdemo01.jsp設定的屬性5 String refName = (String)request.getAttribute("name"); 6 Date refDate = (Date)request.getAttribute("date");7 %>8 <h1>姓名:<%=refName%></h1>9 <h1>日期:<%=refDate%></h1>
以上的結果依然可以訪問,但是如果,此時使用了超連結的方式傳遞的話,則屬性是無法向下繼續傳遞的。
範例:修改requestScopeDemo03.jsp
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <% 4 //取得requestScopdemo01.jsp設定的屬性 5 String refName = (String)request.getAttribute("name"); 6 Date refDate = (Date)request.getAttribute("date"); 7 %> 8 <h1>姓名:<%=refName%></h1> 9 <h1>日期:<%=refDate%></h1>10 <h1>11 <%--使用超連結的形式跳轉,這是用戶端跳轉,URL地址會改變--%>12 <a href="${pageContext.request.contextPath}/requestScopeDemo04.jsp">跳轉到requestScopeDemo04.jsp</a>13 </h1>
此時使用了超連結跳轉,一旦跳轉之後,地址欄改變,所以此種跳轉也可以稱為用戶端跳轉。
requestScopeDemo04.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 //取得requestScopdemo01.jsp設定的屬性5 String refName = (String)request.getAttribute("name"); 6 Date refDate = (Date)request.getAttribute("date");7 %>8 <h1>姓名:<%=refName%></h1>9 <h1>日期:<%=refDate%></h1>
運行結果:
requestScopeDemo04.jsp頁面顯示的結果是null。這說明了在requestScopeDemo01.jsp這個版面設定的屬性經過超連結這種用戶端跳轉到別的頁面時別的頁面是無法取得requestScopeDemo01.jsp中設定的屬性的。
如果還想進一步擴大屬性範圍,則可以使用session範圍屬性
3.3、session屬性範圍
session設定的屬性不管如何跳轉,都可以取得的。當然,session只針對一個使用者
在第一個頁面上設定的屬性,跳轉(伺服器跳轉/用戶端跳轉)到其他頁面之後,其他的頁面依然可以取得第一個頁面上設定的屬性。
下面通過代碼來觀察session屬性範圍
範例:sessionScopeDemo01.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 //此時設定的屬性只能夠在與本頁相關的任何頁面中取得5 session.setAttribute("name","孤傲蒼狼"); //設定屬性6 session.setAttribute("date",new Date());7 %>8 <%--使用伺服器端跳轉--%>9 <jsp:forward page="/sessionScopeDemo02.jsp"/>
這裡使用的是伺服器端跳轉
sessionScopeDemo02.jsp
1 <%@page contentType="text/html;charset=UTF-8"%> 2 <%@page import="java.util.*"%> 3 <% 4 String refName = (String)session.getAttribute("name"); 5 Date refDate = (Date)session.getAttribute("date"); 6 %> 7 <h1>姓名:<%=refName%></h1> 8 <h1>日期:<%=refDate%></h1> 9 <%--使用超連結這種用戶端跳轉--%>10 <h1><a href="${pageContext.request.contextPath}/sessionScopeDemo03.jsp">sessionScopeDemo03</a></h1>
這裡使用的是超連結這種用戶端跳轉
運行程式sessionScopeDemo01.jsp結果如下所示:
sessionScopeDemo03.jsp
1 <%@page contentType="text/html;charset=UTF-8"%>2 <%@page import="java.util.*"%>3 <%4 String refName = (String)session.getAttribute("name");5 Date refDate = (Date)session.getAttribute("date");6 %>7 <h1>姓名:<%=refName%></h1>8 <h1>日期:<%=refDate%></h1>
點擊超連結sessionScopeDemo03,跳轉到了sessionScopeDemo03.jsp這個頁面,此時程式的運行結果如下:
這說明了即使是採用用戶端跳轉,在別的頁面依然可以取得第一個頁面中設定的session屬性。但是,如果,此時新開了一個瀏覽器,則sessionScopeDemo03.jsp肯定無法取得sessionScopeDemo01.jsp中設定的session對象的屬性,因為session只是保留了一個人的資訊。
如果一個屬性想讓所有的使用者都可以訪問,則可以使用最後一種屬性範圍:application範圍。
3.4、application屬性範圍
因為application屬性範圍是在伺服器上設定的一個屬性,所以一旦設定之後任何使用者都可以瀏覽到此屬性。
下面通過代碼來觀察application屬性範圍
範例:applicationScopeDemo01.jsp
1 <%@ page contentType="text/html;charset=GBK"%>2 <%@ page import="java.util.*"%>3 <%4 //此時設定的屬性任何使用者都可以取得5 application.setAttribute("name","孤傲蒼狼"); //設定屬性6 application.setAttribute("date",new Date());7 %>8 <h1><a href="${pageContext.request.contextPath}/applicationScopeDemo02.jsp">applicationScopeDemo02</a></h1>
範例:applicationScopeDemo02.jsp
1 <%@ page contentType="text/html;charset=GBK"%>2 <%@ page import="java.util.*"%>3 <%4 String refName = (String)application.getAttribute("name");5 Date refDate = (Date)application.getAttribute("date");6 %>7 <h1>姓名:<%=refName%></h1>8 <h1>日期:<%=refDate%></h1>
觀察頁面的運行效果:
開啟多個瀏覽器視窗,運行applicationScopeDemo02.jsp時,都可以顯示出所示的結果,因為屬性範圍設定在了伺服器中,所以只要是串連到此伺服器的任意使用者都可以取得此屬性,當然,如果伺服器關閉的話,則此屬性肯定消失。
如把Tomcat伺服器先關閉後再重新啟動,開啟瀏覽器視窗運行applicationScopeDemo02.jsp時,得到的結果如所示:
注意:如果在伺服器上設定了過多的application屬性,則會影響到伺服器的效能。
3.5、關於pageContext屬性範圍的進一步補充
之前所講解的四種屬性範圍,實際上都是通過pageContext屬性範圍設定上的。開啟pageContext所在的說明文檔。
PageContext類繼承了JspContext類,在JspContext類中定義了setAttribute方法,如下:
public abstract void setAttribute(String name,Object value,int scope)
此方法中存在一個scope的整型變數,此變數就表示一個屬性的儲存範圍。
PageContext類繼承了JspContext類,所以在PageContext類中實現了抽象的setAttribute方法:
1 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屬性範圍。
下面通過代碼來觀察此四種屬性範圍常量的作用,以:request為例
範例:pageScopeDemo04.jsp
1 <%@page contentType="text/html;charset=GBK"%>2 <%@page import="java.util.*"%>3 <%4 pageContext.setAttribute("name","孤傲蒼狼",PageContext.REQUEST_SCOPE); //設定屬性,並指明屬性範圍5 pageContext.setAttribute("date",new Date(),PageContext.REQUEST_SCOPE); //設定屬性,並指明屬性範圍6 %>7 <jsp:forward page="/pageScopeDemo05.jsp"/>
pageScopeDemo05.jsp
1 <%@page contentType="text/html;charset=GBK"%> 2 <%@page import="java.util.*"%> 3 <% 4 //使用request對象擷取屬性 5 String refName = (String)request.getAttribute("name"); 6 Date refDate = (Date)request.getAttribute("date"); 7 //也可以使用pageContext對象擷取屬性,只要在擷取時指明對象的屬性範圍即可 8 String refName2 = (String)pageContext.getAttribute("name", PageContext.REQUEST_SCOPE); 9 Date refDate2 = (Date)pageContext.getAttribute("date", PageContext.REQUEST_SCOPE);10 %>11 使用request對象擷取屬性:12 <h1>姓名:<%=refName%></h1>13 <h1>日期:<%=refDate%></h1>14 使用pageContext對象擷取屬性:15 <h1>姓名:<%=refName2%></h1>16 <h1>日期:<%=refDate2%></h1>
運行結果:
從運行結果可以看到:在pageScopeDemo04.jsp使用的是pageContext對象調用setAttribute()方法設定的屬性範圍是request的屬性範圍,因此在調用此方法時,把一個int類型的scope範圍常量REQUEST_SCOPE傳遞了進來,這個REQUEST_SCOPE屬性範圍常量的作用就是告訴pageContext對象現在要設定的屬性範圍是request的屬性範圍,所以pageScopeDemo05.jsp這個頁面中可以直接使用request.getAttribute();方法擷取在pageScopeDemo04.jsp設定的屬性。
四、jsp四種屬性範圍的使用場合
1、request:如果客戶向伺服器發請求,產生的資料,使用者看完就沒用了,像這樣的資料就存在request域,像新聞資料,屬於使用者看完就沒用的。
2、session:如果客戶向伺服器發請求,產生的資料,使用者用完了等一會兒還有用,像這樣的資料就存在session域中,像購物資料,使用者需要看到自己購物資訊,並且等一會兒,還要用這個購物資料結帳。
3、application(servletContext):如果客戶向伺服器發請求,產生的資料,使用者用完了,還要給其它使用者用,像這樣的資料就存在application(servletContext)域中,像聊天資料。
javaweb學習總結(十八)——JSP屬性範圍