cookie机制和session机制

1、cookie机制和session机制的区别
***********************************************************************
具体来讲cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。
同时咱们也看到,因为才服务器端保持状态的方案在客户端也须要保存一个标识,因此session
机制可能须要借助于cookie机制来达到保存标识的目的,但实际上还有其余选择
***********************************************************************javascript

2、会话cookie和持久cookie的区别
***********************************************************************
若是不设置过时时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie通常不保存在硬盘上而是保存在内存里。
  若是设置了过时时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过时时间。
  存储在硬盘上的cookie能够在不一样的浏览器进程间共享,好比两个IE窗口。而对于保存在内存的cookie,不一样的浏览器有不一样的处理方式。
***********************************************************************php

3、如何利用实现自动登陆
***********************************************************************
  当用户在某个网站注册后,就会收到一个唯一用户ID的cookie。客户后来从新链接时,这个
用户ID会自动返回,服务器对它进行检查,肯定它是否为注册用户且选择了自动登陆,从而使用户务需给出明确的用户名和密码,就能够访问服务器上的资源。
************************************************************************html

4、如何根据用户的爱好定制站点
************************************************************************
  网站可使用cookie记录用户的意愿。对于简单的设置,网站能够直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个唯一的标识符发送给用户,由服务器端的数据库存储每一个标识符对应的页面设置。
************************************************************************java

5、cookie的发送
************************************************************************
1.建立Cookie对象
2.设置最大时效
3.将Cookie放入到HTTP响应报头
若是你建立了一个cookie,并将他发送到浏览器,默认状况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器以后被删除。若是你但愿浏览器将该cookie存储在磁盘上,则
须要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
发送cookie须要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP请 求报头中。因为这个方法并不修改任何以前指定的Set-Cookie报头,而是建立新的报头,所以咱们将这个方法称为是addCookie,而非 setCookie。一样要记住响应报头必须在任何文档内容发送到客户端以前设置。web

6、cookie的读取
*************************************************************************
1.调用request.getCookie
要获取有浏览器发送来的cookie,须要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。
2.对数组进行循环,调用每一个cookie的getName方法,直到找到感兴趣的cookie为止
 cookie与你的主机(域)相关,而非你的servlet或JSP页面。于是,尽管你的servlet可能只发送了单个cookie,你也可能会获得许多不相关的cookie。
例如:
  String cookieName = “userID”;
    Cookie cookies[] = request.getCookies();
    if (cookies!=null){
        for(int i=0;i<cookies.length;i++){
    Cookie cookie = cookies[i];
    if (cookieName.equals(cookie.getName())){
        doSomethingWith(cookie.getValue());
}
}
}
************************************************************************数据库

7、如何使用cookie检测初访者
************************************************************************
A.调用HttpServletRequest.getCookies()获取Cookie数组
B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确
C.若是是则退出循环并设置区别标识
D.根据区别标识判断用户是否为初访者从而进行不一样的操做
************************************************************************apache

8、使用cookie检测初访者的常见错误
************************************************************************
不能仅仅由于cookie数组中不存在在特定的数据项就认为用户是个初访者。若是cookie数组为null,客户多是一个初访者,也多是因为用户将cookie删除或禁用形成的结果。
可是,若是数组非null,也不过是显示客户曾经到过你的网站或域,并不能说明他们曾经访问过你的servlet。其它servlet、JSP页面以及非Java Web应用均可以设置cookie,依据路径的设置,其中的任何cookie都有可能返回给用户的浏览器。
正确的作法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。
************************************************************************数组

9、使用cookie属性的注意问题
************************************************************************
  属性是从服务器发送到浏览器的报头的一部分;但它们不属于由浏览器返回给服务器的报头。 
  所以除了名称和值以外,cookie属性只适用于从服务器输出到客户端的cookie;服务器端来自于浏览器的cookie并无设置这些属性。 
  于是不要指望经过request.getCookies获得的cookie中可使用这个属性。这意味着,你不能仅仅经过设置cookie的最大时 效,发出它,在随后的输入数组中查找适当的cookie,读取它的值,修改它并将它存回Cookie,从而实现不断改变的cookie值。
************************************************************************浏览器

