编程届控制师:Cookie和Session两种会话技术分享( 二 )


  1. Session也是域对象之一,它的范围是在一个会话范围内有效 。Session既然是域对象,那么当然就要有getAttribute()和setAttribute()系列方法了 。
  2. 在一个会话内共享一个Session对象,所以Session中可以保存一个会话内的数据 。例如当前用户的信息 。
  3. Session的范围大于request,可以在一个会话中多个请求之间共享数据 。但Session的范围小于Application,Session不能在多个用户之间共享数据 。
1.获取Session对象
使用request.getSession()方法就可以获取Session对象 。有了Session,就不用使用Cookie来跟踪会话了!但是Session不能像Cookie那样长命,一旦用户关闭浏览器窗口,那么Session就死掉了 。
2.Session的实现原理
我们都知道HTTP是无状态协议,但是为什么session可以跟踪会话状态呢?因为,session依赖Cookie 。利用cookie回写了一个JSESSIONID(JESSIONID就是为每个seesion起一个唯一的标识)
类似于银行卡,卡上只有一个ID,其他什么都没有,表示金额的这个数据在银行的数据库里 。那为什么在ATM上我们只需要把卡插入就可以看到卡上余额呢?原因是ATM获取卡上的ID,然后通过ID去银行数据库中查找对应的账户!每个账户都有一个ID属性,账户上可能还会有密码属性、余额属性等 。每张卡上只有一个ID,再没有其他的东西了 。但ATM可以读取卡上的ID,然后去银行数据库中查找对应的账户!所以你大可以放心,银行卡坏掉了没有关系,钱不会掉的,因为账户余额在银行的数据库中,你只需要重新去银行办一张卡,把你的卡号置入到新卡中就OK了 。
每个session对象都有一个id属性,session就相当于银行的账户 。而sessionId就相当于卡!银行数据库就是Tomcat服务器,而手里只有卡的我们就是客户端浏览器 。
当你第一次去银行办理业务时,这需要办一张卡,然后你需要拿着卡回家,下一次再去银行办理业务时就不需要再办卡了,但你不要忘记带着卡去银行 。
当客户端第一次访问服务器时,服务器会为客户端创建一个session对象,然后把session对象放到session池中,在响应时把sessionId通过Cookie响应给客户端 。注意,只有在第一次访问时,服务器才会创建session,给客户端响应sessionId 。从此以后就不会了!
当客户端再次访问服务器时,会在请求中带着sessionId给服务器,服务器通过sessionId到session池中找到session对象,这就可以完成会话跟踪了 。也就是说,服务器端保存的是session对象,而客户端只有sessionId 。每次访问都需要通过客户端的sessionId来匹配服务器端的session对象!这样用户在session中保存的数据就可以再次被使用了 。
sessionId是服务器通过Cookie发送给客户端浏览器的,这个Cookie的maxAge为-1,即只在浏览器内存中存在 。如果你关闭所有浏览器窗口,那么这个Cookie就会消失了!
3.Session失效
Session失效有如下几个原因:
  1. 客户端的请求中没有sessionId 。可能是因为这是第一次请求(开始一个新的会话),也可能是服务器设置Cookie的maxAge为0导致的;(客户端没有银行卡)
  2. 客户端请求中存在sessionId,但这个sessionId在session池中没有匹配的session对象 。这可能是因为session太久没有使用,服务器把session从池中移除的原因;(银行卡没有对应的银行账户)
  3. ?客户端请求中存在sessionId,但匹配的session对象被标记为失效!这可能是因为服务器调用了session.invalidate()方法导致的 。(银行账户找到了,但账户已被冻结)
4.与session相关的方法
String getId():获取sessionId;
int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟 。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
void invalidate():让session失效,调用这个方法会让session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
boolean isNew():查看session是否为新 。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新 。


推荐阅读