書中講:
以下情況,Session結束生命週期,Servlet容器將Session所佔資源釋放:
1.客戶端關閉瀏覽器
2.Session過期
3.服務器端調用了HttpSession的invalidate()方法。
"一個瀏覽器就是一個新session,關了瀏覽器session就結束了"
session 是在服務器端建立的,瀏覽器訪問服務器會有一個sessionid,瀏覽器端通過sessionid定位服務器端的session,session的創建和銷燬由服務器端控制。當瀏覽器關閉後,session還存在在服務器端,只不過你新開的瀏覽器去訪問服務器會創建另一個session,這個時候的 sessionid已經不一樣了。也就不能訪問上一次的哪個session裏面的內容了。
"session的創建和銷燬由服務器端控制",服務器端纔有session,客戶端只是通過sessionid來匹配session.
那服務器端session如何建的呢? 普通html不會創建,jsp默認是創建的,只要你訪問任何一個jsp就會創建(不過只創建一次),你關閉瀏覽器重新訪問又會創建一個,這些創建的session由服務器自己控制銷燬,你也可以在服務器端代碼中銷燬。
什麼情況下需要用上這種服務器端的session方式?
默認情況下,jsp被訪問就會創建session(最開始是空的沒有數據的),你的應用中的代碼只是往session裏面put數據。網上說可以 通過 <%@ page session="false"%>來不讓jsp自動創session.我自己測試了一下(用sessionlistener),根本不起作用, session照樣創建成功。
最後說一下,只有服務器端纔有session.客戶端被存到本地的是cookie.不過安全性低。所以不能放重要的數據。
============================================================================
sesion其實簡單:
先request.getsession(),當已有一個session與前request相關時就返回對這個 session的引用,當沒有時就生成一個.一個session在server通過一個sessionid來標識的。也就是說在一個server是不會有 兩個相同sessionid的session.
那麼session爲什麼會和cookie扯在一起呢?
正如我所說對於一 個session來說它的sessionid就是其身份的標識。若我們將這個sessionid保存到用戶端,當同一個會話的後序請求來時都將這個 sessionid放在request 的header中(也就是我們說的cookie)這樣不就可以來驗證這個request是否與之前的request是同一個會話了嗎!
什麼是會話呢?
我 們可以通俗一點理解。只要你的browers不關我們就稱這一系列的request與response爲一個會話。一斷你close就稱這個會話已結束。 雖然會話結束但並不代表你的session就被destroy.因爲session是存活在server上的。它的生命完全由server來主宰 (web.xml中的設定).
雖然你的session還存活在server上但你已無法再取得它。因爲j2ee的api只給我們一種方法來取得與當前會話相關的session的引用:request.getsession() or reqeust.getsession(boolean)
=======================================================================
一個常見的誤解是以爲session在有客戶端訪問時就被創建,然而事實是直到某server端程序調用HttpServletRequest.getSession(true)這樣的語句時才被創建,注意如果JSP沒有顯示的使用 <%@page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句HttpSession
session = HttpServletRequest.getSession(true);
這也是JSP中隱含的session對象的來歷。
<**********************有點矛盾的地方,到底JSP顯示的使用< %@page session="false"%>能不能讓服務端不創建sessionid呢?試驗下**************************>
<%@ page session="false"%>
不是不讓頁面創建Session,而是在此JSP頁面無法使用session.可以減少網絡數據傳輸.
=========================================================================================================================
session 失效時間
在一般系統登錄後,都會設置一個當前session失效的時間,以確保在用戶沒有使用系統一定時間後,自動退出登錄,銷燬session。
具體設置很簡單:
在主頁面或者公共頁面中加入:session.setMaxInactiveInterval(900);
參數900單位是秒,即在沒有活動15分鐘後,session將失效。
這裏要注意這個session設置的時間是根據服務器來計算的,而不是客戶端。所以如果是在調試程序,應該是修改服務器端時間來測試,而不是客戶端。
在一般系統中,也可能需要在session失效後做一些操作,
(1)控制用戶數,當session失效後,系統的用戶數減少一個等,控制用戶數在一定範圍內,確保系統的性能。
(2)控制一個用戶多次登錄,當session有效時,如果相同用戶登錄,就提示已經登錄了,當session失效後,就可以不用提示,直接登錄了
那麼如何在session失效後,進行一系列的操作呢?
這裏就需要用到監聽器了,即當session因爲各種原因失效後,監聽器就可以監聽到,然後執行監聽器中定義好的程序,就可以了。
監聽器類爲:HttpSessionListener類,有sessionCreated和sessionDestroyed兩個方法
自己可以繼承這個類,然後分別實現。
sessionCreated指在session創建時執行的方法
sessionDestroyed指在session失效時執行的方法
給一個簡單的例子:
public class SessionListener implements HttpSessionListener{
public void sessionCreated(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
SummerConstant.UserMap.put(id, Boolean.TRUE); //添加用戶
}
public void sessionDestroyed(HttpSessionEvent event) {
HttpSession ses = event.getSession();
String id=ses.getId()+ses.getCreationTime();
synchronized (this) {
SummerConstant.USERNUM--; //用戶數減一
SummerConstant.UserMap.remove(id); //從用戶組中移除掉,用戶組爲一個map
}
}
}
然後只需要把這個監聽器在web.xml中聲明就可以了
例如:
<listener>
<listener-class>
com.summer.kernel.tools.SessionListener
</listener-class>
</listener>
補充:
具體設置很簡單,方法有三種:
(1)在主頁面或者公共頁面中加入:session.setMaxInactiveInterval(900);
參數900單位是秒,即在沒有活動15分鐘後,session將失效。設置爲-1將永不關閉。
這裏要注意這個session設置的時間是根據服務器來計算的,而不是客戶端。所以如果是在調試程序,應該是修改服務器端時間來測試,而不是客戶端。
(2)也是比較通用的設置session失效時間的方法,就是在項目的web.xml中設置
<session-config>
<session-timeout>15</session-timeout>
</session-config>
這裏的15也就是15分鐘失效.
(3)直接在應用服務器中設置,如果是tomcat,可以在tomcat目錄下conf/web.xml中
找到<session-config>元素,tomcat默認設置是30分鐘,只要修改這個值就可以了。
需要注意的是如果上述三個地方如果都設置了,有個優先級的問題,從高到低:
(1)--?(2)---?(3)
session的過期時間計算是從當前session的最後一次請求開始的。
做一個過濾器,實現Filter接口,對指定路徑下的請求進行session的失效驗證,如失效則跳轉到登錄頁面:
public class RequestFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
//在這裏判斷session是否已失效,如已失效則重定向到登錄頁面。
/*
User user = (User)request.getSession().getAttribute("user");
if(user == null) {
response.sendRedirect(request.getContextPath()+"/login.jsp");
return;
}
*/
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
}
在web.xml裏配置過濾器:
<filter>
<filter-name>requestFilter</filter-name>
<filter-class>com.xxx.RequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
至於你說的直接跳到登錄頁面,由於頁面響應到達客戶端瀏覽器後就已經與服務端斷開連接並呈靜態,必須要等到用戶再次操作向服務端發起請求時才能執行。
============================================================================================================
cookie 和session 的區別:
1、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙
考慮到安全應當使用session。
3、session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能
考慮到減輕服務器性能方面,應當使用COOKIE。
4、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
5、所以個人建議:
將登陸信息等重要信息存放爲SESSION
其他信息如果需要保留,可以放在COOKIE中
原文鏈接:
http://www.cnblogs.com/tiechui/archive/2010/11/30/1892145.html
http://fengpy2009.iteye.com/blog/834717