10、如何使用cookie记录各个用户的访问计数
************************************************************************
1.获取cookie数组中专门用于统计用户访问次数的cookie的值
2.将值转换成int型
3.将值加1并用原来的名称从新建立一个Cookie对象
4.从新设置最大时效
5.将新的cookie输出
************************************************************************安全

11、session在不一样环境下的不一样含义
************************************************************************
session,中文常常翻译为会话,其原本的含义是指善始善终的一系列动做/消息,好比打电话是从拿起电话拨号到挂断电话这中间的一系列过程能够称之为一个session。
然而当session一词与网络协议相关联时,它又每每隐含了“面向链接”和/或“保持状态”这样两个含义。
  session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决方案。有时候Session也用来指这种解决方案的存储结构。
************************************************************************

12、session的机制
************************************************************************
  session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。
但程序须要为某个客户端的请求建立一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,若是已经包含一个session id则说明之前已经为此客户建立过session,服务器就按照session id把这个session检索出来使用(若是检索不到,可能会新建一个,这种状况可能出如今服务端已经删除了该用户对应的session对象,但用户人为 地在请求的URL后面附加上一个JSESSION的参数)。
若是客户请求不包含session id,则为此客户建立一个session而且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
************************************************************************

十3、保存session id的几种方式
************************************************************************
A.保存session id的方式能够采用cookie,这样在交互过程当中浏览器能够自动的按照规则把这个标识发送给服务器。
B.因为cookie能够被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然可以把session id传递回服务器,常常采用的一种技术叫作URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是做为URL路径的附加信息,另外一种是做为查询字符串附加在URL后面。网络在整个交互过程当中始终 保持状态,就必须在每一个客户端可能请求的路径后面都包含这个session id。
C.另外一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。
************************************************************************

十4、session何时被建立
************************************************************************
一个常见的错误是觉得session在有客户端访问时就被建立,然而事实是直到某server端程序(如Servlet)调用HttpServletRequest.getSession(true)这样的语句时才会被建立。
************************************************************************

十5、session什么时候被删除
************************************************************************
session在下列状况下被删除:
A.程序调用HttpSession.invalidate()
B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
C.服务器进程被中止

再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
************************************************************************

十6、URL重写有什么缺点
************************************************************************
   对全部的URL使用URL重写,包括超连接,form的action,和重定向的URL。每一个引用你的站点的URL,以及那些返回给用户的URL(即便经过间接手段,好比服务器重定向中的Location字段)都要添加额外的信息。
   这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何连接到站点动态页面的连接)。所以,每一个页面都必须使用 servlet或JSP动态生成。即便全部的页面都动态生成,若是用户离开了会话并经过书签或连接再次回来,会话的信息都会丢失,由于存储下来的连接含有 错误的标识信息-该URL后面的SESSION ID已通过期了。  
************************************************************************

十7、使用隐藏的表单域有什么缺点
************************************************************************
    仅当每一个页面都是有表单提交而动态生成时,才能使用这种方法。单击常规的<A HREF..>超文本连接并不产生表单提交,所以隐藏的表单域不能支持一般的会话跟踪,只能用于一系列特定的操做中,好比在线商店的结帐过程
************************************************************************

十8、会话跟踪的基本步骤
************************************************************************
1.访问与当前请求相关的会话对象
2.查找与会话相关的信息
3.存储会话信息
4.废弃会话数据
************************************************************************

十9、getSession()/getSession(true)、getSession(false)的区别
************************************************************************
getSession()/getSession(true):当session存在时返回该session,不然新建一个session并返回该对象
getSession(false):当session存在时返回该session,不然不会新建session,返回null
************************************************************************

二10、如何将信息于会话关联起来
************************************************************************
  setAttribute会替换任何以前设定的值;若是想要在不提供任何代替的状况下移除某个值,则应使用removeAttribute。这个方法会触发全部实现了HttpSessionBindingListener接口的值的valueUnbound
方法。
************************************************************************

二11、会话属性的类型有什么限制吗
************************************************************************
一般会话属性的类型只要是Object就能够了。除了null或基本类型,如int,double,boolean。
若是要使用基本类型的值做为属性,必须将其转换为相应的封装类对象
************************************************************************

