Servlet的session理解

(一)引子

我们知道http是无状态协议,这意味着同一个浏览器发出的前后两次请求之间没有任何联系,请求得到响应之后这次连接就断开了,下一次发出的请求是全新的。

但是大部分业务不可能通过一次请求就能搞定,需要分好几个步骤(也就是发好几次请求),这些步骤在逻辑上必须要关联起来不能分开。比如某人在淘宝买东西,往购物车加一件东西就需要发一次请求,但是这些东西必须放到同一个人的购物车中,那么如何识别这些请求到底是不是来自同一人呢?如果没法识别,那么多人逛淘宝,我刚看中一件商品,结果加到别人的购物车中了,淘宝还不乱套了?

但是现在淘宝活的很滋润,说明必然有某种技术是可以识别请求到底是来自谁的,这就是cookie机制。这玩意儿的运作原理大概是这样:每次发请求的时候,在请求头加入一个cookie属性,长的一般都是下面这样子


Cookie: JSESSIONID=B62233B5E2AA568E02C7E10332EA56E9

这个等号后面的值就相当于一个身份证,用来识别请求来自哪里。同一个浏览器向同一个网站发出的请求都会使用同一个身份证,这样服务器就可以把拥有同一个身份证的请求视为同一个人的操作。这也就是所谓的会话(session)管理,将连续的请求在逻辑上关联起来,像一次会话,有上下文的联系。


(二)客户端(浏览器)的cookie管理

上面说,同一个浏览器向同一个网站发出的请求会拥有同一个sessionId(不管是这个浏览器打开多个窗口还是多个标签页),但是访问另一个网站的时候就不能再使用同一个sessionId;而同一台电脑不同的浏览器访问同一个网站时,使用的也是另一个sessionId。

这说明,每个浏览器都有自己的一套cookie管理机制;而同一个浏览器对每个不同的网站的sessionId也有一套机制。详细可以参考这里:http://hovertree.com/h/bjaf/tll89y8p.htm


(三)服务器端的身份识别

那么带着cookie的请求到达服务器之后又是如何被处理的呢?由于我个人比较熟悉Java,所以就以Servlet和Tomcat为例说明。

请求(默认8080端口)到达服务器后会被tomcat拦截,并将其封装成一个HttpServletRequest对象,然后将这个对象

的引用传递给相应的Servlet进行处理。

HttpServletRequest的API中有个getSession()方法,用来获取与该请求相关的Session对象。这说明,Tomcat在把请

求封装成HttpServletRequest对象的时候,其实已经提取过其cookie属性中的sessionId值了,然后根据这个值去寻找

跟它关联的Session对象,并将其引用赋值给HttpServletRequest实现类中的某个private属性。

这里要注意的是,第一次请求到来的时候,sessionId应该是空的,因而也就不存在与其关联的Session对象。实际上

,正常流程是,第一次请求的时候,服务器端的Servlet代码内调用了以下代码:

request.getSession();

有了这句代码,Tomcat才会建立一个Session对象,并为其生成一个Id值,同时在给这个第一次请求的)响应中

Header部分,加入一个指令“set-cookie: jsessionid=XXXX” ,这里的XXXX就是在服务器生成的sessionId。有了这个

指令,浏览器才会为这个网站建立cookie。也就是说,浏览器不会主动为某个网站建立cookie,cookie或Session的建

立是由服务器端主动发起的,SessionId也是服务器生成的。

那么第二次及以后再调用request.getSession();的时候,就可以找到与之关联的Session对象了,然后我们就可以把

request中的数据存放到这个Session对象中,这样就实现了会话。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值