session:
一般译作会话,从不同层面看待session,它有着类似但不全然相同的含义。如:从web应用的用户看来,他打开浏览器访问一个电子商务网站,登录、并完成购物直到关闭浏览器,这是一个会话。而在web应用开发者看来,用户登录时我需要创建数据结构以存储用户的登录信息,这个结构也叫作session。因此在谈论session的时候要注意上下文环境。
session一般是在web应用的背景之下,我们知道web应用是基于HTTP协议的,而HTTP协议恰恰是一种无状态协议。也就是说,用户从A页面跳转到B页面会重新发送一次HTTP请求,而服务端在返回响应的时候是无法获知该用户在请求B页面之前做了什么的。
session是有状态的,而HTTP协议是无状态的。
解决HTTP协议自身无状态的方式有cookie和session。二者都能记录状态,前者是将状态数据保存在客户端,后者则是保存在服务端。
cookie:每个客户端最多保持是三百个cookie,每个域名下最多20个cookie(实际上一般浏览器现在逗比这个多,如Firefox是50个),而每个cookie的大小为最多4k,不过不同浏览器都有各自的实现。对于cookie的使用,最重要的就是要空着cookie的大小,不要放入无用的信息,也不要放入过多的信息。
不论使用何种服务端技术,只要发送回的HTTP响应中包含如下形式的头,则视为服务器要求设置一个cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain
session:它的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的表示来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session,创建session可以概括为三个步骤:
1.生成全局唯一的标识符(sessionid);
2.开辟数据存储空间。一般会在内存中创建响应的数据结构,但这种情况下,系统一旦停电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这项虽然会增加I/O开销,但是session可以实现某种程度的持久化,而且更有利于session共享;
3.将session的全局唯一标识符发送个客户端。
问题的关键就在服务端如何发送这个session的唯一标识符上。联系到HTTP协议,数据无非可以放到请求行、头域或Body里,基于此,一般来说会有两种常用的方式:cookie和URL重写。
4.cookie
服务端只要设置set-cookie头就可以将session的标识符传送到客户端,而客户端此后的每一次请求都会带上这个标识符,由于cookie可以设置失效时间,所以一般包含session信息的cookie会设置失效时间为0,即浏览器进程有效时间。至于浏览器怎么处理这个0,每个款浏览器都有自己的方案,但差别都不会太大(一般体现在新建浏览器窗口的时候);
5.URL重写
多为URL重写,顾名思义就是重写URL。试想,在返回用户请求的页面之前,将页面所有的URL后面全部以get参数的方式加上session标识符(或者加在path info部分等等),这样用户在收到响应之后,无论点击哪个链接或提交表单,都会再带上这个session标识符,从而就实现了会话的保持。
session原理: 首先浏览器请求服务器访问web站点时,程序需要为客户端的请求创建一个session的时候,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session并且生成一个与此session相关联的session id,sessionid 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将在本次响应中返回到客户端保存,保存这个sessionid的方式就可以是cookie,这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionid就可以找得到对应的session,又回到了这段文字的开始。
session的有效期:
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。
Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。
session的常用方法:
方法名 | 描述 |
void setAttribute(String attribute, Object value) | 设置Session属性。value参数可以为任何Java Object。通常为Java Bean。value信息不宜过大 |
String getAttribute(String attribute) | 返回Session属性 |
Enumeration getAttributeNames() | 返回Session中存在的属性名 |
void removeAttribute(String attribute) | 移除Session属性 |
String getId() | 返回Session的ID。该ID由服务器自动创建,不会重复 |
long getCreationTime() | 返回Session的创建日期。返回类型为long,常被转化为Date类型,例如:Date createTime = new Date(session.get CreationTime()) |
long getLastAccessedTime() | 返回Session的最后活跃时间。返回类型为long |
int getMaxInactiveInterval() | 返回Session的超时时间。单位为秒。超过该时间没有访问,服务器认为该Session失效 |
void setMaxInactiveInterval(int second) | 设置Session的超时时间。单位为秒 |
boolean isNew() | 返回该Session是否是新创建的 |
void invalidate() | 使该Session失效 |