二12、如何废弃会话数据
************************************************************************
A.只移除本身编写的servlet建立的数据:
   调用removeAttribute(“key”)将指定键关联的值废弃
B.删除整个会话(在当前Web应用中):
   调用invalidate,将整个会话废弃掉。这样作会丢失该用户的全部会话数据,而非仅仅由咱们
servlet或JSP页面建立的会话数据
C.将用户从系统中注销并删除全部属于他(或她)的会话
   调用logOut,将客户从Web服务器中注销,同时废弃全部与该用户相关联的会话(每一个Web应用至多一个)。这个操做有可能影响到服务器上多个不一样的Web应用
************************************************************************

二十3、使用isNew来判断用户是否为新旧用户的错误作法
************************************************************************
public boolean isNew()方法若是会话还没有和客户程序(浏览器)发生任何联系,则这个方法返回true,这通常是由于会话是新建的,不是由输入的客户请求所引发的。
但若是isNew返回false,只不过是说明他以前曾经访问该Web应用,并不表明他们曾访问过咱们的servlet或JSP页面。
由于session是与用户相关的,在用户以前访问的每个页面都有可能建立了会话。所以isNew为false只能说用户以前访问过该Web应用,session能够是当前页面建立,也多是由用户以前访问过的页面建立的。
正确的作法是判断某个session中是否存在某个特定的key且其value是否正确
************************************************************************

二十4、Cookie的过时和Session的超时有什么区别
************************************************************************
会话的超时由服务器来维护,它不一样于Cookie的失效日期。首先,会话通常基于驻留内存的cookie
不是持续性的cookie,于是也就没有截至日期。即便截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会大相径庭。
************************************************************************

二十5、session cookie和session对象的生命周期是同样的吗
************************************************************************
当用户关闭了浏览器虽然session cookie已经消失,但session对象仍然保存在服务器端
************************************************************************

二十6、是否只要关闭浏览器,session就消失了
************************************************************************
程序通常都是在用户作log off的时候发个指令去删除session,然而浏览器历来不会主动在关闭以前通知服务器它将要被关闭,所以服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。
之因此会有这种错误的认识,是由于大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次链接到服务器时也就没法找到原来的session。
若是服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求报头,把原来的session id发送到服务器,则再次打开浏览器仍然可以找到原来的session。
偏偏是因为关闭浏览器不会致使session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就能够认为客户端已经中止了活动,才会把session删除以节省存储空间。
  由此咱们能够得出以下结论:
  关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,一样也不会使已经保存到硬盘上的持久化cookie消失。
************************************************************************


二十7、打开两个浏览器窗口访问应用程序会使用同一个session仍是不一样的session
************************************************************************
一般session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的session id,这样咱们信息共享的目的就达不到了。
此时咱们能够先把session id保存在persistent cookie中(经过设置session的最大有效时间),而后在新窗口中读出来,就能够获得上一个窗口的session id了,这样经过session cookie和persistent cookie的结合咱们就能够实现了跨窗口的会话跟踪。
************************************************************************

二十8、如何使用会话显示每一个客户的访问次数
************************************************************************
因为客户的访问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,因此咱们要用到这些基本类型的封装类型对象做为session对象中属性的值
  但像Integer是一种不可修改(Immutable)的数据结构:构建后就不能更改。这意味着每一个请求都必须建立新的Integer对象,以后使用setAttribute来代替以前存在的老的属性的值。例如:
HttpSession session = request.getSession();
SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”);
if (value= =null){
    value = new SomeImmutableClass(…); // 新建立一个不可更改对象
}else{
    value = new SomeImmutableClass(calculatedFrom(value)); // 对value从新计算后建立新的对象
}
session.setAttribute(“someIdentifier”,value); // 使用新建立的对象覆盖原来的老的对象
************************************************************************

二十9、如何使用会话累计用户的数据
************************************************************************
使用可变的数据结构,好比数组、List、Map或含有可写字段的应用程序专有的数据结构。经过这种方式,除非首次分配对象,不然不须要调用setAttribute。例如

HttpSession session = request.getSession();
SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”);
if(value = = null){
    value = new SomeMutableClass(…);
    session.setAttribute(“someIdentifier”,value);
}else{
    value.updateInternalAttribute(…);     // 若是已经存在该对象则更新其属性而不需从新设置属性
}
************************************************************************

