若您對session還不熟悉的話,建議您先閱讀 Servlet Session 和 Request的差別 這篇文章

 

當客戶端發送請求給伺服器時,伺服器中的Container收到客戶端送來的請求後,會為該客戶端建立一個sesson物件。

session物件在Tomcat(Tomcat就是一個Container)中的預設生命週期為30分鐘,也就是說,在Container建立session後,若過了30分鐘都沒收到任何此session所屬的客戶端的請求,則Container會使這個session失效(invalidation),在下一次同個客戶端發來請求時,Container會為其另外建立一個新的session。

 

我們在應用程式中,可以透過以下設定來修改session的存活時間。

第一種方法是在web.xml中設定如下...

...

<session-timeout>中的數字代表session可存活的時間,單位為分鐘(minutes),所以上面把session的生命週期設定為1分鐘。

在web.xml中設定session生命週期所影響的範圍是整個Container,也就是說Container所建立的每個session的生命週期都同樣是1分鐘。

 

第二種方法是在Servlet中使用session的setMaxInactiveInterval()方法...

...

和在web.xml中的差異是,這裡傳入的數字時間單位為秒(seconds),且影響範圍也僅於這個session物件。

這邊的設定會覆寫web.xml中的設定,也就是說若在web.xml設定的時間為1分鐘,但在這使用setMaxInactiveInterval()設定為30秒,則此session的生命週期為30秒。

另外上述兩種方法若提供的參數值為0,-1或其他負數,則session將永遠不會失效

 

以下示範session失效的範例,環境如下

  • Eclipse
  • jdk7
  • tomcat7

 

在Eclipse中建立動態網站專案(Dynamic Web Project)

專案目錄結構如下

 

 

web.xml...

...

 

index.jsp...

...

 

MyServlet_01.java...

...

 

MyServlet_02.java...

...

 

注意此範例的點選順序,應用程式啟動後送出一個request(localhost:8080/ServletSession_001/index.jsp)給Container,此時Container第1次收到此客戶端的請求,所以建立一個新的session,然後將session id放入response物件中與index.jsp一併回應給客戶端。注意此時Hello後面沒有任何字樣。

點擊index.jsp的MyServlet_01連結來發出請求給MyServlet_01.java。

這是Container第2次收到客戶端來的請求。

在MyServlet_01.java的doGet()中收到來自Container送來的request物件(裡面包著session物件的參照),使用request.getSession()取得session物件。

使用session的setMaxInactiveInterval()方法將session的失效時間設為30秒,也就是說,若Container在30秒內沒收到此session的客戶端的任何請求,則此session就會失效。

加入一個名稱為"name",值為"Phoebe"的屬性到session物件,然後將index.jsp回應給客戶端。

回到index.jsp,此時你可以看到Hello後面多了Phoebe的字樣,此Phoebe是使用JSP EL從剛剛的session物件取出。

我在index.jsp中寫了個小小的跳秒器以方便計時,也就是<script>中的部分,可以先不用理會。

 

此時進行的測試如下。

如果在30秒按MyServlet_02連結

則你會發現Hello後面的Phoebe仍舊存在。且在MyServlet_02的doGet()中也會在console印出"Phoebe"。

這是因為在按下MyServlet_02連結時,客戶端送弟3次請求過去,請求中包含了session id,Container收到請求後比對session id的紀錄,因為距離上一次請求還在30秒內,session仍然有效,接著Container將此session交給request物件,因此在MyServlet_02的doGet()中取得的session物件即為第1次請求的session物件。

 


 

 

但如果在30秒按MyServlet_02連結

則你會發現Hello後面的Phoebe消失了,且在MyServlet_02的doGet()中會在console印出"null"。

 

因為距離第上一次請求已經超過了30秒,Container收到第3次請求後比對session id,發現此session id所對應的session已經失效,因此重新建立一個新的session,然後交給request物件,因此在MyServlet_02的doGet()中取得的session是全新的session物件。由於是全新的session物件,所以和第上一次請求的session是不同的session物件,自然沒有在上一次請求時被加入的"name"屬性,所以session.getAttribute("name")回傳一個null,然後在console印出"null",返回index.jsp時Hello後面變回空白。

從上面的測試即可觀察出session失效的狀態。

 

 

 

 

 

 

 

 

文章標籤
創作者介紹

菲比傻大姐&肉豬

phoebelin0606 發表在 痞客邦 PIXNET 留言(0) 人氣()