程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> 深入分析JavaWeb Item16 -- jsp 四大域(屬性)范圍

深入分析JavaWeb Item16 -- jsp 四大域(屬性)范圍

編輯:關於JSP

深入分析JavaWeb Item16 -- jsp 四大域(屬性)范圍


jsp裡面有四大域,作用域從小到大分別是page域,request域,session域,application(servletContext)域,域也可以稱為屬性范圍。所謂的屬性范圍就是一個屬性設置之後,可以經過多少個其他頁面後仍然可以訪問的保存范圍。

一、JSP屬性范圍

  JSP中提供了四種屬性范圍,四種屬性范圍分別指以下四種:

page域——當前頁:一個屬性只能在一個頁面中取得,跳轉到其他頁面無法取得 request域——一次服務器請求:一個頁面中設置的屬性,只要經過了服務器跳轉,則跳轉之後的頁面可以繼續取得。 session域——一次會話:一個用戶設置的內容,只要是與此用戶相關的頁面都可以訪問(一個會話表示一個人,這個人設置的東西只要這個人不走,就依然有效) application——上下文中:在整個服務器上設置的屬性,所有人都可以訪問

二、屬性的操作方法

  既然JSP中提供了四種屬性范圍,則四種屬性范圍中都將包含以下的屬性操作方法。

這裡寫圖片描述

  屬性的操作無外乎就是增加、取得和刪除這個幾個操作。

  單詞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

在頁面中設置兩個屬性

<%@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 refName = (String)pageContext.getAttribute("name");  
    //由於取得的值為Object類型,因此必須使用String強制向下轉型,轉換成String類型
    Date refDate = (Date)pageContext.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

程序運行結果如下:

  這裡寫圖片描述

  這說明了在本頁設置的pageContext范圍屬性在本頁確實可以取得,下面使用跳轉語句,觀察跳轉之後是否還可以取得屬性。

范例:pageScopeDemo02.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    pageContext.setAttribute("name","孤傲蒼狼");  
    pageContext.setAttribute("date",new Date()); 
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>

范例:pageScopeDemo03.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    pageContext.setAttribute("name","孤傲蒼狼");  
    pageContext.setAttribute("date",new Date()); 
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>

  在以上程序中的pageScopeDemo02.jsp只是設置了兩個屬性,跳轉到pageScopeDemo03.jsp之後再在pageScopeDemo03.jsp中取在pageScopeDemo02.jsp設置的page屬性。此時,運行結果如下:

  這裡寫圖片描述

  使用了服務器端跳轉,但是發現內容並不能取得,證明page范圍的屬性只能在本頁中取得,跳轉到其他頁面之中不能取得。如果現在希望跳轉到其他頁面之中,依然可以取得,則可以擴大屬性范圍,使用request屬性范圍即可。

3.2、request屬性范圍

  request屬性范圍表示在一次服務器跳轉中有效,只要是服務器跳轉,則設置的request屬性可以一直傳遞下去。

  這裡寫圖片描述

范例:requestScopeDemo01.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    request.setAttribute("name","孤傲蒼狼");  
    request.setAttribute("date",new Date()); 
%>
<%--使用jsp:forward標簽進行服務器端跳轉--%>

范例:requestScopeDemo02.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    //取得requestScopdemo01.jsp設置的屬性
    String refName = (String)request.getAttribute("name");  
    Date refDate = (Date)request.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

運行結果如下:

  這裡寫圖片描述

  從運行結果來看,程序跳轉了,但是與page范圍相比,內容可以向下繼續傳遞,即在第一個頁面設置的屬性跳轉到第二個頁面後在第二個頁面中依然可以取得第一個頁面設置的屬性。

  如果現在有第三個頁面了,則也可以繼續向後傳遞

范例:修改requestScopeDemo02.jsp

 <%@page contentType="text/html;charset=UTF-8"%>
 <%@page import="java.util.*"%>
 <%--使用jsp:forward標簽進行服務器端跳轉--%>
 

范例:requestScopeDemo03.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    //取得requestScopdemo01.jsp設置的屬性
    String refName = (String)request.getAttribute("name");  
    Date refDate = (Date)request.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

  以上的結果依然可以訪問,但是如果,此時使用了超鏈接的方式傳遞的話,則屬性是無法向下繼續傳遞的。

范例:修改requestScopeDemo03.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    //取得requestScopdemo01.jsp設置的屬性
    String refName = (String)request.getAttribute("name");  
    Date refDate = (Date)request.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

<%--使用超鏈接的形式跳轉,這是客戶端跳轉,URL地址會改變--%> 跳轉到requestScopeDemo04.jsp

  此時使用了超鏈接跳轉,一旦跳轉之後,地址欄改變,所以此種跳轉也可以稱為客戶端跳轉。

requestScopeDemo04.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    //取得requestScopdemo01.jsp設置的屬性
    String refName = (String)request.getAttribute("name");  
    Date refDate = (Date)request.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

運行結果:

這裡寫圖片描述

  requestScopeDemo04.jsp頁面顯示的結果是null。這說明了在requestScopeDemo01.jsp這個頁面設置的屬性經過超鏈接這種客戶端跳轉到別的頁面時別的頁面是無法取得requestScopeDemo01.jsp中設置的屬性的。

  如果還想進一步擴大屬性范圍,則可以使用session范圍屬性