三10、不可更改对象和可更改对象在会话数据更新时的不一样处理
************************************************************************
不可更改对象由于一旦建立以后就不能更改,因此每次要修改会话中属性的值的时候,都须要
调用setAttribute(“someIdentifier”,newValue)来代替原有的属性的值,不然属性的值不会被更新
可更改对象由于其自身通常提供了修改自身属性的方法,因此每次要修改会话中属性的值的时
候,只要调用该可更改对象的相关修改自身属性的方法就能够了。这意味着咱们就不须要调
用setAttribute方法了

************************************************************************
2.cookies的属性有:Domain(域):哪一个站点发的哪一个站点拿走
                   Expires:是否过时
                   Haskeys:是否包含关键
                   path:存放的路径
                   secure:是否安全
注:---cookies的设置在 sever端设置,路径与域一块儿构成cookie的做用范围?
这个是什么意思的啊?为何会是在服务器端进行设置的呢?
    若不设置过时时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称 为会话cookie。会话cookie通常不存储在硬盘上而是保存在内存里,固然这种行为并非规范规定的。若设置了过时时间,浏览器就会把cookie 保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过时时间。存储在硬盘上的cookie能够在不一样的浏览器进程间共享,好比 两个IE窗口。而对于保存在内存里的cookie,不一样的浏览器有不一样的处理方式
IE与FF的区别哦!FF是共享的而IE当打开不一样的窗口的时候是不共享 的
3.session(会话):适用于同一客户在一个站点,不一样页面上的浏览;适用于同一客户在一个页面上,不断的刷新。
6.当程序须要为某个客户端的请求建立一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),若是已包含则说明之前已经为此客户端建立过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),若是客户端请求不包含session id,则为此客户端建立一个session而且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。

IE中:
有效的窗中包括
1.Session对象只在创建Session对象的窗口中有效。
2.在创建Session对象的窗口中新开连接的窗口
无效的窗口包括
1.直接启动IE浏览器的窗口
2.不是在创建Session对象的窗口中新开连接的窗口

***********************************************************************
cookie的内容主要包括:名字,值,过时时间,路径和域。
其中,

    域能够指定某一个域好比.google.com,至关于总店招牌,好比宝洁公司,也能够指定一个域下的具体某台机器好比www.google.com或者froogle.google.com,能够用飘柔来作比。
路径就是跟在域名后面的URL路径,好比/或者/foo等等,能够用某飘柔专柜作比。
   路径与域合在一块儿就构成了cookie的做用范围。
若是不设置过时时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的 cookie被称为会话cookie。会话cookie通常不存储在硬盘上而是保存在内存里,固然这种行为并非规范规定的。若是设置了过时时间,浏览器 就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过时时间。

   存储在硬盘上的cookie能够在不一样的浏览器进程间共享,好比两个IE窗口。而对于保存在内存里的cookie,不一样的浏览器有不一样的处理方式。对于 IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口能够与原窗口共享,而使用其余方式新开的IE进程则不能共享已经打开的窗口的内存 cookie;对于Mozilla Firefox0.8,全部的进程和标签页均可以共享一样的cookie。通常来讲是用javascript的window.open打开的窗口会与原窗 口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式常常给采用session机制的web应用程序开发者形成很 大的困扰。

[经典的语录]

下面就是一个goolge设置cookie的响应头的例子
HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html

到时候咱们的域就要设置为domain=.*****.cn path=/

session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。

4、理解session机制
session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。

当程序须要为某个客户端的请求建立一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,若是已包含一个session id则说明之前已经为此客户端建立过session,服务器就按照session id把这个session检索出来使用(若是检索不到,可能会新建一个),若是客户端请求不包含session id,则为此客户端建立一个session而且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。

保存这个session id的方式能够采用cookie,这样在交互过程当中浏览器能够自动的按照规则把这个标识发挥给服务器。通常这个cookie的名字都是相似于 SEEESIONID,而。好比weblogic对于web应用程序生成的 cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!- 145788764,它的名字就是JSESSIONID。

