来谈一谈session

 

     Session相信作为一个开发的同学并不陌生,附上百度百科的定义:Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。说的很好,但是好像不知所云。

    那session到底是啥呢?为何要有session呢?众所周知,http协议是无状态的,但是在web程序中我们一般会需要有状态,也必须有状态,怎么说呢?比如我们登录了一个网站,当发起下一个请求的时候,正因为http的无状态,我们并不知道之前登录过了,那如何让我们知道已经登录过呢?这时候session便来了,当然还有种解决方案早已产生-cookie但cookie是保存在客户端的。那java web容器中对session如何实现的呢?下面以tomcat为例,来看下session实现。

  • session是如何生成的呢。

在tomcat中,StandardSession为session的标准实现类。先说下这个类最重要的一个成员变量

     这个类维护了一个map集合,一个线程安全的map,是不是很熟悉的名字,对就是他,当我们去setAttribute的时候实际上就是将对象加入这个map集合。当然你操作的session对象并不是他的实例,而是StandardSessionFacade他的实例,通过他维护了一个StandardSession。卧槽,是不是很熟悉,对,这就是所谓的外观设计模式。

     现在看下session的产生,其实session的产生归根结底是因为调用了request中的doGetSession方法,看下这个方法(篇幅有限省略部分代码):

 

       应用程序中的session交给了Manager去维护,manager维护了一个map集合,key就是sessionid,value便是session对象。首先通过一个requestedSessionId变量(就是要去查找的sessionid,这个一会再说)去查找session,找到返回,找不到则判断create是否为true,如果是,则去创建一个session.

中间方法代码就不粘贴了,有兴趣自己点点。创建完成后,又做了什么呢?那就是创建了一个名字为JSESSIONID 的cookie(默认情况下),然后把sessionid保存到了cookie中。是不是很熟悉的名字。

到此session已经生成并放在cookie中,下次访问便会带上cookie,这一步是浏览器完成的。

  • Session又是何时产生的呢?

  知道了session的生成,那session又是何时产生的呢?对于这个问题,网上很多博客之类的都再说一般打开浏览器第一次访问网站是产生,这个一般值得思考,何时不一般嗯?继续看图:

 

 

第一次访问,与第二次访问的请求与响应,可以看到第一次响应中有set-cookie字段,有个JSESSIONID的cookie,第二次请求头中有相同的cookie,根据之前分析,我们知道现在确实生成了session.但是看下面请求:

 

 

哎呀,并没有哦。其实session的产生只有一种时机那便是调用了doGetSession,哈哈,感觉和没说一样,那何时调用呢?我们怎么获取的session一定记得吧,request.getSession();那我们看下这个方法:

哈哈,果真调用了doGetSession,而且参数为true,没有及创建,即第一次调用时创建。那么疑问来了,我打开页面并没有调用这个方法哦。这个时候我们就要说到我们基础知识,jsp九大内置对象,我也背不过,但是我知道一定有session,这个时候session是在小猫解析jsp的时候生成的,有图为证,下面是解析出来的jsp,就是一个servlet

看下pagecontext中的session:

果然调用了getSession,懂了吧。另外会发现有个needsSession的参数,为什么呢?那是因为jsp提供了禁止自动创建session的功能,配置<%  page  session="false"  %>

  到此明白了吗?

  • Session的有效期

提到session失效,一定会得到这样的答案:浏览器关闭。是的,session的最长生命周期就是浏览器打开到关闭。说最长,起点已经了解,终点呢?这个都知道,session可以配置失效时间,也可以手动失效,这里不讨论这个。假定大于浏览器关闭时间。那为什么关闭浏览器失效呢?那是因为我们生成session时,生成的放置sessionid的cookie没有设定有效期,cookie默认有效期即浏览器打开到关闭,这种cookie并没保存在本地,而是保存在浏览器内存中。当cookie都没有了,哪里去找session?

 但,要明白一件事情,这里的失效,并不是session对象没有了,而是找不到他的id了,如果有之前的sessionid,依旧可以获取session对象。这就好比,我们脑子忘记了一个人,并不是这个人没有了,而是你忘记她的名字了呢。

  • Cookie被禁用了怎么办

最后一个问题,我们之前一直在说session依赖于cookie,那么cookie被禁用了呢?你可以去做一件事情,禁用cookie,登录简书,你会发现我擦登录不上了。难道cookie被禁用了session就完蛋了吗?答案当然是,NO!

说到这里,我们就要说一说之前的提到的requestedSessionId。找到tomcat中网络协议的处理类CoyoteAdapter。

其中这个方法解析一次request请求。

这便是这个变量的获取及设置逻辑,解释一下,sessionId依次在url,cookie,ssl请求中获取,一个个看。

首先在路径参数中获取,这个参数可不是你一般理解的参数,这个是路径后以;结尾的参数,专门处理sessionid,其他加了也没意义。看参数名字,默认jsessionid

 

然后再cookie中获取,依据的名字就不说了,和之前一样,并设置浏览器cookie可用

好了,现在你大概知道cookie禁用是如何传递session了吧,url后面加;jsessionid=xxxxxxx,tomcat提供了url重写的方法,当cookie可用时原路返回,不可用时,加上jsessionid参数,前提是session已经生成。

用法如:

  <a href=“<%=response.encodeRedirectURL(“index.jsp“)%>

 另外有一点很有意思,当禁用iecookie,但是访问是用localhost的访问,这时候浏览器依旧有cookie产生,但是用ip访问就不会,别问为什么我也不知道,要问就得问微软0.0。我试过谷歌,火狐,IE,只有IE这样,可以自己试下。

  • 关于http协议

   何为协议,打个比方,你与某人做生意之前,定好了12345.。等等规矩,突然有一天他没有遵守某一规矩,我想这生意应该也没法做了,http协议便是网络通信双方定的规范规矩,约定好这就是标准,如果不按约定发送信息,同样也没法通信了。下面是我截取到tomcat接收到及发送的消息,看下或许就明白了。

接收到的请求:

返回的响应:

好了,写完了,可能大神这个都知道,但是作为像我一样的小菜,不一定知道哦,希望能对大家能有帮助

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值