点击上方 "程序员小乐"关注, 星标或置顶一起成长

第一时间与你相约

每日英文

Promise yourself to be so strong that nothing can disturb your peace of mind.

对自己承诺:我要强大到任何事情都无法破坏我内心的平和。

每日掏心话

每一发奋努力的背后,必是有加倍的赏赐。莫要去找借口失败,只找理由成功。也许现在你正面临一些困难,但是你别忘了,生活总是在向前,明天总是会更好。

来自:PatrickLee666 | 责编:乐乐

链接:juejin.im/post/5b7c1f4d6fb9a019f221ca14

程序员小乐(ID:study_tech)第 717 次推文 图片来自网络

往日回顾:你还在傻傻的从零搭建项目 ?看完这篇你就明白了!

正文

为什么需要cookie和session

在Web发展史中,我们知道浏览器与服务器间采用的是 http协议,而这种协议是无状态的,所以这就导致了服务器无法知道是谁在浏览网页,但很明显,一些网页需要知道用户的状态,例如登陆,购物车等。

所以为了解决这一问题,先后出现了四种技术,分别是隐藏表单域,URL重写,cookie,session,而用的最多也是比较重要的就是cookie和session了。

Cookie

是什么

cookie是浏览器保存在用户电脑上的一小段文本,通俗的来讲就是当一个用户通过 http访问到服务器时,服务器会将一些 Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器时,数据通过请求头又被完整地给带回服务器,服务器根据这些信息来判断不同的用户。

也就是说, cookie是服务器传给客户端并保存在客户端的一段信息,这个 Cookie是有大小,数量限制的!!

Cookie的创建

当前 Cookie有两个版本,分别对应两种设置响应头:“Set-Cookie”和 “Set-Cookie2”。在Servlet中并不支持Set-Cookie2,所以我们来看看Set-Cookie的属性项:

这些属性项,其他的都说的很清楚了,我们来看看Domain有什么用:

现在,我们假设这里有两个域名:

域名A:a.b.f.com.cn 域名B:c.d.f.com.cn

显然,域名A和域名B都是 f.com.cn的子域名

  • 如果我们在域名A中的Cookie的domain设置为f.com.cn,那么f.com.cn及其子域名都可以获取这个Cookie,即域名A和域名B都可以获取这个Cookie

  • 如果域名A和域名B同时设置Cookie的doamin为f.com.cn,那么将出现覆盖的现象

  • 如果域名A没有显式设置Cookie的domain方法,那么domain就为a.b.f.com.cn,不一样的是,这时,域名A的子域名将无法获取这个Cookie

好的,现在了解完了Set-Cookie的属性项,开始创建Cookie

Web服务器通过发送一个称为Set-Cookie的http消息来创建一个Cookie:

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

这里我们思考一个问题,当我们在服务器创建多个Cookie时,这些Cookie最终是在一个Header项中还是以独立的Header存在的呢?

我们可以看到,构建http返回字节流时是将Header中所有的项顺序写出,而没有进行任何修改。所以可以想象在浏览器在接收http返回的数据时是分别解析每一个Header项。

接着,在客户端进行保存,如何保存呢?这里又要对Cookie进行进一步的了解

Cookie的分类

  • 会话级别Cookie:所谓会话级别Cookie,就是在浏览器关闭之后Cookie就会失效。

  • 持久级别Cookie:保存在硬盘的Cookie,只要设置了过期时间就是硬盘级别Cookie。

好的,现在cookie保存在了客户端,当我们去请求一个URL时,浏览器会根据这个URL路径将符合条件的Cookie放在请求头中传给服务器。

Session

Cookie是有大小限制和数量限制的,并且越来越多的Cookie代表客户端和服务器的传输量增加,可不可以每次传的时候不传所有cookie值,而只传一个唯一ID,通过这个ID直接在服务器查找用户信息呢?答案是有的,这就是我们的session。

