07_Sessions

Sessions

超文本传输协议(HTTP)被设计为无状态协议。 要构建有效的Web应用程序,必须将来自特定客户端的请求相互关联。 随着时间的推移,会话跟踪的许多策略都在不断发展,但程序员直接使用它们都很困难或麻烦。

本规范定义了一个简单的HttpSession接口,该接口允许servlet容器使用多种方法中的任何一种来跟踪用户的会话,而不会使Application Developer陷入任何一种方法的细微差别。

1. session追踪机制

以下几节描述了追踪一个用户会话的方法。

1.1 Cookies

通过HTTP cookie进行会话跟踪是最常用的会话跟踪机制,要求被所有servlet容器支持。

容器向客户端发送一个cookie。 然后,客户端会将每个后续请求上的cookie返回给服务器,明确地将该请求与会话相关联。 会话跟踪cookie的标准名称必须是JSESSIONID.Containers可允许通过容器特定配置来定制会话跟踪cookie的名称。

所有servlet容器必须提供配置容器是否将会话跟踪cookie标记为HttpOnly的能力。 已建立的配置必须适用于尚未建立上下文特定配置的所有上下文(有关更多详细信息,请参阅SessionCookieConfig javadoc)。
如果Web应用程序为其会话跟踪cookie配置自定义名称,则如果会话ID在URL中进行了编码(前提是已启用URL重写),则同样的自定义名称也将用作URI参数的名称。

1.2 SSL会话

Secure Sockets Layer, the encryption technology used in the HTTPS protocol, has a built-in mechanism allowing multiple requests from a client to be unambiguously identified as being part of a session. A servlet container can easily use this data to define a session.
安全套接字层是HTTPS协议中使用的加密技术,它有一个内置的机制,可以允许客户机的多个请求被明确标识为会话的一部分。servlet容器可以很容易地使用这些数据来定义会话。

1.3 URL重写

URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.

The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.example.com/catalog/index.html;jsessionid=1234
URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML,and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable

URL重写是会话跟踪的最小公分母。当客户端不接受cookie时,URL重写可能被服务器用作会话跟踪的基础。URL重写涉及到将数据(一个会话ID)添加到由容器解释的URL路径,以将请求与会话关联起来。

会话ID必须编码为URL字符串中的路径参数。参数的名称必须是jsessionid。下面是一个包含编码路径信息的URL示例:

http://www.example.com/catalog/index.html;jsessionid = 1234

URL重写在日志、书签、引用标头、缓存的HTML和URL栏中公开会话标识符。URL重写不应该被用作一个会话跟踪机制,在这个机制中,cookie或SSL会话是受支持的和合适的。

1.4 会话的完整性

Web容器必须能够支持HTTP会话,同时为不支持使用cookie的客户端提供HTTP请求。为了满足这个需求,Web容器通常支持URL重写机制。

2.创建会话

,当会话只是一个预期的会话且尚未建立,那它会被认为是“新”的。因为HTTP是基于请求-响应的协议,所以在客户端“加入”之前HTTP会话被认为是新的。当会话跟踪信息被返回到服务器,表明已经建立了会话时,客户机加入会话。在客户机加入会话之前,不能假定客户机的下一个请求将被视为会话的一部分。

如果下列任何一项是正确的会话将被认为是“新”:

  • 客户还不了解会话
  • 客户选择不加入一个会话

这些条件定义了servlet容器没有将请求与之前的请求关联起来的机制的情况。

Servlet开发人员必须设计他的应用程序来处理客户端没有、不能或不会加入会话的情况。

与每个会话相关联,有一个包含一个独特的标识符的字符串,这被称为会话id。会话id的值可以通过调用javax.servlet.http.HttpSession.getId()获取,和创建后可以通过调用javax.servlet.http.HttpServletRequest.changeSessionId()改变。

3. session范围

HttpSession对象必须在应用程序(或servlet上下文)级别范围内。在底层机制,例如用于建立会话的cookie,对于不同的上下文可以是相同的,但是引用的对象,包括该对象中的属性,不能被容器在上下文之间共享。

要用一个例子来说明这一需求:如果一个servlet使用RequestDispatcher在另一个Web应用程序中调用servlet,那么为这个servlet创建并可见的任何会话都必须与调用servlet可见的会话不同。

此外,上下文的会话必须可被请求恢复到该上下文,而不管它们的关联上下文是否被直接访问或在创建会话时作为请求分派的目标。

4.绑定属性到Session

servlet可以通过名称将对象属性绑定到HttpSession实现。任何绑定到会话的对象都可用于属于同一个ServletContext的任何其他servlet,并处理被标识为同一会话的一部分的请求。

当某些对象被放置或从会话中删除时,可能需要通知。此信息可以通过对象实现HttpSessionBindingListener接口获得。该接口定义了以下方法,该方法将指示被绑定到的对象或从会话中释放的对象。

  • valueBound
  • valueUnbound

