session和cookie的区别和联系,session的生命周期,多个服务部署时session管理
Session和Cookie的区别
对象 | 信息量大小 | 保存时间 | 应用范围 | 保存位置 |
Session | 小量,简单的数据 | 用户活动时间+一段延迟时间(一般为20分钟) | 单个用户 | 服务器端 |
Cookie | 小量,简单的数据 | 可以根据需要设定 | 单个用户 | 客户端 |
1.1 Session对象
浏览器访问服务器时,服务器会创建一个对象(该对象也称为session对象,该对象有一个唯一的id号与其对应)。然后
,服务器会将id号发送给浏览器(默认情况下,使用cookie机制发送)。当浏览器再次访问服务器时,会将id号发送过
来。服务器可以依据id号找到对应的session对象。通过这个session对象,来保存状态。
1.1.1 session在不同环境下的不同含义
session,中文经常翻译为会话,其本来的含义是指有始有终的一系列动作/消息,比如打电话是从拿起电话拨号到挂
断电话这中间的一系列过程可以称之为一个session。
然而当session一词与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这样两个含义。
session在Web开发环境下的语义又有了新的扩展,它的含义是指一类用来在客户端与服务器端之间保持状态的解决
方案。有时候Session也用来指这种解决方案的存储结构。
1.1.2 保存session id的几种方式
A.保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
如果客户端支持Cookie,Web Server在返回Response的时候,在Response的Header部分,加入一个“set-cookie:
jsessionid=XXXX”header属性,把jsessionid放在Cookie里传到客户端。
B.由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务器,经常
采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附
加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求
的路径后面都包含这个session id。
C.另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session
id传递回服务器。
1.1.3 URL重写有什么缺点
对所有的URL使用URL重写,包括超链接,form的action,和重定向的URL。每个引用你的站点的URL,以及那些返
回给用户的URL(即使通过间接手段,比如服务器重定向中的Location字段)都要添加额外的信息。
这意味着在你的站点上不能有任何静态的HTML页面(至少静态页面中不能有任何链接到站点动态页面的链接)。因
此,每个页面都必须使用servlet或JSP动态生成。即使所有的页面都动态生成,如果用户离开了会话并通过书签或链接
再次回来,会话的信息都会丢失,因为存储下来的链接含有错误的标识信息-该URL后面的SESSION ID已经过期了。
1.1.4 使用隐藏的表单域有什么缺点
仅当每个页面都是有表单提交而动态生成时,才能使用这种方法。单击常规的<A HREF..>超文本链接并不产生表单提交
,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程。
1.1.5 session什么时候被创建
一个常见的错误是以为session在有客户端访问时就被创建,然而事实是直到某server端程序(如Servlet)调用
HttpServletRequest.getSession(true)这样的语句时才会被创建。
1.1.6 session何时被删除
session在下列情况下被删除:
A.程序调用HttpSession.invalidate()
B.距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
C.服务器进程被停止
再次注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
1.2 Cookie对象
浏览器向服务器发送请求时,服务器会将少量的数据返回给浏览器(该数据以set-cookie消息头的形式返回给浏览器)
,浏览器会将这些数据存放到硬盘或者内存上。当浏览器下次再次访问服务器时,会将之前存放的数据发送给服务器(
以cookie消息头的形式发送给服务器)。通过这种方式,就可以记录浏览器与服务器之间交互的数据,也就是状态。
1.2.1 会话cookie和持久cookie的区别
如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生
命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过
设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏
览器有不同的处理方式。
2.Session和Cookie的关系
这里用一个形象的比喻来解释session的工作方式。假设
Web Server:是一个商场的存包处
HTTP Request:是一个顾客
Session:商场的存包处的柜子
Session ID:存包号码牌
Cookie:客户随身携带不离身的钱包
情况一:一个顾客(HTTP Request),第一次来到存包处(Web Server),管理员把顾客的物品存放在某一个柜子里面
(Session),然后把一个号码牌(Session ID)交给这个顾客,作为取包凭证。
情况二:顾客(HTTP Request)下一次来的时候,就要把号码牌(Session ID)交给存包处(Web Server)的管理员。
管理员根据号码牌(Session ID)找到相应的柜子(Session),根据顾客(HTTP Request)的请求,存包处(Web
Server)可以取出、更换、添加柜子(Session)中的物品,存包处(Web Server)也可以让顾客(HTTP Request)的号
码牌和号码牌对应的柜子(Session)失效。
情况三:顾客(HTTP Request)的忘性很大,管理员在顾客回去的时候(HTTP Response)都要重新提醒顾客记住自己的
号码牌(Session ID)。这样,顾客(HTTP Request)下次来的时候,就又带着号码牌回来了。
情况四:客户(HTTP Request)把拿到的号码牌(Session ID)放到随身携带不离身的钱包(Cookie)中。
3.Session和Cookie的应用
3.1 如何利用实现自动登录
当用户在某个网站注册后,就会收到一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器
对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务
器上的资源。
3.2 如何根据用户的爱好定制站点
网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对
于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。
3.3 cookie的发送
1) 创建Cookie对象
2) 设置最大时效
3) 将Cookie放入到HTTP响应报头
如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户
退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时
间。将最大时效设为0则是命令浏览器删除该cookie。
发送cookie需要使用HttpServletResponse的addCookie方法,将cookie插入到一个Set-Cookie HTTP请求报头中。由于
这个方法并不修改任何之前指定的Set-Cookie报头,而是创建新的报头,因此我们将这个方法称为是addCookie,而非
setCookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。
Java代码 收藏代码
Cookie cookie = new Cookie("duanqftest", "22222");
cookie.setDomain("172.20.40.73");
cookie.setMaxAge(60000);
cookie.setPath("/");
response.addCookie(cookie);
javax.servlet.http.Cookie[] diskCookies = request.getCookies();
response.sendRedirect("ReadCookie");
3.4 cookie的读取
1) 调用request.getCookie
要获取有浏览器发送来的cookie,需要调用HttpServletRequest的getCookies方法,这个调用返回Cookie对象的数组,
对应由HTTP请求中Cookie报头输入的值。
2) 对数组进行循环,调用每个cookie的getName方法,直到找到感兴趣的cookie为止
cookie与你的主机(域)相关,而非你的servlet或JSP页面。因而,尽管你的servlet可能只发送了单个cookie,你也可能
会得到许多不相关的cookie。
Java代码 收藏代码
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());
}
}
3.5 如何使用cookie检测初访者
A.调用HttpServletRequest.getCookies()获取Cookie数组
B.在循环中检索指定名字的cookie是否存在以及对应的值是否正确
C.如果是则退出循环并设置区别标识
D.根据区别标识判断用户是否为初访者从而进行不同的操作
3.6 使用cookie检测初访者的常见错误
不能仅仅因为cookie数组中不存在在特定的数据项就认为用户是个初访者。如果cookie数组为null,客户可能是一个初
访者,也可能是由于用户将cookie删除或禁用造成的结果。
但是,如果数组非null,也不过是显示客户曾经到过你的网站或域,并不能说明他们曾经访问过你的servlet。其它
servlet、JSP页面以及非Java Web应用都可以设置cookie,依据路径的设置,其中的任何cookie都有可能返回给用户的
浏览器。
正确的做法是判断cookie数组是否为空且是否存在指定的Cookie对象且值正确。
3.7 使用cookie属性的注意问题
属性是从服务器发送到浏览器的报头的一部分;但它们不属于由浏览器返回给服务器的报头。
因此除了名称和值之外,cookie属性只适用于从服务器输出到客户端的cookie;服务器端来自于浏览器的cookie并
没有设置这些属性。
因而不要期望通过request.getCookies得到的cookie中可以使用这个属性。这意味着,你不能仅仅通过设置cookie
的最大时效,发出它,在随后的输入数组中查找适当的cookie,读取它的值,修改它并将它存回Cookie,从而实现不断改
变的cookie值。
3.8 如何使用cookie记录各个用户的访问计数
1) 获取cookie数组中专门用于统计用户访问次数的cookie的值
2) 将值转换成int型
3) 将值加1并用原来的名称重新创建一个Cookie对象
4) 重新设置最大时效
5) 将新的cookie输出
3.9 会话跟踪的基本步骤
1) 访问与当前请求相关的会话对象
2) 查找与会话相关的信息
3) 存储会话信息
4) 废弃会话数据
3.10 getSession()/getSession(true)、getSession(false)的区别
getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象。
getSession(false):当session存在时返回该session,否则不会新建session,返回null。