`

session生命周期2

 
阅读更多

session生命周期
2010-06-03 11:31

Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。

Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。

Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。

 


由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(long interval)修改。

Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。


Session中包括各种方法,使用起来要比Cookie方便得多。Session的常用方法如表5.2所示。

表5.2 HttpSession的常用方法

方 法 名
描    述

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.getCreationTime())

long getLastAccessedTime() 返回Session的最后活跃时间。返回类型为long

int getMaxInactiveInterval() 返回Session的超时时间。单位为秒。超过该时间没有访问,服务器认为该Session失效

void setMaxInactiveInterval(int second) 设置Session的超时时间。单位为秒

void putValue(String attribute, Object value)
不推荐的方法。已经被setAttribute(String attribute, Object Value)替代

Object getValue(String attribute) 不被推荐的方法。已经被getAttribute(String attr)替代

boolean isNew() 返回该Session是否是新创建的

void invalidate() 使该Session失效


Tomcat中Session的默认超时时间为20分钟。通过setMaxInactiveInterval(int seconds)修改超时时间。可以修改web.xml改变Session的默认超时时间。例如修改为60分钟:

<session-config>    
<session-timeout>60</session-timeout>       <!-- 单位:分钟 -->
</session-config>
注意:<session-timeout>参数的单位为分钟,而setMaxInactiveInterval(int s)单位为秒。

 

Session对浏览器的要求

虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。

该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。

注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择"在新窗口中打开"时,子窗口便可以访问父窗口的Session。

如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。

 

URL地址重写

URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,例如:

<td>      <a href="<%= response.encodeURL("index.jsp?c=1&wd=Java") %>">       Homepage</a> </td> 该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。重写后的输出可能是这样的:

<td>      <a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=       1&wd=Java">Homepage</a> </td> 即在文件名的后面,在URL参数的前面添加了字符串";jsessionid=XXX"。其中XXX为Session的id。分析一下可以知道,增添的jsessionid字符串既不会影响请求的文件名,也不会影响提交的地址栏参数。用户单击这个链接的时候会把Session的id通过URL提交到服务器上,服务器通过解析URL地址获得Session的id。

如果是页面重定向(Redirection),URL地址重写可以这样写:

<%      if("administrator".equals(userName)){          response.sendRedirect(response.encodeRedirectURL("administrator.jsp"));          return;      } %> 效果跟response.encodeURL(String url)是一样的:如果客户端支持Cookie,生成原URL地址,如果不支持Cookie,传回重写后的带有jsessionid字符串的地址。

对于WAP程序,由于大部分的手机浏览器都不支持Cookie,WAP程序都会采用URL地址重写来跟踪用户会话。比如用友集团的移动商街等。

注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。


Session中禁止使用Cookie

既然WAP上大部分的客户浏览器都不支持Cookie,索性禁止Session使用Cookie,统一使用URL地址重写会更好一些。Java Web规范支持通过配置的方式禁用Cookie。下面举例说一下怎样通过配置禁止使用Cookie。

打开项目sessionWeb的WebRoot目录下的META-INF文件夹(跟WEB-INF文件夹同级,如果没有则创建),打开context.xml(如果没有则创建),编辑内容如下:

代码5.11 /META-INF/context.xml

<?xml version='1.0' encoding='UTF-8'?> <Context path="/sessionWeb" cookies="false"> </Context> 或者修改Tomcat全局的conf/context.xml,修改内容如下:

代码5.12 context.xml

<!-- The contents of this file will be loadedfor each web application --> <Context cookies="false">      <!-- ... 中间代码略 --> </Context> 部署后TOMCAT便不会自动生成名JSESSIONID的Cookie,Session也不会以Cookie为识别标志,而仅仅以重写后的URL地址为识别标志了。

注意:该配置只是禁止Session使用Cookie作为识别标志,并不能阻止其他的Cookie读写。也就是说服务器不会自动维护名为JSESSIONID的Cookie了,但是程序中仍然可以读写其他的Cookie。


Session与Cookie的比较

Cookie与Session都可以进行会话跟踪,但是实现的原理不太一样。一般情况下二者均可以满足需求,但有时候不可以使用Cookie,有时候不可以使用Session。下面通过比较说明二者的特点以及适用的场合。

5.3.1 从存取方式上比较

Cookie中只能保存ASCII字符串,如果需要存取Unicode字符或者二进制数据,需要进行UTF-8,GBK或者BASE64等方式的编码。Cookie中也不能直接存取Java对象。若要存储稍微复杂的信息,使用Cookie是比较困难的。

而Session中可以存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也可以直接保存Java Bean乃至任何Java类,对象等,使用起来非常方便。可以把Session看做是一个Java容器类。

从隐私安全上比较

Cookie存储在客户端浏览器中,对客户端是可见的,客户端的一些程序可能会窥探、复制甚至修改Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的危险。

如果选用Cookie,比较好的办法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只有自己能读得懂。而如果选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以。


从有效期上比较

使用过Google的人都知道,如果登录过Google,则Google的登录消息长期有效。用户不必每次访问都重新登录,Google会长久地记录该用户的登录信息。要达到这种效果,使用Cookie会是比较好的选择。只需要设置Cookie的maxAge属性为一个很大很大的数字或者Integer.MAX_VALUE就可以了。Cookie的maxAge属性支持这样的效果。

使用Session理论上也能实现这种效果。只要调用方法setMaxInactiveInterval(Integer. MAX_VALUE)不就可以了么。但是由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的maxAge默认为-1,只要关闭了浏览器该Session就会失效,因此Session不能实现信息永久有效的效果。使用URL地址重写也不能实现。

而且如果设置Session的超时时间过长,服务器累计的Session就会越多,越容易导致内存溢出。


从对服务器的负担上比较

Session是保存在服务器端的,每个用户都会产生一个Session。如果并发访问的用户非常多,会产生非常多的Session,消耗大量的内存。因此像Google、Baidu、Sina这样并发访问量极高的网站,是不太可能使用Session来追踪客户会话的。

而Cookie保存在客户端,不占用服务器资源。如果并发浏览的用户非常多,Cookie是很好的选择。对于Google、Baidu、Sina来说,Cookie也许是唯一的选择。

 

从浏览器支持上比较

Cookie是需要客户端浏览器支持的。如果客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。对于WAP上的应用,常规的Cookie就派不上用场了。

如果客户端浏览器不支持Cookie,需要使用Session以及URL地址重写。需要注意的是所有的用到Session程序的URL都要使用response.encodeURL(String URL)或者response.encodeRedirectURL(String URL)进行URL地址重写,否则导致Session会话跟踪失败。对于WAP应用来说,Session+URL地址重写也许是它唯一的选择。

如果客户端支持Cookie,则Cookie既可以设为本浏览器窗口以及子窗口内有效(把maxAge设为-1),也可以设为所有浏览器窗口内有效(把maxAge设为某个大于0的整数)。但Session只能在本浏览器窗口以及其子窗口内有效。如果两个浏览器窗口互不相干,它们将使用两个不同的Session。


从跨域名上比较

Cookie支持跨域名访问,例如将domain属性设置为".helloweenvsfei.com",则以".helloweenvsfei.com"为后缀的所有域名均可以访问该Cookie。跨域名Cookie现在被广泛用在网络中,例如Google、Baidu、Sina等。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。

注意:仅使用Cookie或者仅使用Session可能实现不了理想的效果。这时应该尝试一下同时使用Cookie与Session。Cookie与Session的搭配使用在实际项目中会实现绚烂多姿的效果。


本章小结

Cookie是早期的会话跟踪技术,它将信息保存到客户端浏览器中。浏览器访问网站时会携带这些Cookie信息,达到鉴别身份的目的。

Session是在Cookie基础上建立的会话跟踪技术,它将信息保存在服务器端,Session中能够存储负责的Java对象,因此使用更加方便。Session依赖于名为JSESSIONID的Cookie。

如果客户端浏览器不支持Cookie,或者禁用了Cookie,仍然可以通过使用URL地址重写来使用Session。

分享到:
评论

相关推荐

    session生命周期的设置

    Session生命周期的设置是管理用户会话的关键环节,它决定了一个Session对象从创建到失效的时间间隔。本篇将深入探讨Session的工作原理、生命周期以及如何进行有效设置。 一、Session的工作原理 Session的工作基于...

    hibernate session生命周期示例

    本示例将深入探讨Hibernate Session的生命周期及其使用,帮助你更好地理解和运用这个强大的工具。 Hibernate Session是Hibernate的核心接口,它是与数据库交互的主要接口。Session对象负责管理实体对象的状态,包括...

    c#.net配置Session的生命周期.rar(视频)

    通过Ex01_05视频教程,你将详细学习到如何在实际项目中配置和管理C#.NET的Session生命周期,包括设置超时、选择存储模式以及优化Session使用等技巧。这将有助于你更好地理解Session在Web开发中的角色,从而提升应用...

    xfire开发的带session生命周期的webservice应用工程实例

    2. **会话管理类**:如前所述,可能存在一个类用于管理Session生命周期。 3. **配置文件**:可能包括Spring配置文件,用于配置服务bean、会话管理器等。 这个实例为开发者提供了一个实践机会,学习如何在Web服务中...

    使用监听器跟踪session的生命周期和session的属性

    以下是关于使用监听器跟踪Session生命周期和属性的详细解释。 1. **HttpSessionListener**: - `HttpSessionListener` 是Servlet API提供的一种接口,用于监听HttpSession对象的创建和销毁事件。 - 当一个新的...

    session的生命周期1

    以下是对`Session`生命周期、何时失效以及对浏览器要求的详细解释。 ### Session的生命周期 1. **创建**:当用户首次访问包含JSP、Servlet等动态内容的网页时,服务器会检查是否存在当前用户的`Session`。如果没有...

    spring bean的生命周期

    2. **容器管理的生命周期回调** - **Singleton Beans的懒加载**:如果Bean的scope为singleton,并且在XML配置中没有设置`lazy-init="true"`,那么Spring容器在启动时就会实例化这些Bean。 - **Prototype Beans的...

    创建多种生命周期的DataSnapServer

    本话题主要关注DataSnap Server的三种生命周期:Invocation生命周期,Session生命周期,以及Server生命周期。我们将深入探讨这些概念,并结合提供的文件名称列表来解析它们在实际应用中的意义。 首先,我们来看`...

    详解Spring中Bean的生命周期和作用域及实现方式

    2. 使用Annotation配置:可以使用Annotation来配置Bean的生命周期和作用域。 3. 使用Java配置:可以使用Java代码来配置Bean的生命周期和作用域。 在本文中,我们介绍了Spring中Bean的生命周期和作用域及实现方式。...

    过滤器对于session周期的控制

    在探讨如何通过`OpenSessionInViewFilter`来有效管理Hibernate中的Session生命周期之前,我们需要先理解Session及其生命周期的基本概念。 #### Session与生命周期 在Hibernate框架中,`Session`是执行数据库操作的...

    关于PHP5 Session生命周期介绍

    **PHP5 Session生命周期详解** 在PHP中,Session是一种用于存储用户状态信息的机制,它允许在不同的页面间共享数据,而无需使用Cookie或其他方法。Session的核心是Session ID,这是一个唯一的标识符,通常由服务器...

    hibernate的生命周期

    1. 应该尽量减少持久态对象的生命周期,避免长时间持有Session,以降低内存占用和提高系统性能。 2. 使用Transaction来包裹对数据库的所有操作,保证数据的一致性。 3. 对于大量数据的操作,考虑使用批处理更新和...

    Spring bean生命周期demo

    在Spring框架中,Bean的生命周期是指从创建到销毁的整个过程。这个过程包含了初始化、正常使用以及最终的销毁几个阶段。了解并掌握Spring Bean的生命周期对于优化应用性能和资源管理至关重要。接下来,我们将深入...

    Application,Session,Cookie,ViewState和Cache生命周期

    Application,Session,Cookie,ViewState和Cache生命周期

    测试实体对象的生命周期

    本文将详细探讨“测试实体对象的生命周期”,并结合给定的标签“源码”和“工具”,阐述如何通过Hibernate Session来理解和控制这些对象的状态。 首先,理解实体对象的生命周期对于数据库操作至关重要。在Hibernate...

    php5的session详解

    2. **购物车管理**:在电子商务网站中,Session 可以用于存储用户选购的商品信息。 3. **个性化设置**:根据用户偏好动态调整网站布局或内容展示方式。 4. **多页面交互**:在多页面应用中,Session 可以用于跨页面...

    session、viewstate jQuery SQL存储过程等一系列教学网站 相当实用哦

    #### 三、Session的生命周期 1. **创建**:当用户首次访问应用时。 2. **使用**:在整个会话过程中,可以读取和修改Session中的数据。 3. **销毁**:通常情况下,Session会在一定时间后自动失效,也可以手动销毁。 ...

    session监听小例子

    这两个接口提供了对Session生命周期事件的监听方法: 1. `HttpSessionListener`: 包含两个方法,`sessionCreated(HttpSessionEvent se)`用于监听Session创建事件,`sessionDestroyed(HttpSessionEvent se)`用于监听...

Global site tag (gtag.js) - Google Analytics