session和request的生命周期
首先是session,比如我們在實現一個購物車功能時,在某一頁面(這里稱為頁面A)選擇了一些購物的商品,添加到購物車。那么當我們選擇完成后點擊我的購物車時會跳轉到一個購物車頁面(這里稱為頁面B),這和頁面A是兩個不同的頁面,那么怎么講頁面A選取的商品添加到頁面B呢。這里一種解決方案就是session。直接上一個demo了:
A.jsp頁面:
<body> <h1>A界面</h1> <% session.setAttribute("name","蘋果");//這是jsp文件,如果是Servlet的話,先得獲得Session,HttpSession hs=request.getSession(true); %> </body>
B.jsp頁面:
<body> <h1>B界面</h1> <% String name = (String) session.getAttribute("name"); %> <p>Session的值為:<%=name%></p> </body>
上面就達到了一個傳值的目的,當然,我們談的是session的生命周期,Tomcat里,默認的session生命周期是30min,也就是你不操作界面的時間,你一刷新界面的話,session會重新計時的,那么session的默認時間可以改么,答案是肯定的。可以在Tomcat目錄下的conf文件下的web.xml進行修改,如下圖所示,默認是30min,修改的話改個數值就行了:
當然我們每個應用程序的session可以自己設置生命周期,比如在A.jsp界面加句話就行了。
A.jsp頁面:
<body> <h1>A界面</h1> <% session.setAttribute("name", "蘋果");//這是jsp文件,如果是Servlet的話,先得獲得Session,HttpSession hs=request.getSession(true); session.setMaxInactiveInterval(5); %> </body>
這里session.setMaxInactiveInterval(5);設置的是有效時間5秒,這里是以秒為單位的。
那么比如我從A界面跳轉到B界面,B界面會顯示Asession傳過來的session內容,但是如果我5秒內沒有動過B界面,那么再次刷新A界面時, 將不會再獲得session內的值了,因為這個session失效了。
下面是request,request有兩個方法:getParameter()和getAttribute()
現在有兩個界面test1.jsp,test2.jsp,當我們在瀏覽器中輸入http://127.0.0.1:8080/AA/test2.jsp時,一個request就產生了,也就是生命周期的開始。test1.jsp的request中,我們可以設置一些值,比如我在test1.jsp是這樣設置的:
<body> <h1>test1界面</h1> <% request.setAttribute("name", "hello"); %> <a href="test2.jsp"></a> </body>
上面setAttribue是在request中設置值的。那么問題來了,我們需要從test1.jsp界面跳轉訪問test2.jsp界面,是否test2.jsp界面中的request也保存test1.jsp中的request值呢?
一般來說有兩種處理方式實現跳轉,一種是response.sendRedirect,另一種是request.getRequestDispatcher("xxx.jsp").forward(request,response);
用第一種方法,那么test1.jsp中的request不會傳遞到test2.jsp。
用第二種方法,request的生命周期將延續下去,當采用forward如果到達JSP頁面,那么之前從第一個JSP頁面中發送出來的request的消息將仍然存在,新的頁面同樣能夠取得該request里所包含的一些信息,比如之前的JSP發送request中所包含的參數信息。事實上,它們是同一個request。
這里注意一下:第二種方法中,如果在頁面中通過setAttribute()設置一個Object值到request中,那么在另一個頁面中可以通過getAttribute()來獲得值,這里值是Object類型的。
下面是test1.jsp和test2.jsp頁面的代碼:
test1.jsp
<body>
<h1>test1界面</h1>
<%
request.setAttribute("name", "hello");
request.getRequestDispatcher("test2.jsp").forward(request, response);
%>
<a href="test2.jsp"></a>
</body>
test2.jsp
<body> <h1>test2界面</h1> <% String name = (String) request.getAttribute("name"); %> <p>值為:<%=name%></p> </body>
session和cookie的區別
session是存儲服務器端,cookie是存儲在客戶端,所以session的安全性比cookie高。
也因此關了瀏覽器session當然仍然存在,因為session是儲存在服務器端的,而服務器是不知道你有沒有關掉瀏覽器的。
獲取session里的信息是通過存放在會話cookie里的session id獲取的。
session是存放在服務器的內存中里,而session里的數據不斷增加會造成服務器的負擔,所以會把很重要的信息存儲在session中,而把一些次要東西存儲在客戶端的cookie里。
cookie確切的說分為兩大類:會話cookie和持久化cookie。
會話cookie是存放在客戶端瀏覽器的內存中,他的生命周期和瀏覽器是一致的,當瀏覽器關閉會話cookie也就消失了。
而持久化cookie是存放在客戶端硬盤中,持久化cookie的生命周期(session-timeout)是我們在設置cookie時候設置的那個保存時間,
session的信息是通過session id獲取的,而session id是存放在會話cookie當中的,當瀏覽器關閉的時候會話cookie消失,所以session id也就消失了,
但是session的信息還存在服務器端,並沒有消失,只是查不到session但它並不是不存在。同時由於關閉瀏覽器不會導致session被刪除,所以迫使服務器為seesion設置了一個失效時間(session-timeout),當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間。
對於“只要關閉瀏覽器,session就消失了”誤解的解釋
在談論session機制的時候,常常聽到這樣一種誤解“只要關閉瀏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程序(相當於客戶)通知服務器刪除一個session,否則服務器會一直保留,程序一般都是在用戶做log off的時候發個指令去刪除session。瀏覽器從來不會在關閉之前主動通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器是否關閉。之所以會有這種錯覺,是因為大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器后這個session id就消失了,再次連接服務器時也就無法找到原來的session。如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,即持久化cookie,則再次打開瀏覽器仍然能夠找到原來的session。