By Li Jiangtao
At 2018-10-24 15:22:33 Shanghai
Catalog
Javadoc
/**
* Invalidates this session then unbinds any objects bound
* to it.
*
* @exception IllegalStateException if this method is called on an
* already invalidated session
*/
public void invalidate();
從javadoc來看,某Session對象調用該方法以後會做兩件事情:
-
使該Session無效
-
將該Session綁定的對象全部解綁
Experiment
上面兩條:使Session無效和解綁綁定的對象,可能讓你聽得一頭霧水。
下面我們就做個小實驗,看下執行invalidate() 方法會發生些什麼。
在Controller中,利用參數中的HttpServletRequest
執行如下代碼:
HttpSession session=request.getSession();
session.setAttribute("tao", "good boy");
System.out.println("before invalidate:"+session.getId()+"-"+session.getAttribute("tao"));
session.invalidate();
System.out.println("after invalidate:"+session.getId());
HttpSession s1=request.getSession(false);
System.out.println("s1:"+s1);
HttpSession s2=request.getSession(true);
System.out.println("s2 id:"+s2.getId());
HttpSession s3=request.getSession();
System.out.println("s3 id:"+s3.getId());
HttpSession s4=request.getSession(false);
System.out.println("s4 id:"+s4.getId());
//session.getAttribute("tao");
//session.setAttribute("tao", "good boy");
控制檯輸出的內容如下:
before invalidate:h7p0lnh08fe415ro1o43lwl4w-good boy
after invalidate:h7p0lnh08fe415ro1o43lwl4w
s1:null
s2 id:ztx2uk2776612wbzjt9wo30d
s3 id:ztx2uk2776612wbzjt9wo30d
s4 id:ztx2uk2776612wbzjt9wo30d
如果此時利用原來的session
對象再次執行session.getAttribute("tao")
或者session.setAttribute("tao", "good boy")
,會拋出如下異常:
Caused by: java.lang.IllegalStateException
at org.eclipse.jetty.server.session.AbstractSession.checkValid(AbstractSession.java:106)
at org.eclipse.jetty.server.session.HashedSession.checkValid(HashedSession.java:79)
at org.eclipse.jetty.server.session.AbstractSession.getAttribute(AbstractSession.java:459)
Summary
結合 invalidate()
方法的javadoc,再通過上面的實驗,我們可以對invalidate()
方法的作用歸結如下:
-
調用
invalidate()
方法會使該Session無效,無效只是不能調用setAttribute
或者getAttribute
之類的方法了,Session對象還在; -
調用過
invalidate()
方法的Session對象如果再執行setAttribute
或者getAttribute
方法會拋出IllegalStateException
; -
調用
invalidate()
方法會將該Session綁定的對象全部解綁,因此如果調用request.getSession(false)
方法,返回值會是null——即此時request沒有綁定任何Session; -
如果調用
invalidate()
方法後執行request.getSession()
或者request.getSession(true)
,那麼此時會創建一個新的Session給該Request對象綁定;需要特殊說明的是,getSession()
無參和參數爲true的效果是一樣的,並且此時如果你再次執行request.getSession(false)
方法,返回的就不是null了,而是上面新創建的Session對象。
Thinking
通過上面的介紹,你應該對invalidate()
方法的作用已經瞭如指掌了,那麼接下來的問題是:什麼時候需要調用這個方法呢?
最常見的地方是退出登錄,因爲一般情況下當用戶退出登錄以後,爲了保證登陸後產生的數據在退出以後不會因非法獲取到SessionId而泄露,就要通過invalidate()
方法來解綁該Session綁定的所有數據。
雖然通過session.removeAttribute("tao")
也可以刪除存在Session中的屬性,但與SessionId綁定的相關的瀏覽記錄還可能在客戶端保存着,另外,removeAttribute難免有漏網之魚而且也不優雅。
好比方說,一個人幹了一件壞事,也許可以通過銷燬證據來掩蓋真相,當這個人作惡多端、臭名遠揚的時候,只好換個身份過活了。
今天我們生活在一個萬物互聯的時代,即使不上網,走在路上,每天可能會被監控拍到幾十次,如果我們想在這個互聯網時代退出登錄
還有可能嗎?
以前看美劇超感獵殺(Sense8)
,黑客女主人公(變性之前是小帥哥)爲了躲避警方的通緝,選擇了E-Death。
也許只有我們每個人都可以選擇E-DEATH的時候,才能真正的在這個互聯時代invalidate
吧…