Session是基于Cookie来工作的,同一个客户端每次访问服务器时,只要当浏览器在第一次访问服务器时,服务器设置一个id并保存一些信息(例如登陆就保存用户信息,视具体情况),并把这个id通过Cookie存到客户端,客户端每次和服务器交互时只传这个id,就可以实现维持浏览器和服务器的状态,而这个ID通常是NAME为JSESSIONID的一个Cookie。

实际上,有四种方式让Session正常工作:

  • 通过URL传递SessionID

  • 通过Cookie传递SessionID

  • 通过SSL传递SessionID

  • 通过隐藏表单传递SessionID

第一种情况:

当浏览器不支持Cookie功能时,浏览器会将用户的SessionCookieName(默认为JSESSIONID)重写到用户请求的URL参数中。格式:/path/Servlet;name=value;name2=value2?Name3=value3

第三种情况:

会根据javax.servlet.request.ssl_session属性值设置SessionID。

注:如果客户端支持Cookie,又通过URL重写,Tomcat仍然会解析Cookie中的SessionID并覆盖URL中的SessionID

session工作原理

先看session工作的时序图

一、创建session

当客户端访问到服务器,服务器会为这个客户端通过request.getSession()方法创建一个Session,如果当前SessionID还没有对应的HttpSession对象,就创建一个新的,并添加到org.apache.catalina.Manager的sessions容器中保存,这就做到了对状态的保持。当然,这个SessionID是唯一的

二、session保存

由图可知,session对象已经保存在了Manager类中,StandardManager作为实现类,通过requestedSessionId从StandardManager的sessions集合中取出StandardSession对象。

我们来看看StandardManager时如何对所有StandardSession对象进行生命周期管理

当Servlet容器关闭:

StandardManager将持久化没过期的StandardSession对象(必须调用Servlet容器中的stop和start命令,不能直接kill)

当Servlet容器重启时:

StandardManager初始化会重读这个文件,解析出所有session对象。

三、session的销毁

这里有一个误区,也是我之前的错误理解,就是我将session的生命周期理解成一次会话,浏览器打开就创建,浏览器关闭就销毁,这样理解是错的!!

session的声明周期是从创建到超时过期

也就是说,当session创建后,浏览器关闭,会话级别的Cookie被销毁,如果没有超过设定时间,该SessionID对应的session是没有被销毁的,

检查session失效

检查每个Session是否失效是在Tomcat的一个后台线程完成的(backgroundProcess()方法中);除了后台进程检验session是否失效外,调用request.getSession()也会检查该session是否过期,当然,调用这种方法如果过期的话又会重新创建一个新的session。

小结

二者的异同

相同点(有关系的地方):

  • Session和Cookie都是为了让http协议又状态而存在

  • Session通过Cookie工作,Cookie传输的SessionID让Session知道这个客户端到底是谁

不同点:

  • Session将信息保存到服务器,Cookie将信息保存在客户端

工作流程

当浏览器第一次访问服务器时,服务器创建Session并将SessionID通过Cookie带给浏览器保存在客户端,同时服务器根据业务逻辑保存相应的客户端信息保存在session中;客户端再访问时上传Cookie,服务器得到Cookie后获取里面的SessionID,来维持状态。

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

Linux 系统 CPU 100% 异常排查实践与总结

动画演绎Java常用数据结构(建议收藏)

记录自己理解的一些设计模式

关注「程序员小乐」,收看更多精彩内容
嘿,你在看吗?