因为cookie能够被人为的禁止,必须有其余机制以便在cookie被禁止时仍然可以把session id传递回服务器。常常被使用的一种技术叫作URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是做为URL路径的附加信息,表现形式为http://..... /xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另外一种是做为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
这两种方式对于用户来讲是没有区别的,只是服务器在解析的时候处理的方式不一样,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。
为了在整个交互过程当中始终保持状态,就必须在每一个客户端可能请求的路径后面都包含这个session id。

另外一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。好比下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>
在被传递给客户端以前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
这种技术如今已较少应用,笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。
实际上这种技术能够简单的用对action应用URL重写来代替。

在谈论session机制的时候,经常听到这样一种误解“只要关闭浏览器,session就消失了”。其实能够想象一下会员卡的例子,除非顾客主动 对店家提出销卡,不然店家绝对不会轻易删除顾客的资料。对session来讲也是同样的,除非程序通知服务器删除一个session,不然服务器会一直保 留,程序通常都是在用户作log off的时候发个指令去删除session。然而浏览器历来不会主动在关闭以前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭,之所 以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次链接服务器时也就没法找到原来的session。若是服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的 HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然可以找到原来的session。

偏偏是因为关闭浏览器不会致使session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就能够认为客户端已经中止了活动,才会把session删除以节省存储空间。

[写得太精彩了。感觉太深了!]

一、session在什么时候被建立
一个常见的误解是觉得session在有客户端访问时就被建立,然而事实是直到某server端程序调用 HttpServletRequest.getSession(true)这样的语句时才被建立,注意若是JSP没有显示的使用 <%@page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。

因为session会消耗内存资源,所以,若是不打算使用session,应该在全部的JSP中关闭它。

二、session什么时候被删除
综合前面的讨论,session在下列状况下被删除a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session id时间间隔超过了session的超时设置;或c.服务器进程被中止(非持久session)

三、如何作到在浏览器关闭时删除session
严格的讲,作不到这一点。能够作一点努力的办法是在全部的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动做,而后向服务器发送一个请求来删除session。可是对于浏览器崩溃或者强行杀死进程这些很是规手段仍然无能为力。

七、开两个浏览器窗口访问应用程序会使用同一个session仍是不一样的session
参见第三小节对cookie的讨论,对session来讲是只认id不认人,所以不一样的浏览器,不一样的窗口打开方式以及不一样的cookie存储方式都会对这个问题的答案有影响。

八、如何防止用户打开两个浏览器窗口操做致使的session混乱
这个问题与防止表单屡次提交是相似的,能够经过设置客户端的令牌来解决。就是在服务器每次生成一个不一样的id返回给客户端,同时保存在session里, 客户端提交表单时必须把这个id也返回服务器,程序首先比较返回的id与保存在 session里的值是否一致,若是不一致则说明本次操做已经被提交过了。[对不起你已经投过票了!能够这样来进行控制的哦]

8、总结
session机制自己并不复杂,然而其实现和配置上的灵活性却使得具体状况复杂多变。这也要求咱们不能把仅仅某一次的经验或者某一个浏览器,服务器的经验看成广泛适用的经验,而是始终须要具体状况具体分析。


