一、Session機制
session機制採用的是在服務器端保持 HTTP 狀態信息的方案 。
服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要爲某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求裏是否包含了一個session標識(即sessionId),如果已經包含一個sessionId則說明以前已經爲此客戶創建過session,服務器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個,這種情況可能出現在服務端已經刪除了該用戶對應的session對象,但用戶人爲地在請求的URL後面附加上一個JSESSION的參數)。如果客戶請求不包含sessionId,則爲此客戶創建一個session並且生成一個與此session相關聯的sessionId,這個session
id將在本次響應中返回給客戶端保存。
二、保存SessionID的方式
①.保存session id的方式可以採用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發送給服務器。
②.由於cookie可以被人爲的禁用,必須有其它的機制以便在cookie被禁用時仍然能夠把session id傳遞迴服務器,經常採用的一種技術叫做URL重寫,就是把session id附加在URL路徑的後面,附加的方式也有兩種,一種是作爲URL路徑的附加信息,另一種是作爲查詢字符串附加在URL後面。網絡在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。
Session Cookie
session通過SessionID來區分不同的客戶, session是以cookie或URL重寫爲基礎的,默認使用cookie來實現,系統會創造一個名爲JSESSIONID的輸出cookie,這稱之爲session cookie,以區別persistent cookies(也就是我們通常所說的cookie),session cookie是存儲於瀏覽器內存中的,並不是寫到硬盤上的,通常看不到JSESSIONID,但是當把瀏覽器的cookie禁止後,web服務器會採用URL重寫的方式傳遞Sessionid,這時地址欄看到
session cookie針對某一次會話而言,會話結束session cookie也就隨着消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本。
關閉瀏覽器,只會是瀏覽器端內存裏的session cookie消失,但不會使保存在服務器端的session對象消失,同樣也不會使已經保存到硬盤上的持久化cookie消失。
三、Session的生命週期
1)什麼時候創建HTTPSession對象?
①:對於JSP:瀏覽器訪問訪問服務器端的任何一個JSP,服務器都會立即創建一個HttpSession對象?
不一定.
*若當前的JSP 是客戶端訪問的當前WEB 應用的第一個資源,且 JSP 的 page 指定的session屬性爲false,則服務器就不會爲JSP創建一個HttpSession對象
*若當前JSP不是客戶端訪問的當前WEB應用的第一個資源,且其他頁面已經創建一個HttspSession對象,則服務器也不會爲當前JSP頁面創建一個HttpSession對象,而會把和當前會話相關的那個HTTPSession對象返回給當前的JSP頁面
②:對於Servlet::若 Servlet 是客戶端訪問的第一個WEB應用的資源,則只有調用了request.getSession() 或 request.getSession(true) 纔會創建HTTPSession對象
2)page 指令 的session="false" 到底什麼意思
*當前JSP頁面禁用session隱含變量!但可以使用其他的顯示的 HttpSession對象
3)在Servlet 中 如何獲取HTTPSession對象?
*request.getSession(boolean create):當create 爲 false 時,若沒有和當前JSP頁面關聯的 Httpsession 對象,返回null,若有則返回 HttpSession 對象。
當create爲 true ,一定會返回 HttPSession 對象,若沒有和當前JSP頁面關聯的HTTPSession對象,則服務器會創建一個新的HTTPSession對象,若有關聯,則直接返回關聯的。
*request..getSession()等同於request.getSession(true)
4)什麼時候銷燬HttpSession對象
①.直接調用 HttpSession 的 invalidate() 方法:立刻是HTTPSession對象失效
②.服務器卸載了當前 WEB 應用
③.超出了 HTTPSession 的過期時間
* 設置HttpSession的過期時間,調用session.setMaxInactiveInterval(int x); 單位是秒
* 在Tomcat 的 WEB.xml中設置 (單位是分鐘,如果session不設置生命週期,就會使用這個默認的)
<session-config>
<session-timeout>30</session-timeout >
</session-config>
④. 並不是關閉了瀏覽器就銷燬了 session ,所以說要訪問到Session對象,可以通過持久化Cookie 和 URL重寫 兩種方式 。
詳細看 HttpSession API
代碼示例
login.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
SessionID: <%=session.getId() %><br><br>
IsNew: <%=session.isNew() %><br><br>
MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br>
createTime: <%=session.getCreationTime() %><br><br>
lastAccessTime: <%=session.getLastAccessedTime() %><br><br>
<%
Object username = session.getAttribute("username");
if(username == null){
username = "";
}
%>
<form action="hello.jsp" method="post">
<%--<form action="<%=response.encodeURL("hello.jsp") %>" method="post">--%> // 如果客戶端的Cookie處於禁用狀態,就要使用URL重寫
username:<input type="text" name="username" value="<%=username %>" />
<input type="submit" name="Submit" />
</form>
</body>
</html></span>
hello.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
SessionID: <%=session.getId() %><br><br>
IsNew: <%=session.isNew() %><br><br>
MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br>
createTime: <%=session.getCreationTime() %><br><br>
lastAccessTime: <%=session.getLastAccessedTime() %><br><br>
Hello:<%=request.getParameter("username") %><br>
<%-- <a href="login.jsp?username= <%= request.getParameter("username") %> ">重新登錄</a> 採用設置屬性的方式比較好--%>
<%
session.setAttribute("username",request.getParameter("username"));
%>
<%-- <%=response.encodeURL("login.jsp") %> <%=response.encodeURL("logout.jsp") %> URL重寫--%>
<a href="login.jsp">重新登錄</a>
<a href="logout.jsp">註銷</a>
</body>
</html></span>
logout.jsp
<span style="font-family:KaiTi_GB2312;font-size:18px;"><%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
SessionID: <%=session.getId() %><br><br>
IsNew: <%=session.isNew() %><br><br>
MaxInactiveInternal: <%=session.getMaxInactiveInterval() %><br><br>
createTime: <%=session.getCreationTime() %><br><br>
lastAccessTime: <%=session.getLastAccessedTime() %><br><br>
Bye:<%=session.getAttribute("username") %><br><br>
<a href="login.jsp?">重新登錄</a>
<%
session.invalidate();//殺死session
%>
</body>
</html></span>
HttpSession接口中的方法
getId方法 getCreationTime方法
getLastAccessedTime方法 setMaxInactiveInterval方法
getMaxInactiveInterval方法 isNew方法
如果客戶端請求消息中返回了一個與Servlet程序當前獲得的HttpSession對象的會話標識號相同的會話標識號,則認爲這個HttpSession對象不是新建的。
invalidate方法 getServletContext方法
setAttribute方法 getAttribute方法
removeAttribute方法 getAttributeNames方法
HttpServletRequest接口中的Session方法
getSession方法
public HttpSession getSession(boolean create)
public HttpSession getSession()
isRequestedSessionIdValid方法
isRequestedSessionIdFromCookie方法
isRequestedSessionIdFromURL方法
利用URL重寫實現Session跟蹤
Servlet規範中引入了一種補充的會話管理機制,它允許不支持Cookie的瀏覽器也可以與WEB服務器保持連續的會話。這種補充機制要求在響應消息的實體內容中必須包含下一次請求的超鏈接,並將會話標識號作爲超鏈接的URL地址的一個特殊參數。
將會話標識號以參數形式附加在超鏈接的URL地址後面的技術稱爲URL重寫。如果在瀏覽器不支持Cookie或者關閉了Cookie功能的情況下,WEB服務器還要能夠與瀏覽器實現有狀態的會話,就必須對所有可能被客戶端訪問的請求路徑(包括超鏈接、form表單的action屬性設置和重定向的URL)進行URL重寫。
HttpServletResponse接口中定義了兩個用於完成URL重寫方法:
encodeURL方法
encodeRedirectURL方法
關於在IE下禁用cookie,刷新SessionId不變的情況
從網上找到了答案,只要是IE或基於IE內核的瀏覽器,關閉Cookie實際上並沒有真的關閉,論壇上都是噴IE的
在Chrome 和 火狐 上試驗,SessionID不刷新的問題就不存在了