apache 设置session超时时间_深入分析 Session 和 Cookie,看这篇就对了相关推荐

  1. python怎么设置函数超时时间_在python运行时为函数设置超时秒数

    我遵循this解.在 我试图为我的函数during runtime设置超时秒数,这使我能够灵活地传递不同的timeout seconds,甚至不打开脚本(测试.py)在 在超时.py在from fun ...

  2. php iis session 超时设置,如何配置IIS Session超时时间

    原来IIS为了保护服务器,有一个"回收"的概念!测试了半天终于有了点大体了解(不要笑我菜^-^).先来看看这个"回收"在哪设置. 启动IIS管理器->应用 ...

  3. php session超时时间_php怎么设置session超时时间

    [摘要] PHP即"超文本预处理器",是一种通用开源脚本语言.PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言.PHP独特的语法混合了C.Java.Perl以及 ...

  4. session 超时时间设置

    在Java Web开发中,Session为我们提供了很多方便,Session是由浏览器和服务器之间维护的.Session超时理解为:浏览器和服务器之间创建了一个Session,由于客户端长时间(休眠时 ...

  5. java session时间_java session时长问题,java设置session超时时间实例

    java session超时设置你知道应该如何设置吗?下面要给大家带来的实例就是和java设置session超时时间相关的内容,一起来看看具体实现方式吧. 一般的系统登陆了之后,都会有设置一个当前的s ...

  6. php iis session 超时设置,如何配置IIS Session超时时间

    原来IIS为了保护服务器,有一个"回收"的概念!测试了半天终于有了点大体了解(不要笑我菜^-^).先来看看这个"回收"在哪设置. 启动IIS管理器->应用 ...

  7. httpclient 设置超时时间_面试官:技术选型,HttpClient还是OkHttp?

    你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 来源:juejin.im/post/6844904040644476941 推荐 ...

  8. 同时设置超时时间_刚入职的小菜鸡,设错了RPC超时,搞了个线上事故

    上面这张监控图,对于服务端的研发同学来说再熟悉不过了.在日常的系统维护中,『服务超时』应该属于监控报警最多的一类问题. 尤其在微服务架构下,一次请求可能要经过一条很长的链路,跨多个服务调用后才能返回结 ...

  9. mysql 事务 超时时间_设置事务超时时间的问题及数据库update和锁

    Oracle的update语句问题: update config t set t.value =1 where t.key='DB_ KEY' 或者: select * from config t w ...

最新文章

  1. 提高网站页面收录的几个方法 返回列表 发新帖回复
  2. 前沿丨DeepMind提出「心智神经网络ToMnet」,训练机器的「理解」能力
  3. How to use nheqminer in RedHat based systems (CentOS/Fedora)
  4. main函数的参数问题 (转载)
  5. [视频]youku与56客户端DLL却持
  6. 模拟实现单链表(三级)
  7. android闹钟——原代码【转】
  8. java aqs源码_java中AQS源码分析
  9. fragment中嵌套viewpager,vierpager中用fragment不显示数据
  10. php和python-Python与PHP:有什么区别?
  11. flume学习(三):Flume Interceptors的使用
  12. js知识梳理1:理解对象的属性特性
  13. 订单同步有技巧,双十一高峰不再怕
  14. Java - 两个对象值相同(x.equals(y) == true),但却可以有不同的hash code,这句话对不对?
  15. 程序员界之行业求职黑名单!实用!
  16. C++ 1179:奖学金
  17. Vue报错:contains both .browserslistrc and package.json with browsers
  18. 杨超越的经历故事性太强了,现实版的娱乐圈爽文
  19. protobuf详细介绍和使用
  20. 大连文思海辉php面试题,文思海辉前端面试题

热门文章

  1. 冲击中国超融合第一,浪潮的底气从何而来?
  2. 如果还不懂如何使用 Consumer 接口,就来看这篇!
  3. Nutanix企业云助力嘉里大通提升核心竞争力
  4. 云漫圈 | 我觉得我的手机被监听了。。。
  5. 引入的html设置utf-8,如何为default.html将字符编码设置为UTF-8?
  6. mysql查找无根节点sql_SQL 双亲节点查找所有子节点的实现方法
  7. 使用canal实现MySQL 8 增量同步数据到 ElasticSearch 7.15.2中 linux
  8. Elasticsearch7.15.2 安装、部署(linux环境)
  9. tomcat不重启java文件自动编译
  10. 在maven引入一个maven仓库中不存在的jar,安装本地底仓库