正确理解session:使用HttpSession进行会话管理




1. Session模型:

    1) HTTP协议是无状态的,无法记录多次请求/响应之间的联系,而Session模型就好比一个中间人,可以帮助使用HTTP协议通信的双方记录每次通信的内容(即会话的内容),因此Session模型就是一种中间人模型,可以保存通信记录;

    2) HttpSession对Session模型的实现:

         i. 当客户端第一次请求服务器时服务器可以主动建立一个HttpSession对象专门用于记录该客户端和自己这一次,包括今后将要发生的多次,通信记录,建立HttpSession就是建立会话,这种会话(会话对象)可以长期保存;

         ii. Web容器会为每个会话分配一个唯一的ID号,容器会将相关通信记录都保存在相应ID的会话对象中,并可以将这些会话对象长期保存在Web容器中(服务器端);

         iii. 而Servlet响应客户端时只需要将相应会话的ID保存在Cookie中返回即可,而浏览器下次再请求时只需要凭Cookie中的会话对象的ID让Web容器调出保存在其中的会话对象即可;

    3) 大致模型就是:

客户端(Cookie:Session ID) <====>   服务器端(很多Session对象)

!服务器根据客户端请求Cookie中的Session ID调出保存在Web容器中相应的Session对象,然后取出对象中保存的前几次通信的记录并利用!


2. 使用HttpSession的基本流程:

   1) 建立或获取Session对象要使用HttpServletRequest的getSession函数:

        i. HttpSession HttpServletRequest.getSession(); // 如果通信双方建立过会话则返回之前保存在Web容器中的会话,否则就建立一个新的会话

        ii. HttpSession HttpServletRequest.getSession(boolean create); // true就和getSession等价,而false在没有建立过会话的条件下返回null,否则返回相应的会话

        !!通常使用前者较多;

    2) 插入和提取会话记录:

         i. 插入会话记录使用HttpSession的setAttribute,提取会话记录使用getAttribute,用法和HttpServletRequest的setAttribute和getAttribute一模一样,会话记录也是以“键值对”的形式保存;

         ii. Object HttpSession.getAttribute(String name);  // 提取相应参数名的对象

         iii. void HttpSession.setAttribute(String name, Object value);  // 设置键值对

!!会话记录都是以类对象的形式保存的,提取出来需要类型转换一下才能放心使用;


2. 会话模型的具体实现:

    1) 在建立Session的时候Web容器会为每个Session分配一个唯一的ID号,因此一个HttpSession对象中保存有ID号和各个键值对(会话记录);

    2) Session对象都保存在Web容器中;

    3) 在响应客户端时Web容器会自动把本次通信的Session的ID加入到Cookie中返回给客户端,其在set-cookie标头中的参数名为JSESSIONID(在Tomcat中是这样),例如:set-cookie: k1=v1; k2=v2…JSESSIONID=C8D2S02LA23…kn=vn….

    4) 客户端和服务器端通信只传送Session的ID而不传送Session中的通信记录,当服务器端收到客户端请求并调用getSession时,就会根据请求Cookie中的Session ID从Web容器缓存中调出相应的Session对象,这样通信时就能节省很多容量资源,加大网络流量的利用率同时提高效率,只不过通信记录都是保存在服务器端的,因此服务器端的存储压力较大;


3. HttpSession的常用方法以及配置:

    1) 获取Session的ID:String getId();

    2) 设置Session的存活期限:void setMaxInactiveInterval(int interval);  // 设置请求间隔时间(单位是秒),当浏览器超出interval秒还没有请求该应用的话就清除该Session(释放内存)

!!如果interval为0或负则表示Session可以无限存活(除非关闭Web容器);

!!由于用服务器来保存通信记录是非常消耗内存资源的,因此建议不要将大型对象保存在Session中,如果Session中的对象较大那么设置存活期限就相当必要,否则会导致内存不足降低服务效率;

    3) 在web.xml中配置Session的默认存活时间:如果没有调用setMaxInactiveInterval则使用web.xml中的默认值,否则就使用程序中设置的值

         i. 所有关于Session的配置都放在<web-app>的<session-config>中;

         ii. 存活时间的配置标签是<session-timeout>,但是单位是分钟!!!和set函数单位是秒不一样,千万别搞错了!!

         iii. 示例:


 
 
  1. ...
  2. <web-app>
  3. ...
  4. <session-config>
  5. <session-timeout>30 </session-timeout>
  6. </session-config>
  7. ...
  8. </web-app>
  9. ...
!!!这里设置的是30分钟而不是30秒;

    3) Session ID的Cookie配置:

         i. 默认情况下,Web容器自动为Session建立的传送ID的Cookie的max-age(Cookie存活时长)为“退出时长”,“退出时常”是指Cookie的存活时间为从创建到浏览器关闭那么久,一旦浏览器退出那么该Cookie就会被清除,不会保存到下次浏览器打开;

         ii. 因此在默认情况下,浏览器退出再打开后再次请求该网站,那么请求Cookie中就没有Session ID的信息了,那么服务器端使用getSession时就没有ID可以查找,那么此时就会创建一个新的Session,因此之前的通信记录就无法再获取了,即使记录前几次通信记录的Session对象还可能存活在Web容器的缓存中,但是由于调出该对象的请求不复存在了,因此该Session也只能深埋在缓存中直到达到存活期限被销毁;

         iii. 所以我们希望修改Session ID的Cookie的存活时间,关于Session ID的Cookie的配置可以在web.xml中进行:

              a. 在<session-config>标签下的<cookie-config>中配置即可;

              b. <name>标签可以设置Cookie的名称,可以将默认的JSESSIONID的名称改成其它你想要的;

              c. <max-age>标签可以修改Cookie的存活时间,单位为秒;

              d. 示例:


 
 
  1. <session-config>
  2. <session-timeout>30 </session-timeout>
  3. <cookie-config>
  4. <name>SID </name>
  5. <max-age>5000 </max-age>
  6. </cookie-config>
  7. </session-config>
    4) 使Session对象立即无效(Web容器会立即销毁该对象并回收其内存空间):void invalidate();

!!调用后不得在使用其它函数获取、修改Session中的信息,因为其空间已经被回收了,更不能再次invalidate,因为此时引用已经和对象脱钩,如果发生以上任何一种行为都会引发指针异常并抛出IllegalStateException异常;

!!这就相当于C++中手动调用析构函数;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值