在Web开发环境下,session是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构,比如说把某某信息存储在session中。

session机制

  • 服务器使用一种类似于散列表的结构来保存信息。
  • 当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识
  • 如果已经包含则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用;如果检索不到(服务端已经删除了该用户对应的session对象),可能会新建一个
  • 如果客户请求不包含sessionId,则为此客户创建一个session并且生成一个与此session相关联的sessionId,这个session id将在本次响应中返回给客户端保存。

保存session id的几种方式

  • 保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
  • 由于cookie可以被人为的禁用,必须有其它的机制以便在cookie被禁用时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。

Session cookie

  • session通过SessionID来区分不同的客户, session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,这称之为session cookie,以区别persistent cookies(也就是我们通常所说的cookie),session cookie是存储于浏览器内存中的,并不是写到硬盘上的,通常看不到JSESSIONID,但是当把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,这时地址栏看到session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本。
  • 关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的persistent cookie消失。
  • 关闭浏览器,客户端session id消失,服务器端session有存在的必要吗?答案见session超时管理。

Session的创建与删除

  • 一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用 HttpServletRequest.getSession(true) 这样的语句时才会被创建。
  • session在下列情况下被删除:
    A.程序调用 HttpSession.invalidate() B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
    C.服务器进程被停止

两个浏览器窗口访问应用程序会使用同一个session

  • 通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的session id,这样信息共享的目的就达不到了。
    * 这里的新窗口是指 一个浏览器新的标签页吗???
  • 此时可以先把session id保存在persistent cookie中(通过设置cookie的最大有效时间),然后在新窗口中读出来,就可以得到上一个窗口的session id了,这样通过session cookie和persistent cookie的结合就可以实现了跨窗口的会话跟踪。
    * 是不是说关闭浏览器session id消失是由于cookie有效期过小的原因?如果设置大一些也变成persistent cookie了?

Session的超时管理

  • WEB服务器无法判断当前的客户端浏览器是否还会继续访问,也无法检测客户端浏览器是否关闭,所以,即使客户已经离开或关闭了浏览器,WEB服务器还要保留与之对应的HttpSession对象。
  • 随着时间的推移而不断增加新的访问客户端,WEB服务器内存中将会因此积累起大量的不再被使用的HttpSession对象,并将最终导致服务器内存耗尽。
  • WEB服务器采用超时限制的办法来判断客户端是否还在继续访问,如果某个客户端在一定的时间之内没有发出后续请求,WEB服务器则认为客户端已经停止了活动,结束与该客户端的会话并将与之对应的HttpSession对象变成垃圾。
  • 如果客户端浏览器超时后再次发出访问请求,WEB服务器则认为这是一个新的会话的开始,将为之创建新的HttpSession对象和分配新的会话标识号。
    会话的超时间隔可以在web.xml文件中设置,其默认值由Servlet容器定义。
<session-config> 
  <session-timeout>30</session-timeout> 
</session-config>