Servlet——理解会话Session

 

1.什么是会话(Session)

超文本传输协议(HTTP)被设计成一种无状态的协议。

所谓无状态协议就是指在服务器端的请求彼此相互之间是不认识彼此的,哪怕是来自同一个客户端的请求,相互之间也是不认识的,这个就叫做无状态

但要构建复杂的Web应用程序,就必须能够将来自同一个客户端的请求彼此关联起来。比如我们最常见的信息管理系统,一般要求用户先登录,后进行相关操作,而仅仅通过无状态协议实现这个功能是非常麻烦,而且不安全的。

由于请求彼此之间相互不认识,因此尝试修改用户信息的请求无法依赖于登录认证的请求所提供的身份认证信息,而只能每次在请求时自己携带登录信息,这样会造成额外的数据负担,并且非常不安全。

因此,需要有一种机制,能够让来自同一个客户端的请求彼此之间能够认识,这种机制被称为会话。

2.会话的实现
会话的实现分为两个部分,首先是要让来自同一个客户端的请求能够彼此相互认识;其次是来自同一个客户端的请求能够在服务器端共享数据。为什么这么说?

让每个来自客户端的请求携带一个口令,来自同一个客户端的请求可能能够获取到相同的口令,这样来自同一个客户端的请求就能够彼此认识。之后请求可以利用这个口令在服务器端存储一些数据,其他请求可以利用口令来读写这些数据。这个就是会话实现的一个基本思路。

3.会话追踪机制(Session Tracking Mechanisms)

要给每个请求设置一个Token,来追踪请求属于哪个会话,被称为会话追踪。目前形成了几种不同的会话追踪策略,但是对于应用程序开发者来说,这些策略直接使用起来都比较麻烦。一般是有应用程序服务器所提供的实现。比如遵循Servlet 规范的Tomcat。

3.1.Cookie
通过HTTP Cookie技术进行会话追踪是最常用的会话追踪机制,也是所有的Servlet容器都必须支持的方式。

容器会发送一个cookie到客户端。然后客户端每次发送一个到服务器的请求时,都会带上这个cookie,这样就能够将这些请求关联到一个会话。

3.2.URL重写(URL Rewriting)
URL重写是使用范围最小的一种会话追踪机制。如果一个客户端不接收cookie,服务器可以使用URL重写来进行会话追踪。URL重写将一个会话ID拼接到URL中。

比如:http://www.myhost.com/oolong/index;jessionid=12345

因为URL重写技术会在多处暴露Session ID,因此如果可能的话,就尽量不使用URL重写技术。

3.3.隐藏表单
通过上面的两个例子,应该能够明白了所谓的会话追踪技术,实际上就是实现一种方式,能够确保客户端在请求服务器端时,能够携带一个身份认证的标志。

因此自然而然的隐藏表单也能够实现这种功能,因此也可以算是一种会话追踪方式。思路就是每个页面上存在一个隐藏表单,这个表单中存放着从服务器端获取的SESSION ID,每次提交请求时,将这个表单中的ID也一起发送到服务器。具体实现方式此处不表。

4.会话的创建
当来自一个客户端的请求首次访问一个应用程序时,是没有SESSION ID的,也就是没有Token,此时服务器会为这个请求创建一个SESSION ID,并且在服务器段开辟一块空间作为这个会话所共享的数据存储区域。

然后当这个请求返回时,会将服务器端创建的这个SESSION ID一起带回客户端,之后每次来自这个客户端的请求,都会携带者这个SESSION ID

5.在会话中绑定值
会话最常用的一个功能是用来做用户登录来自同一个客户端的请求使用一个被称为SESSION ID的Token在服务器端存储一些共享数据。同一个客户端的不同请求因为拥有相同的SESSION ID,因此能够共享属于这个客户端的会话空间,也就能够在里面读写数据。这个被称为在会话中绑定值

 

6.会话超时(Session Timeouts)
由于每个客户端在访问服务器端时都会占用服务器端一定的系统资源,而服务器端的系统资源是有限的,为了提高利用效率,因此服务器端针对每一个会话的共享空间是有一定的时效性的。超过这个时间,服务器端会自动将这个会话在服务器中所占用的系统资源释放掉,换而言之,这个会话中的数据丢失,会话失效了。

这个会话超时时间是可以设置的,相关的有一些机制可以更智能的计算合理的会话时间,就不在此表述了。

 

参考

[1] JSR-000340 Java Servlet 3.1 Specification

posted @ 2016-12-27 16:54  大肥肥就是我  阅读(626)  评论(1编辑  收藏  举报