session生命周期

session生命周期

原文连接:http://blog.sina.com.cn/s/blog_72c8c1150100qpgl.html

文中黄色字体为个人标记修改或添加html

Session保存在服务器端。为了得到更高的存取速度,服务器通常把Session放在内存里。每一个用户都会有一个独立的Session。若是Session内容过于复杂,当大量客户访问服务器时可能会致使内存溢出。所以,Session里的信息应该尽可能精简。web

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生命周期的三种方法;
方式一:
在Servlet中设置
HttpSession session = request.getSession();
session.setMaxInactiveInterval(60);//单位为秒
方式二:
在web.xml中设置session-config以下:
<session-config>
<session-timeout>2(单位:分钟)</session-timeout>
</session-config>
方式三:
在Tomcat的/conf/web.xml中session-config,默认值为:30分钟 配置全局Session生命周期,即全部在该服务器中部署的项目都会使用
<session-config>
<session-timeout>30</session-timeout>
</session-config>
优先级:Servlet中API设置 > 程序/web.xml设置 > Tomcat/conf/web.xml设置cookie

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

笔记: 使session失效的方法: session.invalidate() ;
Session中包括各类方法,使用起来要比Cookie方便得多。Session的经常使用方法以下。session

 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失效

Session对浏览器的要求

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

该Cookie为服务器自动生成的,它的maxAge属性通常为-1,表示仅当前浏览器内有效,而且各浏览器窗口间不共享,关闭浏览器就会失效。(默认值是-1,表示关闭浏览器,cookie就会消失。若是是正数,表示从如今开始,即将过时的seconds。)所以同一机器的两个浏览器窗口访问服务器时,会生成两个不一样的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地址重写,例如:

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

<td><a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=Java">Homepage</a> 即在文件名的后面,在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(若是没有则建立),编辑内容以下:

/META-INF/context.xml

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

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实现登录信息长时间有效:

1. session须要依赖jsessionid,而jsessionid的maxAge为-1,也就是当关闭浏览器后存在cookie中的jsessionid就会丢失,当该客户端再次请求服务器时,即便该客户端上次会话对应的session对象仍然存在于服务器内存中(由于设置了maxInactiveInterval很大),可是该客户端的第二次请求没有jsessionid,因此服务器没法根据jsessionid找到上次访问时的session对象。

2. 若是设置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。session是服务器端对象与浏览器没有关系,若是客户端浏览器存有表示当前session的cookie中的jsessionid,那么就能够访问到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。

相关文章
相关标签/搜索