因为项目须要,最近用session容器比较多,传载的同时加上了本身的一些理解,不足之处还请你们补充和纠正。
1、cookie机制和session机制的区别
*************************************************************************************
Cookie是客户端的存储空间,由浏览器来维持。具体来讲cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时咱们也看到,因为才服务器端保持状态的方案在客户端也须要保存一个标识,因此session机制可能须要借助于cookie机制来达到保存标识的目的,但实际上还有其余选择,好比说重写URL和隐藏表单域。
*************************************************************************************
2、会话cookie和持久cookie的区别
*************************************************************************************
若是不设置过时时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie通常不保存在硬盘上而是保存在内存里。
若是设置了过时时间(setMaxAge(60*60*24)),浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过时时间。存储在硬盘上的cookie能够在不一样的浏览器进程间共享,好比两个IE窗口。而对于保存在内存的cookie,不一样的浏览器有不一样的处理方式。(在IE下测试经过)
*************************************************************************************
3、如何利用实现自动登陆
*************************************************************************************
当用户在某个网站注册后,就会收到一个唯一用户ID的cookie。客户后来从新链接时,这个用户ID会自动返回,服务器对它进行检查,肯定它是否为注册用户且选择了自动登陆,从而使用户务需给出明确的用户名和密码,就能够访问服务器上的资源。
*************************************************************************************
4、如何根据用户的爱好定制站点
*************************************************************************************
网站可使用cookie记录用户的意愿。对于简单的设置,网站能够直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个唯一的标识符发送给用户,由服务器端的数据库存储每一个标识符对应的页面设置。
*************************************************************************************
5、cookie的发送
*************************************************************************************
1.建立Cookie对象
2.设置最大时效
3.将Cookie放入到HTTP响应报头
若是你建立了一个cookie,并将他发送到浏览器,默认状况下它是一个会话级别的cookie:存储在浏览器的内存中(服务器自动建立一个cookie并将jsessionId做为key,sessionId的值做为value发送到客户端浏览器内存中),用户退出浏览器以后被删除。若是你但愿浏览器将该cookie存储在磁盘上,则须要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。发送cookie须要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP请求报头中。因为这个方法并不修改任何以前指定的Set-Cookie报头,而是建立新的报头,所以咱们将这个方法称为是addCookie,而非setCookie。一样要记住响应报头必须在任何文档内容发送到客户端以前设置。
*************************************************************************************
6、cookie的读取
*************************************************************************************
1.调用request.getCookie
要获取有浏览器发送来的cookie,须要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,对应由HTTP请求中Cookie报头输入的值。
2.对数组进行循环,调用每一个cookie的getName方法,直到找到感兴趣的cookie为止,cookie与你的主机(域)相关,而非你的servlet或JSP页面。于是,尽管你的servlet可能只发送了单个cookie,你也可能会获得许多不相关的cookie。
例如:(login.jsp页面cookie实现用户名userName填写)
javascript
String username = ""; //从客户端读取硬盘中的cookie文件 Cookie[] cookies = request.getCookies(); if(cookies == null){ username = ""; } else{ for (int i = 0; i < cookies.length; i++){ if ("USERNAME".equalsIgnoreCase(cookies[i].getName())){ username = cookies[i].getValue(); } } %> <form name="login" method="post" action="login.do"> <td width="100%" bgcolor="#CCCCCC" colspan="2"> <p align="left">用户名<br> <input type="text" name="username" value= "<%=username%>"> </p> <p align="left">密 码 <br> <input type="password" name="password"> </p> <p align="left"> <input type="submit" name="Submit" value="肯定"> <input name="reset" type="reset" value="取消"> </p> </form> LoginAction: //将正确userName放入c1对象,并用"USERNAME"作key标识 Cookie c1= new Cookie("USERNAME",logindto.getUsername()); //若是不设置时间,则cookie为会话cookie,不写入客户端硬盘 c1.setMaxAge(60*60*24); response.addCookie(c1);
*************************************************************************************
7、如何使用cookie检测初访者
*************************************************************************************
A.调用HttpServletRequest.getCookies()获取Cookie数组
B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确
C.若是是则退出循环并设置区别标识
D.根据区别标识判断用户是否为初访者从而进行不一样的操做
*************************************************************************************
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。若是客户端Cookie禁用,则服务器能够自动经过重写URL的方式来保存Session的值,而且这个过程对程序员透明。(IE6.0除外)
C.另外一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。
*************************************************************************************
十4、session何时被建立
*************************************************************************************
一个常见的误解是觉得session在有客户端访问时就被建立,然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被建立。
注意若是JSP没有显示的使用 <% @page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句 HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。
因为session会消耗内存资源,所以,若是不打算使用session,应该在全部的JSP中关闭它。
*************************************************************************************
十5、session什么时候被删除
*************************************************************************************
session在下列状况下被删除:
A.程序调用HttpSession.invalidate()
B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
C.服务器进程被中止
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效,除非此时Server端恰好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方法会替换上次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消失。
补充:那如何作到在浏览器关闭时删除session呢 ?
严格的讲,作不到这一点。能够作一点努力的办法是在全部的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动做,而后向服务器发送一个请求来删除session。可是对于浏览器崩溃或者强行杀死进程这些很是规手段仍然无能为力。
*************************************************************************************
二十7、打开两个浏览器窗口访问应用程序会使用同一个session仍是不一样的session
*************************************************************************************
一般session cookie是不能跨窗口使用的,当你新开了一个新的浏览器窗口进入相同页面时,系统会赋予你一个新的session id,这样咱们信息共享的目的就达不到了。对session来讲是只认id不认人,所以不一样的浏览器,不一样的窗口打开方式以及不一样的cookie存储方式(如会话cookie和持久cookie)都会对这个问题的答案有影响。
(在IE下测试,打开两个浏览器(不是新建窗口,是直接启动两次浏览器),获得的SessionID也是不同)
要实现跨窗口的会话跟踪,咱们能够先把session id保存在persistent cookie中(经过设置session的最大有效时间),而后在新窗口中读出来,就能够获得上一个窗口的session id了,这样经过session cookie和persistent cookie的结合咱们就能够实现了跨窗口的会话跟踪。(待测试)
*************************************************************************************
二十8、如何使用会话显示每一个客户的访问次数
*************************************************************************************
因为客户的访问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,因此咱们要用到这些基本类型的封装类型对象做为session对象中属性的值.
但像Integer是一种不可修改(Immutable)的数据结构:构建后就不能更改。这意味着每一个请求都必须建立新的Integer对象,以后使用setAttribute来覆盖以前存在的老的属性的值。例如:
java
Integer value = (Integer)request.getSession().getAttribute("cout"); if (value == null){ value = new CountClass(…); // 新建立一个不可更改对象 }else{ value = new CountClass(calculated(value)); // 对value从新计算后建立新的对象 } request.getSession().setAttribute("cout",value);// 使用新建立的对象覆盖原来的老的对象
*************************************************************************************
二十9、如何使用会话累计用户的数据
*************************************************************************************
使用可变的数据结构,好比数组、List、Map或含有可写字段的应用程序专有的数据结构。经过这种方式,除非首次分配对象,不然不须要调用setAttribute。例如:
程序员
List list_check = (List) request.getSession().getAttribute("ids_go"); if(list_check = = null){ list_check = new List(); request.getSession().setAttribute(("ids_go",list_check ); }else{ list_check .clear();// 若是已经存在该对象则更新其属性而不需从新设置属性 } List list_check1 = (List) request.getSession().getAttribute("ids_go"); System.out.println(list_check1.size());//此时size为0
*************************************************************************************
三10、不可更改对象和可更改对象在会话数据更新时的不一样处理
*************************************************************************************
不可更改对象由于一旦建立以后就不能更改,因此每次要修改会话中属性的值的时候,都须要调用setAttribute(“someIdentifier”,newValue)来代替原有的属性的值,不然属性的值不会被更新。
可更改对象由于其自身通常提供了修改自身属性的方法,因此每次要修改会话中属性的值的时候,只要调用该可更改对象的相关修改自身属性的方法就能够了,这意味着咱们就不须要调用setAttribute方法了。
数据库
总结数组
session机制自己并不复杂,然而其实现和配置上的灵活性却使得具体状况复杂多变。这也要求咱们不能把仅仅某一次的经验或者某一个浏览器,服务器的经验看成广泛适用的。浏览器