官术网_书友最值得收藏!

5.5 session內置對象

HTTP協議本身是無狀態的,即信息無法通過HTTP協議本身進行傳遞。這與HTTP協議本來的目的是相符的,客戶端只需要簡單地向服務器發送請求,無論是客戶端還是服務器都沒有必要記錄彼此過去的行為,每一次請求之間都是獨立的。為了跟蹤用戶的操作狀態,在多個頁面之間保存共享信息,JSP中提供了session對象。該對象是產生于服務器端的,使用一種類似于散列表的結構來保存信息。

當需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session id,它是session的標識。如果已包含一個session ID則說明以前已經為此客戶端創建過session,服務器就按照session id把這個session檢索出來使用,如果客戶端請求不包含session ID,則為此客戶端創建一個session并且生成一個與此session相關聯的session ID,session ID的值應該是一個既不會重復又不容易被找到規律以仿造的字符串,這個session ID將在本次響應中返回給客戶端保存。session ID將保存在客戶機的cookie中。

session對象中主要方法如表5.5所示。

表5.5 session對象中常用方法

下面通過對幾個session常用例程的介紹,來詳細說明這些方法的具體用法。

5.5.1 獲取session的ID

session對象的ID是用來唯一識別session的標識,該ID是由一個32位的十六進制字符串組成,可以保證服務器中所創建的所有session對象都不相同。

【實例5-8】獲取session的ID。該實例通過一個獲取session的ID來證明一個會話過程中的多個頁面之間進行跳轉時使用的是同一個session對象。

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>
    05     <% String s=session.getId();        //獲取當前頁面的session對象的ID
    06     %>
    07  <P> 您的session對象的ID是:
    08     <BR>
    09     <%=s%>
    10  <P>輸入用戶姓名連接到session2.jsp
    11     <FORM action="session2.jsp" method=post name=form>
    12        <INPUT type="text" name="name">
    13        <INPUT TYPE="submit" value="提交" name=submit>
    14    </FORM>
    15  </BODY>
    16  </HTML>

【代碼說明】在該頁面的第5行中通過getId()方法獲取當前頁面的session ID并在第9行使用表達式顯示在頁面上。當單擊頁面中的“提交”按鈕時,將通過<form>表單跳轉到session2.jsp頁面。

【運行結果】實例5-8 的JSP頁面的執行結果如圖5.14所示。

圖5.14 顯示session1.jsp頁面的session的ID值

session2.jsp頁面的具體代碼如下:

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>session2.jsp頁面
    05     <% String s=session.getId();       //獲取當前頁面的session對象的ID
    06     %>
    07  <P> 在session2.jsp頁面中的session對象的ID是:
    08     <%=s%>
    09  <P> 單擊超鏈接,連接到session3.jsp頁面。
    10  <A HREF="session3.jsp">
    11   <BR>  進入session3.jsp
    12  </A>
    13  </BODY>
    14  </HTML>

【代碼說明】在該頁面的第5行中通過getId()方法獲取當前頁面的session ID并在第8行使用表達式顯示在頁面上。在第10行通過<a>標簽聲明一個超鏈接,該鏈接的目標地址是session3.jsp頁面。單擊session2.jsp頁面中的超鏈接,將轉向session3.jsp頁面。

【運行結果】session2.jsp頁面的執行結果如圖5.15所示。

session3.jsp頁面的具體代碼如下:

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>session3.jsp頁面
    05     <% String s=session.getId();       //獲取當前頁面的session對象的ID
    06     %>
    07  <P> 在session3.jsp頁面中的session對象的ID是:
    08     <%=s%>
    09  <P> 單擊超鏈接,連接到session1.jsp頁面。
    10  <A HREF="session1.jsp">
    11   <BR>  進入session1.jsp
    12  </A>
    13  </BODY>
    14  </HTML>

【代碼說明】在該頁面的第5行中通過getId()方法獲取當前頁面的session ID并在第8行使用表達式顯示在頁面上。在第10行通過<a>標簽聲明一個超鏈接,該鏈接的目標地址是session1.jsp頁面。單擊session3.jsp頁面中的超鏈接,將轉回到session1.jsp頁面。

【運行結果】session3.jsp頁面的執行結果如圖5.16所示。

圖5.15 顯示session2.jsp頁面的session的ID值

圖5.16 顯示session3.jsp頁面的session的ID值

通過比較圖5.14和圖5.15的運行結果可以看出,通過表單提交請求進行轉向的兩個頁面共享同一個session對象。通過圖5.16所示的運行結果可以看到,該頁面中的session ID與之前的頁面中的session ID也一樣,所以通過超鏈接進行轉向的兩個頁面也是共享同一個session對象的。

5.5.2 使用URL重寫支持session

前面介紹過,session對象的ID將保存在客戶機的cookie中,而cookie又被認為是一項不安全的技術。因此在瀏覽器中可以通過設置使cookie被禁用,這將直接導致session失效。

在瀏覽器中禁用cookie的操作步驟如下。

(1)選擇瀏覽器菜單欄中的“工具”|“Internet選項”命令,在彈出的“Internet選項”對話框中選擇“隱私”選項。

(2)在其中將隱私設置的滑塊設置到最高,即阻止所有cookie,然后單擊“確定”按鈕,將使得瀏覽器不支持任何網站發來的cookie。

設置完成后,再次運行實例5-8將會發現每個頁面中顯示的session ID各不相同,而且即使是同一個頁面,每次刷新之后顯示的session ID也是不同的。這個結果說明當瀏覽器中設置禁用cookie后,session對象也隨之失效了。那么對于應用程序來說,如果客戶端設置為禁用cookie,那么依賴session對象所實現的功能是不是就無法完成了呢?表面上看是這樣的,但是可以使用response對象的encodeURL()方法,通過URL重寫機制來在cookie禁用的情況下支持session。

實質上,URL重寫是通過向URL鏈接添加參數,并把session ID作為參數值包含在鏈接中。encodeURL()方法首先判斷cookie是否被瀏覽器所支持,如果支持則參數URL被原樣返回,否則session ID作為參數將添加到URL的后面。因此無論用戶的瀏覽器是否禁用cookie使用URL重寫機制都能正確支持session對象。

【實例5-9】使用URL重寫機制支持session。使用URL重寫機制改寫實例5-8,使得該實例在禁用cookie的客戶端瀏覽器中照樣能夠正常執行。修改后的實例5-8中的3個頁面代碼分別如下。

修改后的session1.jsp頁面的具體代碼如下:

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>
    05     <%
    06       String url=response.encodeURL("session2.jsp");   //對URL地址進行重寫
    07     %>
    08  <P> URL重寫后的路徑是:
    09     <BR>
    10     <%=url%>
    11  <P>輸入用戶姓名連接到session2.jsp
    12     <FORM action="<%=url%>" method=post name=form> <%--設置重寫后的URL為提交路徑--%>
    13        <INPUT type="text" name="name">
    14        <INPUT TYPE="submit" value="提交" name=submit>
    15    </FORM>
    16  </BODY>
    17  </HTML>

【代碼說明】在該頁面的第6 行中使用encodeURL()方法對要提交的頁面路徑進行URL重寫,然后在第12行將重寫后的路徑作為新的提交路徑賦值給<form>表單標簽的action屬性。

【運行結果】session1.jsp頁面的執行結果如圖5.17所示。

單擊“提交”按鈕后,將轉向session2.jsp頁面,修改后的session2.jsp頁面的具體代碼如下:

圖5.17 session1.jsp頁面顯示URL重寫后的路徑

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>session2.jsp頁面
    05     <%
    06      String url=response.encodeURL("session3.jsp");   //對URL地址進行重寫
    07     %>
    08  <P> URL重寫后的路徑是:
    09     <%=url%>
    10  <P> 單擊超鏈接,連接到session3.jsp頁面。
    11  <A HREF="<%=url%>"> <%--設置重寫后的URL為超級鏈接的路徑--%>
    12   <BR>  進入session3.jsp
    13  </A>
    14  </BODY>
    15  </HTML>

【代碼說明】在該頁面的第6 行中使用encodeURL()方法對要跳轉到的鏈接頁面的路徑進行URL重寫,然后在第11行將URL重寫后的路徑設置為超鏈接的路徑。

【運行結果】session2.jsp頁面的執行結果如圖5.18所示。

單擊超鏈接后,將轉向session3.jsp頁面,修改后的session3.jsp頁面的具體代碼如下:

圖5.18 session2.jsp頁面顯示URL重寫后的路徑

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY>
    04  <P>session3.jsp頁面
    05     <%
    06      String url=response.encodeURL("session1.jsp");    //對URL地址進行重寫
    07     %>
    08  <P> URL重寫后的路徑是:
    09     <%=url%>
    10  <P> 單擊超鏈接,連接到session1.jsp頁面。
    11  <A HREF="<%=url%>"> <%--設置重寫后的URL為超級鏈接的路徑--%>
    12   <BR>  進入session1.jsp
    13  </A>
    14  </BODY>
    15  </HTML>

【代碼說明】在該頁面的第6 行中使用encodeURL()方法對要跳轉到的鏈接頁面的路徑進行URL重寫,然后在第11行將URL重寫后的路徑設置為超鏈接的路徑。

【運行結果】session3.jsp頁面的執行結果如圖5.19所示。

圖5.19 session3.jsp頁面顯示URL重寫后的路徑

通過這三個頁面的運行結果可以看出,即使客戶端瀏覽器禁用了cookie,只要使用了URL重寫機制一樣可以支持session對象。

說明

建議讀者在日后的實際開發中涉及到對session對象的使用時,最好使用URL重寫機制,這樣能夠保證應用程序在任何的客戶端瀏覽器上都能正常執行。

5.5.3 session中保存和讀取共享數據

與request對象一樣,session對象也有一對setAttribute()和getAttribute()方法,用來存儲或者讀取session中的共享信息。session對象與request對象的這兩個方法的使用方式完全相同,區別在于共享信息的范圍不同,session對象中保存的共享信息的范圍是整個會話過程,而request對象中保存的共享信息的范圍則是提交和被提交的頁面。

【實例5-10】session和request對象共享信息的范圍。

設置共享信息頁面sessionSetAttribute.jsp的具體代碼如下:

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY >
    04     <%
    05       session.setAttribute("name","sun");      //將共享信息存儲到session對象中
    06    %>
    07    <a href="sessionReadAttribute.jsp">讀取共享信息</a>
    08  </BODY>
    09  </HTML>

【代碼說明】在該頁面的第5行中使用setAttribute(String name,Object object)方法將共享數據保存到session對象中,然后在第7行中使用超鏈接轉向到讀取共享信息的頁面。

讀取共享信息頁面sessionReadAttribute.jsp的具體代碼如下:

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <HTML>
    03  <BODY >
    04     讀取的共享信息是:
    05     <%
    06       out.println(session.getAttribute("name")); //從session對象中獲取共享信息并顯示
    07     %>
    08  </FONT>
    09  </BODY>
    10  </HTML>

【代碼說明】在該頁面的第6行中使用getAttribute(String name)方法來獲取存儲在session中的共享數據并使用out對象將其顯示在頁面上。

【運行結果】sessionReadAttribute.jsp頁面的執行結果如圖5.20所示。如果將代碼中的session對象換成request對象,將顯示如圖5.21所示的運行結果。

圖5.20 讀取并顯示session對象中的共享數據

圖5.21 讀取不到request對象中的共享信息

通過以上運行結果可以看出,request對象只能讀取提交頁面中保存的共享信息,而session對象則可以讀取會話中存儲的共享信息。

5.5.4 session的生命周期

session對象的創建是由服務器完成的,當客戶端第一次請求服務器時由服務器創建。如果會話過程一直存在,則session對象也將一直存在下去。只有當session過期、客戶端關閉瀏覽器或者服務器端調用了session的invalIDate()方法時session對象才被釋放掉,結束其生命周期。

【實例5-11】session的生命周期。

    01  <%@ page contentType="text/html;charset=GB2312" %>
    02  <html>
    03  <head>
    04  <title>Session生命周期</title>
    05  </head>
    06  <body>
    07  <h2>Session生命周期</h2>
    08  <%
    09  if(session.isNew()) // 如果session是新的,設定session生命周期的初始值
    10      {
    11           session.setMaxInactiveInterval(10);  //設定session若10秒內沒活動則使
                 Session過期
    12           session.setAttribute("expire","10"); //將此session的time out的秒數加入
                 過期時間中
    13           out.println("設定Session若十秒內沒有活動則使Session過期");
    14           }
    15  else
    16      {
    17          String str_expire_time =(String)session.getAttribute("expire");
    18           long create_time=session.getCreationTime();  //取得session創建的時間
    19           long access_time=session.getLastAccessedTime();//獲得session最后訪問時間
    20           long current_time=System.currentTimeMillis();     //獲取當前系統時間
    21           long exist_time=(current_time-create_time)/1000; //計算session存在時間
    22           out.println("session已存在"+exist_time+"秒");      //輸出session存在時間
    23               if (exist_time>=30)  //如果session存在的時間超過30秒,則將session移除
    24               {
    25                   out.println("session時間已到...自動失效");
    26                   session.invalidate();                     //使session實效
    27               }
    28               }
    29  %>
    30  </body>
    31  </html>

【代碼說明】在該頁面的第9行中通過調用session對象的isNew()方法來判斷session對象是否是第一次創建的。在第10~14行為新創建的session對象設置最大不活躍的時間,當超過這個時間時,session對象將被清除。在第16~28行表示如果不是新創建的session對象,則表示session對象已經存在,這樣就顯示出session對象已經存在的時間,并且當session對象存在超過30秒后,自動移除該session對象。

【運行結果】該頁面在不同時間段內運行的結果如圖5.22~圖5.24所示。

圖5.22 新建session對象時顯示的頁面信息

圖5.23 在創建session對象30秒內顯示的頁面信息

圖5.24 session對象移除后顯示的頁面信息

主站蜘蛛池模板: 喀什市| 宁晋县| 文成县| 明水县| 许昌市| 界首市| 灵台县| 友谊县| 余干县| 石柱| 原平市| 营口市| 南通市| 新泰市| 邵东县| 昌乐县| 高淳县| 永济市| 平乡县| 郁南县| 小金县| 汶上县| 公主岭市| 平遥县| 遂宁市| 辰溪县| 闽侯县| 宜兰县| 名山县| 嫩江县| 象州县| 舒兰市| 沙坪坝区| 桐庐县| 安福县| 宁蒗| 河南省| 资阳市| 鄂温| 灵丘县| 济阳县|