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
吧......