Cookie的介绍和使用:cookie的作用是当用户通过http访问一个服务器时,这个服务器会将一些key/value键值对返回给客户端浏览器,并给这些数据加上限制条件,在条件符合时用户下次访问服务器时,数据又被完整地带 回服务器。当初W3C在设计 Cookie时实际上考虑的是为了记录用户在一段时间内访问web应用的行为路径。由于Http协议是一种无状态协议,当用户的一次访问请求结束后,后端服务器就无法知道下一次来访问的还是不是上次访问的用户,在设计应用程序时,我们很容易想到两次访问是同一人访问与不同的两个人访向对程序设计和性能来说有很大的不同。例如,在一个很短的时闻内,如果与用户相关的数据被频繁访问,可以针对这个数据做缓存,这样可以大大提高数据的访问性能。 Cookie的作用正是在此,由于是同一个客户端发出的请求,每次发出的请求都会带有第一次访问时服务端设置的信息,这样服务端就可以根据 Cookie值来划分访问的用户了.
BAIDUID: 3C64D3C3F1753134D13C33AFD2B38367:FG
ispeed_lsm: 2
MCITY: -131:
pgv_pvi: 3797581824
pgv_si: s9468756992
BDUSS: JhNXVoQmhPYTVENEdIUnQ5S05xcHZMMVY5QzFRNVh5SzZoV0xMVDR6RzV-bEJZSVFBQUFBJCQAAAAAAAAAAAEAAACteXsbYnRfY2hpbGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlxKVi5cSlYZj
BD_HOME: 1
H_PS_PSSID: 1423_21080_17001_21454_21408_21530_21377_21525_21193_21340
BD_UPN: 123253
sug: 3
sugstore: 0
ORIGIN: 0
bdime:
存在服务器的一种用来存放用户数据的类HashTable结构。
浏览器第一次发送请求时,服务器自动生成了一HashTable和一Session ID来唯一标识这个HashTable,并将其通过响应发送到浏览器。浏览器第二次发送请求会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。
一般这个值会有个时间限制,超时后毁掉这个值,默认30分钟。
当用户在应用程序的 Web页间跳转时,存储在 Session 对象中的变量不会丢失而是在整个用户会话中一直存在下去。
Session的实现方式和Cookie有一定关系。建立一个连接就生成一个session id,打开几个页面就好几个了,这里就用到了Cookie,把session id存在Cookie中,每次访问的时候将Session id带过去就可以识别了.
一个在客户端一个在服务端。因Cookie在客户端所以可以编辑伪造,不是十分安全。
Session过多时会消耗服务器资源,大型网站会有专门Session服务器,Cookie存在客户端没问题。
域的支持范围不一样,比方说a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。
利用成熟技术做session复制,如12306使用的gemfire,如常见内存数据库redis或memorycache,虽较普适但依赖第三方.
将 session维护在客户端,利用 cookie,但客户端存在风险数据不安全,且可以存放的数据量较小,所以将session 维护在客户端还要对 session 中的信息加密。
第二种方案和第三种方案的合体,可用gemfire实现 session 复制共享,还可将session 维护在 redis中实现 session 共享,同时可将 session 维护在客户端的cookie 中,但前提是数据要加密。
使用:
真正构建 Cookie是在 org.apache.catalina.connector. Response
类中完成的,调用 generateCookieString方法将cookie对象构造成一个字符串;构造的字
符串的格式如 userName=“ junshan"; Version=“1”; Domain=“ xulingbo. net"; Max-Age=1000。
然后将这个字符串命名为 Set- Cookie添加到 MimeHeaders中。
在这里有几点需要注意:
- 创建的 Cookie的NAME不能和 Set-Cookie或者 Set-Cookie2的属性项值一样,如果一样会抛 IllegalArgument Exception异常。
- 创建 Cookie的NAME和 VALUE的值不能设置成非ASSIC字符,如果要使用中文,可以通过 URLEncoder将其编码,否则将会抛 llIegalArgumentException异常。
- 当NAME和 VALUE的值出现一些 TOKEN字符(如“”、“,”等)时,构建返回头会将该 Cookie的 Version自动设置为1
- 当该 Cookie的属性项中出现 Version为1的属性项时,构建HTTP响应头同样会将 Version设置为1。
当我们通过 response.addCookie创建多个 Cookie时,这些 Cookie最终是在一个 Header项中还是以独立的 Header存在的,通俗地说也就是我们每次创建 Cookie时是否都是创建一个以NAME为 Set-Cookie的 Mimeheaders?答案是肯定的,从上面的时序图中可以看出每次调用 addCookie的时候,最终都会创建一个Header,但是我们还不知道最终在请求返回时构造HTTP响应头是否将相同Header标识的set- Cookie值进行合并。
Tomcat构造的Http响应头代码,这段代码位于org.apache.coyote.http11.Http11Processor类的propareResponse的方法中,如下所示:
可以看出在构建Http返回字节流是将Header中所有的项顺序地写出,而没有进行任何修改。所以浏览器在接收HTTP协议返回的数据时是分别解析每一个Header项的使用cookie的限制
session与cookie
下面详讲Session如何基于cookie来工作,实际上有三种方式能可以让 Session正常工作:
- 基于 URL Path Parameter,默认支持。
- 基于Cookie如果没有修改 Context容器的 cookies标识,默认也是支持的。
- 基于SSL,默认不支持,只有connector.getAttribute("SSLEnabled")为TRUE时才支持
第一种情况下,当浏览器不支持cookie功能时,浏览器会将用户的 SessionCookieName重写到用户请求的URL参数中,它的传送格式如 /path/Servlet;name =value;name2-value2.Name3=value3,其中“ Servlet:”后面的K-V就是要传递的 Path Parameters,,服务器会从这个 Path Parameters中拿到用户配置的 SessioncookieName,关于这个 SessioncookieName,
如果在 web.xml中配置 session-config 配置项,其 cookie-config下的name属性就是这个SessionCookieName值。如果没有配置了session-config配置项,默认的 SessionCookieName就是大家熟悉的“ JSESSIONID”。需要说明的一点是,与 Session关联的 Cookie与其他Cookie没有什么不同。接着 Reques根据这个 SessionCookieName到 Parameters中拿到Session ID并设置到 request.setRequestedSessionld 中。
请注意,如果客户端也支持 Cookie,Tomcat仍然会解析Cookie的 Session ID,并会覆盖URL中的Session ID
如果是第三种情况,將会根据 javax.servlet,request.ssl_session属性值设置 Session Id