您的位置:首页 > 理论基础 > 计算机网络

[Servlet]使用HttpSession进行会话管理

2015-11-04 22:15 363 查看
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. 示例:

...
<web-app>
...
<session-config>
<session-timeout>30</session-timeout>
</session-config>
...
</web-app>
...
!!!这里设置的是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. 示例:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>SID</name>
<max-age>5000</max-age>
</cookie-config>
</session-config>
4) 使Session对象立即无效(Web容器会立即销毁该对象并回收其内存空间):void invalidate();

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

!!这就相当于C++中手动调用析构函数;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: