HttpSession 的 invalidate() 方法介绍

By Li Jiangtao

At 2018-10-24 15:22:33 Shanghai


Catalog

  • Javadoc
  • Experiment
  • Summary
  • Thinking
  • Links

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

sense8-season-2

Links

  • Apache Tomcat - Interface HttpSession

  • Acoderanch - what does session invalidate means?

  • Atheserverside - Web tier: servlets, JSP, Web frameworks: Session.invalidate

  • Astackoverflow - Why session is not null after session.invalidate() in JAVA?

  • stackexchange - What is E-DEATH based on in Sense8?

你可能感兴趣的:(HttpSession 的 invalidate() 方法介绍)