文章出处:DIY部落(http://www.diybl.com/course/3_program/java/javashl/20090306/158662.html)

************************************************************************

关于COOKIE和SESSION的关系,一直没搞清楚。网上一搜COOKIE,广泛都有会话COOKIE和持久COOKIE的概念。

rubyeye的博客里有这样的解释,我把部分贴过来。(http://rubyeye.javaeye.com/blog/196117)


引用
当你第一次访问一个网站的时候,网站服务器会在响应头内加上
Set-Cookie:PHPSESSID=nj1tvkclp3jh83olcn3191sjq3(php服务器),或Set-Cookie JSESSIONID=nj1tvkclp3jh83olcn3191sjq3(java服务器)信息,此信息是服务器随机生成的,放在服务器内存里,为 了标识惟一的客户端用户,内容不会重复,这就是sessionid.
   当浏览器获得这个sessionid会将它放在本身的进程内存里,这里不一样的浏览器会有所不一样,IE进程间不能共享这个sessionid,也就是新开一 个IE将不能共享这个sessionid;而Firefox进程间能够共享.而后你继续发请求给这个网站的时候,浏览器就会把这个sessionid放在 请求头里发送给该服务器了,这样服务器获得sessionid后再和本身内存里存放的sessionid对比锁定客户端,从而区分不一样客户端,完成会话.
   能够看出若是用这种方式,当用户在会话的过程当中关闭浏览器结束进程,则这个sessionid将消失,若是用户又打开浏览器想继续此次会话的时候,就会因 为发送的请求中没有这个sessionid而使服务器没法辨别该把那个session信息给他,注意(这个时候服务器端的sessionid和 sessionid所指向的session都还存在,只是没有正确的sessionid和它匹配而占用服务器内存,只有session过时或服务器重启才 释放内存).
   上面这种方式叫会话cookie,把cookie放在浏览器内存里,只能在这个浏览器的内存范围里完成会话,是一种不长久的方式,为了能长久会话,就出现 了持久化cookie,把cookie固化在用户的计算机上,如今的cookie不仅仅能存放sessionid,还能放用户信息,样式表信息等.
   若是用户禁止了全部cookie的使用,那么会话cookie和持久化cookie都不能用了,有个方案也能够解决问题,就是URL重写,这里要说下的就是URL重写只能实现会话cookie的效果,持久会话实现不了.


刚开始理解时,我也认为会有持久和会话这两种COOKIE。我认为,
会话COOKIE就是用来存放SESSIONID的,而且只存在于浏览器内存,浏览器关闭后会话COOKIE就被删除;
持久COOKIE就是用来存放其它信息,而且是在咱们的本地硬盘里能看到的那种COOKIE。

而后我写了个SERVLET试了一下。

Java代码
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {   
       
    Cookie cookie = null;   
       
    PrintWriter out = response.getWriter();   
    out.println("<html><body>");   
       
    Cookie[] cookies = request.getCookies();   
       
    // 若是没有COOKIE,新建一个COOKIE   
    if (cookies == null) {   
           
        out.println("<b>cookies is null.</b></br>");   
           
        cookie = new Cookie("new", "1");   
           
        response.addCookie(cookie);   
           
    } else {   
           
        out.println("<b>cookies is not null.</b></br>");   
           
        for (int i = 0; i < cookies.length; i++) {   
               
            cookie = cookies[i];   
               
            out.println("cookie" + i + " name: " + cookie.getName() + "</br>");   
        }   
    }   
       
    HttpSession session = request.getSession();   
       
    if (session == null) {   
        out.println("<b>session is null.</b></br>");   
           
    } else {   
        out.println("<b>session is not null.</b></br>");   
        out.println("session id: " + session.getId() + "</br>");   
    }   
       
    out.println("</body></html>");   
}  
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
 
 Cookie cookie = null;
 
 PrintWriter out = response.getWriter();
 out.println("<html><body>");
 
 Cookie[] cookies = request.getCookies();
 
 // 若是没有COOKIE,新建一个COOKIE
 if (cookies == null) {
  
  out.println("<b>cookies is null.</b></br>");
  
  cookie = new Cookie("new", "1");
  
  response.addCookie(cookie);
  
 } else {
  
  out.println("<b>cookies is not null.</b></br>");
  
  for (int i = 0; i < cookies.length; i++) {
   
   cookie = cookies[i];
   
   out.println("cookie" + i + " name: " + cookie.getName() + "</br>");
  }
 }
 
 HttpSession session = request.getSession();
 
 if (session == null) {
  out.println("<b>session is null.</b></br>");
  
 } else {
  out.println("<b>session is not null.</b></br>");
  out.println("session id: " + session.getId() + "</br>");
 }
 
 out.println("</body></html>");
}

第一次访问这个SERVLET,页面显示

引用
cookies is null.
session is not null.
session id: 0D0AABB6F911362FEE87BEEB2953C33F


第二次访问,页面显示

引用
cookies is not null.
cookie0 name: new
cookie1 name: JSESSIONID
session is not null.
session id: 0D0AABB6F911362FEE87BEEB2953C33F


第二次访问时从客户端来了两个COOKIE,名为“new”的COOKIE是我建立的,名为“JSESSIONID”的COOKIE应该是服务器TOMCAT建立的,但这时,在本地硬盘里找不到这两个COOKIE的文件。

改一下SERVLET,在建立名为“new”的COOKIE时,加一句

Java代码
cookie.setMaxAge(1000);  
cookie.setMaxAge(1000);
而后本地硬盘里就有“new”这个COOKIE了。

这下就有疑问了,在没有设置COOKIE存活期时,本身建立的SESSION不会存到本地硬盘,会不会TOMCAT建立的所谓的会话COOKIE也是没有设置存活期呢?

而后根据zddava的博客(http://zddava.javaeye.com/blog/311053),找到了TOMCAT里建立会话COOKIE的代码。

org.apache.catalina.connector.Request.java里,

Java代码
protected void configureSessionCookie(Cookie cookie) {   
    cookie.setMaxAge(-1);   
    String contextPath = null;   
    if (!connector.getEmptySessionPath() && (getContext() != null)) {   
        contextPath = getContext().getEncodedPath();   
    }   
    if ((contextPath != null) && (contextPath.length() > 0)) {   
        cookie.setPath(contextPath);   
    } else {   
        cookie.setPath("/");   
    }   
    if (isSecure()) {   
        cookie.setSecure(true);   
    }   
}  
protected void configureSessionCookie(Cookie cookie) {
    cookie.setMaxAge(-1);
    String contextPath = null;
    if (!connector.getEmptySessionPath() && (getContext() != null)) {
        contextPath = getContext().getEncodedPath();
    }
    if ((contextPath != null) && (contextPath.length() > 0)) {
        cookie.setPath(contextPath);
    } else {
        cookie.setPath("/");
    }
    if (isSecure()) {
        cookie.setSecure(true);
    }
}
cookie.setMaxAge(-1);使COOKIE在浏览器被关闭时删除。并且这里的cookie和上面SERVLET里的cookie都是javax.servlet.http.Cookie。

由此得出结论:
    可能最开始是我理解错了,COOKIE并无会话COOKIE和持久COOKIE之分。咱们本地建立的“持久COOKIE”和WEB容器建立的“会话 COOKIE”都是一种COOKIE,就是javax.servlet.http.Cookie。只是WEB容器把存活期设置成了关闭浏览器时删除而已 (TOMCAT)。
    这个结论不正确。在服务器端设置过时时间后就是持久cookie了,因此有会话COOKIE和持久COOKIE之分。
************************************************************************
cookie和session机制之间的区别与联系
具体来讲cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他须要用户打开客户端的cookie支持。cookie的做用就是为了解决HTTP协议无状态的缺陷所做的努力.
而session机制采用的是一种在客户端与服务器之间保持状态的解决方案。同时咱们也看到,因为采用服务器端保持状态的方案在客户端也须要保存一个标 识,因此session机制可能须要借助于cookie机制来达到保存标识的目的。而session提供了方便管理全局变量的方式
session是针对每个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪一个用户session变量,这个值是经过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器。
就安全性来讲:当你访问一个使用session 的站点,同时在本身机子上创建一个cookie,建议在服务器端的SESSION机制更安全些.由于它不会任意读取客户存储的信息。

正统的cookie分发是经过扩展HTTP协议来实现的,服务器经过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie
从网络服务器观点看全部HTTP请求都独立于先前请求。就是说每个HTTP响应彻底依赖于相应请求中包含的信息
状态管理机制克服了HTTP的一些限制并容许网络客户端及服务器端维护请求间的关系。在这种关系维持的期间叫作会话(session)。
Cookies是服务器在本地机器上存储的小段文本并随每个请求发送至同一个服务器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie规范。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它 会自动将同一服务器的任何请求缚上这些cookies
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
理解session机制
session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。

当程序须要为某个客户端的请求建立一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为 session id,若是已包含一个session id则说明之前已经为此客户端建立过session,服务器就按照session id把这个 session检索出来使用(若是检索不到,可能会新建一个),若是客户端请求不包含session id,则为此客户端建立一个session而且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。

保存这个session id的方式能够采用cookie,这样在交互过程当中浏览器能够自动的按照规则把这个标识发挥给服务器。通常这个cookie的名字都是相似于 SEEESIONID,而。好比weblogic对于web应用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。

因为cookie能够被人为的禁止,必须有其余机制以便在cookie被禁止时仍然可以把session id传递回服务器。常常被使用的一种技术叫作URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是做为URL路径的附加信息,表现形式为http://..... /xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另外一种是做为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
这两种方式对于用户来讲是没有区别的,只是服务器在解析的时候处理的方式不一样,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。
为了在整个交互过程当中始终保持状态,就必须在每一个客户端可能请求的路径后面都包含这个session id。

另外一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。好比下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>
在被传递给客户端以前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
这种技术如今已较少应用,笔者接触过的很古老的iPlanet6(SunONE应用服务器的前身)就使用了这种技术。
实际上这种技术能够简单的用对action应用URL重写来代替。

在谈论session机制的时候,经常听到这样一种误解“只要关闭浏览器,session就消失了”。其实能够想象一下会员卡的例子,除非顾客主动 对店家提出销卡,不然店家绝对不会轻易删除顾客的资料。对session来讲也是同样的,除非程序通知服务器删除一个session,不然服务器会一直保 留,程序通常都是在用户作log off的时候发个指令去删除session。然而浏览器历来不会主动在关闭以前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭,之所 以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个 session id就消失了,再次链接服务器时也就没法找到原来的session。若是服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的 HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然可以找到原来的session。

偏偏是因为关闭浏览器不会致使session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就能够认为客户端已经中止了活动,才会把session删除以节省存储空间。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 由JSESSIONID谈cookie与SESSION的区别和联系
在一些投票之类的场合,咱们每每由于公平的原则要求每人只能投一票,在一些WEB开发中也有相似的状况,这时候咱们一般会使用COOKIE来实现,例如以下的代码:
< % cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
doStuffForNewbie();
//没有访问过
}

else
{
doStuffForReturnVisitor(); //已经访问过了
}

% >

这是很浅显易懂的道理,检测COOKIE的存在,若是存在说明已经运行过写入COOKIE的代码了,然而运行以上的代码后,不管什么时候结果都是执行 doStuffForReturnVisitor(),经过控制面板-Internet选项-设置-察看文件却始终看不到生成的cookie文件,奇怪, 代码明明没有问题,不过既然有cookie,那就显示出来看看。
cookie[]cookies = request.getCookies();
if (cookies.lenght == 0 || cookies == null)
out.println("Has not visited this website");
}