在通过HttpSession接口的getAttribute方法提供对象之前,必须调用valueBound方法。在对象不再可以通过HttpSession接口的getAttribute方法可达之后,必须调用valueUnbound方法。

5.会话超时

In the HTTP protocol, there is no explicit termination signal when a client is no longer active. This means that the only mechanism that can be used to indicate when a client is no longer active is a time out period.

The default time out period for sessions is defined by the servlet container and can be obtained via the getSessionTimeout method of the ServletContext interface or the getMaxInactiveInterval method of the HttpSession interface.

This time out can be changed by the Developer using the setSessionTimeout method of the ServletContext interface or the setMaxInactiveInterval method of the HttpSession interface. The time out periods used by session timeout methods are defined in minutes. The time out periods used by max active interval methods are defined in seconds. See the javadoc for setSessionTimeout for additional normative requirements. By definition, if the time out period for a session is set to 0 or lesser value, the session will never expire. The session invalidation will not take effect until all servlets using that session have exited the service method. Once the session invalidation is initiated, a new request must not be able to see that session.
在HTTP协议中,当客户端不再活动时,是没有显式的终止信号的。这意味着,唯一可以用来指示客户端不再活动的机制是超时时间。

会话的默认超时时间由servlet容器定义,可以通过ServletContext接口的getSessionTimeout方法或HttpSession接口的getMaxInactiveInterval方法获得。

这个时间可以由开发人员使用ServletContext接口的setSessionTimeout方法或HttpSession接口的setMaxInactiveInterval方法来更改。会话超时方法使用的超时时间定义为分钟。max activeinterval方法所使用的超时时间定义为秒。请参见javadoc以获得额外的规范需求。根据定义,如果会话的超时时间设置为0或更低的值,会话将不会过期。在使用该会话的所有servlet退出服务方法之前,会话将不会失效。一旦会话失效开始,新的请求就不能看到会话。

6. 最后访问时间

HttpSession接口的getLastAccessedTime方法允许servlet在当前请求之前确定会话上次访问的时间。当会话的一部分请求首先由servlet容器处理时,会话被认为是被访问的。

7. 重要的Session语义

7.1 线程问题

执行请求线程的多个servlet可以同时对同一个会话对象进行活动访问。容器必须确保对表示会话属性的内部数据结构的操作以线程安全的方式执行。开发人员负责线程安全访问属性对象本身。这将保护HttpSession对象内的属性集合不受并发访问,从而消除了应用程序导致该集合被破坏的机会。除非在规范的其他地方(例如第7.7.1节,在第7-67页的会话对象上的“线程问题”)中明确声明,否则从请求或响应中获得的对象必须被假定为非线程安全的。这包括,但不限于返回的PrintWriter ServletResponse.getWriter()和返回的OutputStream ServletResponse.getOutputStream()

7.2 分布式环境

在分布式的应用程序中,所有属于会话的请求必须一次由一个JVM处理。容器必须能够正确地使用setAttribute或putValue方法将所有放置到HttpSession类实例中的对象处理。为了满足这些条件,我们实施了以下限制:

  • 容器必须接受实现Serializable接口的对象。
  • 容器可以选择支持HttpSession中其他指定对象的存储,例如对Enterprise JavaBeans组件和事务的引用。
  • 迁移会话将由特定容器设施处理。

当分布式 servlet 容器不支持必需的会话迁移存储对象机制时容器必须抛出 IllegalArgumentException。

分布式 servlet 容器必须支持迁移的对象实现 Serializable 的必要机制。

这些限制意味着开发人员可以确保在非分布式容器中不存在其他并发性问题。

容器提供程序可以通过将会话对象及其内容(从分布式系统的任何活动节点)移动到系统的不同节点,从而确保负载均衡和故障转移等服务特性的可伸缩性和质量。

如果分布式容器持久化或迁移会话以提供服务特性的质量,它们并不局限于使用本机JVM序列化机制来序列化httpsession及其属性。开发人员不能保证容器会在会话属性上调用readObject和writeObject方法,如果他们实现了这些方法,但保证它们的属性的可序列化闭包将被保留。

容器必须在迁移会话期间通知任何实现HttpSessionActivationListener的会话属性。它们必须在会话序列化之前通知侦听器,并在会话反序列化之后激活。编写分布式应用程序的应用程序开发人员应该意识到,由于容器可能在多个Java虚拟机中运行,因此开发人员不能依赖静态变量来存储应用程序状态。它们应该使用企业bean或数据库存储这些状态。

7.3 客户端语义

Due to the fact that cookies or SSL certificates are typically controlled by the Web browser process and are not associated with any particular window of the browser,requests from all windows of a client application to a servlet container might be part of the same session. For maximum portability, the Developer should always assume that all windows of a client are participating in the same session.
由于cookie或SSL证书通常由Web浏览器进程控制,且不与浏览器的任何特定窗口相关联,所以从客户机应用程序的所有窗口向servlet容器请求可能是同一会话的一部分。为了获得最大的可移植性,开发人员应该始终假设客户的所有窗口都参与了相同的会话。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容