HttpSession 的 invalidate() 方法介紹

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對象調用該方法以後會做兩件事情:

  1. 使該Session無效

  2. 將該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()方法的作用歸結如下:

  1. 調用invalidate() 方法會使該Session無效,無效只是不能調用setAttribute或者getAttribute之類的方法了,Session對象還在;

  2. 調用過invalidate()方法的Session對象如果再執行setAttribute或者getAttribute方法會拋出IllegalStateException

  3. 調用invalidate() 方法會將該Session綁定的對象全部解綁,因此如果調用request.getSession(false)方法,返回值會是null——即此時request沒有綁定任何Session;

  4. 如果調用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吧…

在這裏插入圖片描述


Links

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章