java网络通讯:HTTP协议 之 Sessions与Cookies

  经过前一篇博客的讲解,咱们大致知道了HTTP协议是什么,它有什么组成,以及它的工做原理,那么在HTTP的不少特色中,有一点叫作,无状态,就HTTP是一个无状态的协议,若是须要前面的信息用于处理后边的请求,那么在HTTP当中,就须要对前边的信息进行重发,这一点是很不方便的,那么为了解决HTTP在用于须要记录前边信息的场景的问题,提出了这么两个概念,Session和Cookie。那么咱们先来了解一下Session是什么呢?html

  Session,顾名思义,中文含义是会话,如同前文所述,它是用于解决一类用来在客户端与服务器之间保持状态的解决方案,在java当中讨论的Session,一般指的是javax.servlet.http.HttpSession,能够看出Session它自己是一个对象,那么在这个对象当中主要包含了如下几个要素:1.属性,用于存储Request当中的各种信息。2.SessionID,用于映射相应Request的标识。也许这么说,可能有一些不大清晰,那么咱们仍是老规矩,举一个栗子来讲:java

  假设咱们的WebServer是一个商场的储物处,而每个HTTP Request是一个来商场购物的顾客,那么顾客须要在商场当中存包,管理员会将顾客的包放到相应的储物柜,当中而这个储物柜就至关于Session,而且交给顾客相应的号码牌做为顾客离开的时候要取包的凭证,而且以后一段时间这个储物柜就只交给这个顾客使用了,这个号码牌就是SessionID。那么等这个顾客(HTTP Request)下次来的时候,只须要初始相应的号码牌(SessionID),储物处(WEB Server)就会将客户须要用的储物柜(Session)交个顾客使用,顾客能够在储物柜里头放东西(存入相应的属性,setAttribute)以及取东西(getAttribute)等,固然,商场的储物处也能够将顾客的储物柜给取消,而后给其余客户使用。当顾客离开商场的时候(这时候顾客变成了HTTP Response),商场的储物间还会友情的提示储物柜的编号告诉顾客(将SessionID放入Response当中),以防顾客下次忘记带来号码牌。这样顾客下次过来的时候,又会带着相同的号码牌。mysql

  经过这个栗子,咱们能够很好的理解了Session与HTTP Request和WEB Server之间的关系咯吧?Request和WEB Server就是依靠Session对该次状态进行记录,而且下次访问的时候,就会经过相同的SessionID获取到上一次的状态,解决了HTTP的无状态的问题,那么咱们在标题当中提到的Cookie又是什么东西呢?其实,Cookie就是咱们在例子当中提到的 “号码牌”,这个号码牌就放在客户端的(存储与浏览器的)一位顾客不可能一生只去一个商场,那么这个顾客手上就会有不少 “号码牌”,当顾客想去其中的某一个商场的时候,就会在本身手里找一找有没有那个商场的号码牌(查找符合做用域的Cookie)而后带着这个号码牌去相应的商场进行存包取包等操做。面试

  这个例子呢,只是让咱们对HTTP Request、WEB Server、Cookie、Session、HTTP Response之间的关系作一个大致的了解,那么接下来,咱们开始正经的介绍在HTTP当中的Cookie和Session,以及在面试当中经常遇到过的相关问题。sql

 

Cookie 机制数据库

  Cookie在浏览器的生成,主要是经过拓展HTTP协议来实现的,在第一次访问WEB Server的时候,WEB Server会在响应的HTTP Response当中的响应报头添加一行特殊的指示,提示浏览器在本地保存相应的cookie(至关于顾客第一次来商场的储物处存东西,管理员为顾客分配一个储物柜,而后给顾客一个号码牌,要求顾客要拿着)。而这个Cookie的主要内容主要包括如下几点:浏览器

1.名字:即cookie的名字。tomcat

2.值:在Cookie中存入的值。服务器

3.过时时间:若是不设置过时时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie通常不存储在硬盘上而是保存在内存里,固然这种行为并非规范规定的。若是设置了过时时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过时时间。cookie

4.路径和域:指定某一个域好比.google.com,也能够指定一个域下的具体某台机器好比www.google.com,路径就是跟在域名后面的URL路径,好比/或者/foo,路径与域合在一块儿就构成了cookie的做用范围。

这里提到一点,当设置了过时时间的cookie被存在硬盘以后,能够在不一样的浏览器进程间共享。对于Mozilla Firefox0.8,全部的进程和标签页均可以共享一样的cookie。

 

Seesion 机制

  session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。当某个客户端发起HTTP Request,并须要使用一个Session的时候,WEB Server首先会检查在这个Http Request里头有没有相应的SessionID,若是已包含一个SessionID则说明之前已经为此客户端建立过session,服务器就按照session id把这个session检索出来使用(若是检索不到,可能会新建一个),若是客户端的Http Request中不包含session id,则为此客户端建立一个session而且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应Http response中返回给客户端保存。

  这里要格外的提一点,以前的例子当中,一直说SessionID,是用Cookie来进行保存的,这是固然能够的,cookie的名字都是相似于SEEESIONID,可是当客户端(浏览器)禁用Cookie的话,是否是就意味着这个SessionID无法存储了呢?固然是不可能的啊。

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

 

了解完Session和Cookie机制以后,咱们来看看一些面试当中的干货。

 

Session常见问题

 

1.Session建立的时间:人们常有一个误解就是觉得Session是在有客户端访问的时候就必定会被建立,然而事实是到某个Server端程序调用了HttpServletRequest.getSession(true)这样的语句时才被建立,即在打开浏览器第一次请求该jsp的时候,服务器会自动为其建立一个session(JSP没有显示关闭Session的时候),在JSP的默认编译成Servlet时将会自动加上这样一条语句 HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的 session对象的来历。若是不须要在JSP当中使用Session的话,须要显示的声明关闭Session,<% @page session="false"%>。

注意:访问*.html的静态资源由于不会被编译为Servlet,也就不涉及session的问题、

 

2.Session删除的时间:知足如下三种状况,则会删除Session。

1)Session超时:超时指的是连续必定时间服务器没有收到该Session所对应客户端的请求,而且这个时间超过了服务器设置的Session超时的最大时间。

2)程序调用HttpSession.invalidate()

3)服务器关闭或服务中止(通常状况下,session是不作持久化的。)

除了以上状况,均不会删除Session,好比关闭浏览器,是不会删除Session的,只会删除会话Cookie(没有被存入硬盘的Cookie)

 

3.session存放在哪里:存放于服务器的内存当中,也能够作特殊处理进行持久化,存入数据库或者硬盘。

 

4.SessionID的生成和使用:当客户端第一次请求服务器。且须要应用到Session的时候,服务器会为客户端建立一个Session,而且相应的生成一个SessionID用来表示该Session,当浏览器下次(session继续有效时)请求别的资源的时候,浏览器会自动地将SessionID放置到请求头中,服务器接收到请求后就获得该请求的SessionID,服务器找到该id的Session 返还给请求者(Servlet)使用。一个会话只能有一个Session对象,对Session来讲是只认id不认人。

 

5.同一客户端机器屡次请求同一个资源,session是否同样:对于多标签的浏览器(好比360浏览器)来讲,在一个浏览器窗口中,多个标签同时访问一个页面,session 是一个。对于多个浏览器窗口之间,同时或者相隔很短期访问一个页面,session是多个的,和浏览器的进程有关。

 

总结一下:Session是一个容器,能够存放会话过程当中的任何对象,Session由于请求(request对象)而产生,同一个会话中多个request共享了一Session对象,能够直接从请求中获取到Session对象,而且其实,session的建立和使用总在服务端,而浏览器历来都没获得过session对象。但浏览器能够请求Servlet(jsp也是 Servlet)来获取session的信息。客户端浏览器真正牢牢拿到的是session ID,而这个对于浏览器操做的人来讲,是不可见的,而且用户也无需关心本身处于哪一个会话过程当中。

 

6.Session共享的方法

1)客户端Cookie保存:客户端Cookie保存以cookie加密的方式保存在客户端.

优势是减轻服务器端的压力,每次session信息被写在客服端。而后经浏览器再次提交到服务器。即便两次请求在集群中的两台服务器上完成,也能够到达session共享。

2)服务器间Session同步:使用服务器间session同步使用主-从服务器的架构,当用户在主服务器上登陆后,经过脚本或者守护进程的方式,将session信息传递到各个从服务器中,这样用户访问其它的从服务器时,就能够读到session信息。 缺点:好比速度慢、不稳定等,另外,若是 session 信息传递是主->从单向的,会有一些风险,好比主服务器down了,其它服务器没法得到 session 信息

3)使用集群管理Session(如MSM) :使用集群统一管理Session提供一个集群保存session共享信息.其余应用通通把本身的session信息存放到session集群服务器组。当应用系统须要session信息的时候直接到 session 集群服务器上读取。目前大多都是使用 Memcache 来对 Session 进行存储。目前比较流行的两种方案:

a) 使用Filter方式:此方式使用过滤器的方式从新对httpRequest 对象进行了包装,并加入memcached客户端,此方式的优势是:使用简单,把过滤器配置进去便可,另外比较灵活,由于它是在客户端实现的,配置比较灵活,并且服务器无关,你能够在任何支持servlet的容器上部署。
b)使用Memcached-Session-Manager,俗称MSM,是一个用于解决分布式 tomcat 环境下 session 共享的问题的开源解决方案。它的实现原理为以tomcat插件的方式部署在服务器,修改了 servlet 容器代码中的 session 相关代码,使其链接 memcached ,在 memcached 中建立和更新session。

4)把Session持久化到数据库:将session持久化到数据中这种共享session的方式即将session信息存入数据库中,其它应用能够从数据库中查出session信息。目前采用这种方案时所使用的数据库通常为mysql。 利用数据库共享 session 的方案有必定的实用性,但也有以下缺点:首先 session 的并发读写在数据库中完成,对 mysql 的性能要求比较高;其次,咱们须要额外地实现 session 淘汰(超时)逻辑代码,即定时从数据库表中更新和删除 session 信息,增长了工做量。

相关文章
相关标签/搜索