3.3、session屬性范圍

  session設置的屬性不管如何跳轉,都可以取得的。當然,session只針對一個用戶

 這裡寫圖片描述

  在第一個頁面上設置的屬性,跳轉(服務器跳轉/客戶端跳轉)到其他頁面之後,其他的頁面依然可以取得第一個頁面上設置的屬性。

下面通過代碼來觀察session屬性范圍

范例:sessionScopeDemo01.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    //此時設置的屬性只能夠在與本頁相關的任何頁面中取得
    session.setAttribute("name","孤傲蒼狼");  //設置屬性
    session.setAttribute("date",new Date());
%>
<%--使用服務器端跳轉--%>

  這裡使用的是服務器端跳轉

sessionScopeDemo02.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    String refName = (String)session.getAttribute("name");
    Date refDate = (Date)session.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

<%--使用超鏈接這種客戶端跳轉--%>

sessionScopeDemo03

  這裡使用的是超鏈接這種客戶端跳轉

  運行程序sessionScopeDemo01.jsp結果如下所示:

  這裡寫圖片描述

sessionScopeDemo03.jsp

<%@page contentType="text/html;charset=UTF-8"%>
<%@page import="java.util.*"%>
<%
    String refName = (String)session.getAttribute("name");
    Date refDate = (Date)session.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

  點擊超鏈接sessionScopeDemo03,跳轉到了sessionScopeDemo03.jsp這個頁面,此時程序的運行結果如下:

  這裡寫圖片描述

  這說明了即使是采用客戶端跳轉,在別的頁面依然可以取得第一個頁面中設置的session屬性。但是,如果,此時新開了一個浏覽器,則sessionScopeDemo03.jsp肯定無法取得sessionScopeDemo01.jsp中設置的session對象的屬性,因為session只是保留了一個人的信息。

  如果一個屬性想讓所有的用戶都可以訪問,則可以使用最後一種屬性范圍:application范圍。

3.4、application屬性范圍

  這裡寫圖片描述

  因為application屬性范圍是在服務器上設置的一個屬性,所以一旦設置之後任何用戶都可以浏覽到此屬性。

下面通過代碼來觀察application屬性范圍

范例:applicationScopeDemo01.jsp

<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.util.*"%>
<%
    //此時設置的屬性任何用戶都可以取得
    application.setAttribute("name","孤傲蒼狼");  //設置屬性
    application.setAttribute("date",new Date());
%>

applicationScopeDemo02

范例:applicationScopeDemo02.jsp

<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.util.*"%>
<%
    String refName = (String)application.getAttribute("name");
    Date refDate = (Date)application.getAttribute("date");
%>

姓名:<%=refName%>

日期:<%=refDate%>

觀察頁面的運行效果:

  這裡寫圖片描述

  開啟多個浏覽器窗口,運行applicationScopeDemo02.jsp時,都可以顯示出上圖所示的結果,因為屬性范圍設置在了服務器中,所以只要是連接到此服務器的任意用戶都可以取得此屬性,當然,如果服務器關閉的話,則此屬性肯定消失。

  如把Tomcat服務器先關閉後再重新啟動,打開浏覽器窗口運行applicationScopeDemo02.jsp時,得到的結果如下圖所示:

  這裡寫圖片描述

  注意:如果在服務器上設置了過多的application屬性,則會影響到服務器的性能。<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoNCBpZD0="35關於pagecontext屬性范圍的進一步補充">3.5、關於pageContext屬性范圍的進一步補充

  之前所講解的四種屬性范圍,實際上都是通過pageContext屬性范圍設置上的。打開pageContext所在的說明文檔。

  這裡寫圖片描述

  PageContext類繼承了JspContext類,在JspContext類中定義了setAttribute方法,如下:

     public abstract void setAttribute(String name,Object value,int scope) 

  此方法中存在一個scope的整型變量,此變量就表示一個屬性的保存范圍。

  這裡寫圖片描述

  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_SCOPEAPPLICATION_SCOPE時,則表示setAttribute()方法設置的就是session屬性范圍和application屬性范圍。

下面通過代碼來觀察此四種屬性范圍常量的作用,以:request為例

范例:pageScopeDemo04.jsp

<%@page contentType="text/html;charset=GBK"%>
<%@page import="java.util.*"%>
<%
    pageContext.setAttribute("name","孤傲蒼狼",PageContext.REQUEST_SCOPE);  //設置屬性,並指明屬性范圍
    pageContext.setAttribute("date",new Date(),PageContext.REQUEST_SCOPE); //設置屬性,並指明屬性范圍
%>

pageScopeDemo05.jsp

<%@page contentType="text/html;charset=GBK"%>
<%@page import="java.util.*"%>
<%
    //使用request對象獲取屬性
    String refName = (String)request.getAttribute("name");
    Date refDate = (Date)request.getAttribute("date");
    //也可以使用pageContext對象獲取屬性,只要在獲取時指明對象的屬性范圍即可
    String refName2 = (String)pageContext.getAttribute("name", PageContext.REQUEST_SCOPE);
    Date refDate2 = (Date)pageContext.getAttribute("date", PageContext.REQUEST_SCOPE);
%>
使用request對象獲取屬性:

姓名:<%=refName%>

日期:<%=refDate%>

使用pageContext對象獲取屬性:

姓名:<%=refName2%>

日期:<%=refDate2%>

運行結果:

  這裡寫圖片描述

  從運行結果可以看到:在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)域中,像聊天數據。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved