客戶與服務(wù)器之間的通信是通過(guò) HTTP 協(xié)議完成的。HTTP 是一種無(wú)狀態(tài)的協(xié)議,當(dāng)客戶向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器接收請(qǐng)求并返回響應(yīng)后,該連接就被關(guān)閉了。此時(shí),服務(wù)器端不保留連接的有關(guān)信息,要想記住客戶的連接信息,可以使用 JSP 提供的 session 對(duì)象。
用戶登錄網(wǎng)站時(shí),系統(tǒng)將為其生成一個(gè)獨(dú)一無(wú)二的 session 對(duì)象,用以記錄該用戶的個(gè)人信息。一旦用戶退出網(wǎng)站,那么,所對(duì)應(yīng)的 session 對(duì)象將被注銷。session 對(duì)象可以綁定若干個(gè)用戶信息或者 JSP 對(duì)象,不同的 session 對(duì)象的同名變量是不會(huì)相互干擾的。
當(dāng)用戶首次訪問(wèn)服務(wù)器上的一個(gè) JSP 頁(yè)面時(shí),JSP 引擎便產(chǎn)生一個(gè) session 對(duì)象,同時(shí)分配一個(gè) String 類型的 ID 號(hào),JSP 引擎同時(shí)將這個(gè) ID 號(hào)發(fā)送到客戶端,存放在 Cookie 中,這樣,session 對(duì)象和客戶端之間就建立了一一對(duì)應(yīng)的關(guān)系。
當(dāng)用戶再次訪問(wèn)該服務(wù)器的其他頁(yè)面時(shí),不再分配給用戶新的 session 對(duì)象,直到用戶關(guān)閉瀏覽器,或者在一定時(shí)間(系統(tǒng)默認(rèn)在 30 分鐘內(nèi),但可在編寫程序時(shí),修改這個(gè)時(shí)間限定值或者顯式地結(jié)束一個(gè)會(huì)話)客戶端不向服務(wù)器發(fā)出應(yīng)答請(qǐng)求,服務(wù)器端就會(huì)取消該用戶的 session 對(duì)象,與用戶的會(huì)話對(duì)應(yīng)關(guān)系消失。當(dāng)用戶重新打開瀏覽器,再次連接到該服務(wù)器時(shí),服務(wù)器為該用戶再創(chuàng)建一個(gè)新的 session 對(duì)象。
session 對(duì)象保存的是每個(gè)用戶專用的私有信息,可以是與客戶端有關(guān)的,也可以是一般信息,可以根據(jù)需要設(shè)定相應(yīng)的內(nèi)容,并且所保存的信息在當(dāng)前 session 屬性范圍內(nèi)是共享的。表 1 列出了 session 對(duì)象的常用方法。
表1 session對(duì)象的常用方法
方法 |
說(shuō)明 |
---|---|
Object getAttribute(String name) |
獲取指定名字的屬性 |
Enumeration getAttributeName() |
獲取 session 中全部屬性的名字,一個(gè)枚舉 |
long getCreationTime() |
返回 session 的創(chuàng)建時(shí)間,單位:毫秒 |
public String getld() |
返回創(chuàng)建 session 時(shí) JSP 引擎為它設(shè)置的唯一 ID 號(hào) |
long getLastAccessedTime() |
返回此 session 中客戶端最近一次請(qǐng)求的時(shí)間。由 1970-01-01算起,單位是毫秒。使用這個(gè)方法,可以判斷某個(gè)用戶在站點(diǎn)上一共停留了多長(zhǎng)時(shí)間 |
int getMaxInactiveInterval() |
返回兩次請(qǐng)求間隔多長(zhǎng)時(shí)間 session 被銷毀(單位:秒) |
void setMaxlnactivelnterval(int interval) |
設(shè)置兩次請(qǐng)求間隔多長(zhǎng)時(shí)間 session 被銷毀(單位:秒) |
void invalidate() |
銷毀 session 對(duì)象 |
boolean isNew() |
判斷請(qǐng)求是否會(huì)產(chǎn)生新的 session 對(duì)象 |
void removeAttxibute(String name) |
刪除指定名字的屬性 |
void setAttribute(String name,String value) |
設(shè)定指定名字的屬性值 |
使用 session 對(duì)象在不同的 JSP 文件(整個(gè)客戶會(huì)話過(guò)程,即 session scope)中保存屬性信息,比如用戶名、驗(yàn)證信息等,最為典型的應(yīng)用是實(shí)現(xiàn)網(wǎng)上商店購(gòu)物車的信息存儲(chǔ)。下面重點(diǎn)介紹 session 對(duì)象的應(yīng)用。
JSP 頁(yè)面可以將任何對(duì)象作為屬性來(lái)保存。使用 setAttribute() 方法設(shè)置指定名稱的屬性,并將其存儲(chǔ)在 session 對(duì)象中,使用 getAttribute() 方法獲取與指定名字 name 相聯(lián)系的屬性。語(yǔ)法格式如下:
session.setAttribute(String name,String value); //參數(shù)name為屬性名稱,value為屬性值
session.getAttribute(String name); //參數(shù) name 為屬性名稱
例1:用 session 對(duì)象創(chuàng)建及獲取會(huì)話屬性。通過(guò) session 對(duì)象的 setAttribute() 方法,將數(shù)據(jù)保存在 session 對(duì)象中,并通過(guò) getAttribute() 方法取得數(shù)據(jù)的值,代碼如下:
<!--3-13.jsp-->
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<html>
<head>
<title>
session 對(duì)象創(chuàng)建及獲取客戶會(huì)話屬性
</title>
</head>
<body>
session 的創(chuàng)建時(shí)間:<%=new Date(session.getCreationTime()).toLocaleString() %> <br>
session 的 ID 號(hào):<%=session.getId() %> <br> <hr>
當(dāng)前時(shí)間:<%=new Date().toLocaleString( ) %> <br>
該 session 是新創(chuàng)建的嗎?:<%=session.isNew()?"是":"否" %> <br> <hr>
當(dāng)前時(shí)間:<%=new Date().toLocaleString( ) %> <br>
<% session.setAttribute("info","您好,我們正在使用 session 對(duì)象傳遞數(shù)據(jù)!"); %>
已向 Session 中保存數(shù)據(jù),請(qǐng)單擊下面的鏈接將頁(yè)面重定向到 4-11-1.jsp
<a href="Test.jsp"> 請(qǐng)按這里</a>
</body>
</html>
3-13-1.jsp 與 3-13.jsp 的代碼基本相同,不同的是獲取 session 對(duì)象中的屬性值的方法,重要代碼如下:
獲取 session 中的數(shù)據(jù)為:<br>
<%=session.setAttribute("info")%>
運(yùn)行結(jié)果如圖 1(a) 所示,單擊超鏈接“請(qǐng)按這里”,進(jìn)入如圖 1(b) 所示的頁(yè)面。
a)頁(yè)面 3-13.jsp 的運(yùn)行結(jié)果
b)頁(yè)面 3-13-1.jsp 的運(yùn)行結(jié)果
圖1 用session對(duì)象創(chuàng)建及獲取會(huì)話屬性
JSP 頁(yè)面可以將任何已經(jīng)保存的對(duì)象部分或者全部移除。使用 removeAttribute() 方法,將指定名稱的對(duì)象移除,也就是說(shuō),從這個(gè)會(huì)話刪除與指定名稱綁定的對(duì)象。使用 invalidate() 方法,可以將會(huì)話中的全部?jī)?nèi)容刪除。語(yǔ)法格式如下:
session.removeAttribute(String name); //參數(shù)name為session對(duì)象的屬性名,代表要移除的對(duì)象名
session.invalidate(); //把保存的所有對(duì)象全部刪除
例2:用 session 對(duì)象從會(huì)話中移除指定的對(duì)象。繼續(xù)沿用例 1 中的 3-13.jsp 頁(yè)面,并且改造 3-13-1.jsp,代碼如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<html>
<head>
<title>
session 對(duì)象創(chuàng)建及獲取客戶會(huì)話屬性
</title>
</head>
<body>
session 的創(chuàng)建時(shí)間:<%=new Date(session.getCreationTime()).toLocaleString() %> <br>
session 的 ID 號(hào):<%=session.getId() %> <br> <hr>
當(dāng)前時(shí)間:<%=new Date().toLocaleString( ) %> <br>
該 session 是新創(chuàng)建的嗎?:<%=session.isNew()?"是":"否" %> <br> <hr>
當(dāng)前時(shí)間:<%=new Date().toLocaleString( ) %> <br>
移除 session 中的數(shù)據(jù)后:<br>
<%
session.removeAttribute("info");
if(session.getAttribute("info")==null)
{
out.println("session 對(duì)象 info 已經(jīng)不存在");
}
else
{
out.println(session.getAttribute("info"));
}
%>
</body>
</html>
運(yùn)行程序,單擊“請(qǐng)按這里”超鏈接后,將會(huì)顯示如圖 2 所示的頁(yè)面。
圖2 用session對(duì)象從會(huì)話中移除指定的對(duì)象
當(dāng)某一客戶與 Web 應(yīng)用程序之間處于非活動(dòng)狀態(tài)時(shí),并不以顯式的方式通知服務(wù)器,所以,在 Servlet 程序或 JSP 文件中,做超時(shí)設(shè)置是確保客戶會(huì)話終止的唯一方法。
Servlet 程序容器設(shè)置一個(gè)超時(shí)時(shí)長(zhǎng),當(dāng)客戶非活動(dòng)的時(shí)間超出時(shí)長(zhǎng)的大小時(shí),JSP 容器將使 session 對(duì)象無(wú)效,并撤銷所有屬性的綁定,這樣,就清除了客戶申請(qǐng)的資源,從而實(shí)現(xiàn)了會(huì)話生命周期的管理。
session 用于管理會(huì)話生命周期的方法有 getLastAccessedTime()、getMaxInactiveInterval() 和 setMaxInactiveInterval(int interval)。
例3:為 session 對(duì)象設(shè)置會(huì)話時(shí)限。首先輸出 session 對(duì)象默認(rèn)的有效時(shí)間,然后設(shè)置為 5 分鐘,并輸出新設(shè)置的有效時(shí)間。代碼如下:
<%@ page language="java" pageEncoding="utf-8" %>
<html>
<head>
<title>
session 對(duì)象設(shè)置會(huì)話時(shí)限
</title>
</head>
<body>
session 對(duì)象默認(rèn)的有效時(shí)間:<%=session.getMaxInactiveInterval()%>秒<br>
<%
session.setMaxInactiveInterval(60*5); //設(shè)置session的有效時(shí)間為5分鐘
%>
已經(jīng)將 session 有效時(shí)間修改為:<%=session.getMaxInactiveInterval()%>秒<br>
</body>
</html>
運(yùn)行結(jié)果如圖 3 所示。
圖3 session對(duì)象設(shè)置會(huì)話時(shí)限