else
{
for (int i = 0; i < cookie.length; i++)
{
out.println("cookie name:" + cookies[i].getName() + "cookie value:" +
cookie[i].getValue());
}
}

运行结果:
cookie name:JSESSIONID cookie value:KWJHUG6JJM65HS2K6 为何会有cookie呢,你们都知道,http是无状态的协议,客户每次读取web页面时,服务器都打开新的会话,并且服务器也不会自动维护客户的上下 文信息,那么要怎么才能实现网上商店中的购物车呢,session就是一种保存上下文信息的机制,它是针对每个用户的,变量的值保存在服务器端,经过 SessionID来区分不一样的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为 JSESSIONID的输出cookie,咱们叫作session cookie,以区别persistent cookies,也就是咱们一般所说的cookie,注意session cookie是存储于浏览器内存中的,并非写到硬盘上的,这也就是咱们刚才看到的JSESSIONID,咱们一般情是看不到JSESSIONID的,但 是当咱们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,咱们就能够在地址栏看到 sessionid=KWJHUG6JJM65HS2K6之类的字符串。
明白了原理,咱们就能够很容易的分辨出persistent cookies和session cookie的区别了,网上那些关于二者安全性的讨论也就一目了然了,session cookie针对某一次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本(一般是加密的),并且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,天然不如 session cookie安全了。
一般session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样咱们信息共享的目的就达不到 了,此时咱们能够先把sessionid保存在persistent cookie中,而后在新窗口中读出来,就能够获得上一个窗口SessionID了,这样经过session cookie和persistent cookie的结合咱们就实现了跨窗口的session tracking(会话跟踪)。
在一些web开发的书中,每每只是简单的把Session和cookie做为两种并列的http传送信息的方式,session cookies位于服务器端,persistent cookie位于客户端,但是session又是以cookie为基础的,明白的二者之间的联系和区别,咱们就不难选择合适的技术来开发web service了。

 

本文来自CSDN博客,http://blog.csdn.net/yuhua3272004/archive/2009/07/17/4357268.aspx

相关文章
相关标签/搜索