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

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

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

  通过这个栗子,我们可以很好的理解了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,以及在面试当中常常遇到过的相关问题。

Cookie 机制

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

1.名字:即cookie的名字。

2.值:在Cookie中存入的值。

3.过期时间:如果不设置过期时间,则表示这个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 信息,增加了工作量。

java网络通信:HTTP协议 之 Sessions与Cookies的更多相关文章

  1. Java程序员从笨鸟到菜鸟之(十三)java网络通信编程

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 首先声明一下,刚开始学习java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所 ...

  2. Java实现SOAP协议 之 HelloWorld

    Java实现SOAP协议 之 HelloWorld SOAP是把基于HTTP的WEB技术与XML的灵活性和可扩展性组合在了一起. 准备: 1. 准备一个web server.Tomcat 下载地址 h ...

  3. 《转》Java与Http协议

    引言 http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式.HTTP协议的主要特点是:     1.支持客户/服务器模式.     2.简单快速:客户向 ...

  4. Java远程方法协议(JRMP)

    Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的.用于查找和引用远程对象的协议.这是运行在Java远程方法调用(RMI)之下.TCP ...

  5. java网络通信:异步非阻塞I/O (NIO)

    转: java网络通信:异步非阻塞I/O (NIO) 首先是channel,是一个双向的全双工的通道,可同时读写,而输入输出流都是单工的,要么读要么写.Channel分为两大类,分别是用于网络数据的S ...

  6. java 网络通信传输层协议——UDP和TCP

    本文原文由作者“zskingking”发表于:jianshu.com/p/271b1c57bb0b,本次收录有改动. 1.点评 互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯网专注的即时通 ...

  7. java网络通信:HTTP协议

    熟悉java的同学,都知道javaEE当中很大一部分的内容,是WEB开发,那么在进行WEB开发的学习过程当中,除了需要学习SpringMVC/STRUTS2等框架以外,我们还需要对在WEB开发当中常用 ...

  8. java网络通信:TCP协议

    面试的时候,面试官由于需要考察一个面试人对于网络编程的熟悉程度,往往会考察学生对于TCP.HTTP.UDP.这些常见的网络编程当中的协议的了解程度,而TCP协议则是首当其冲的,作为进程之间通信常用的一 ...

  9. Java 实现 SSH 协议的客户端登录认证方式--转载

    背景 在开篇之前,让我们先对 SSH 协议有个宏观的大致了解,这样更有利于我们对本文的加深了解.首先要提到的就是计算机网络协议,所谓计算机网络协议,简单的说就是定义了一套标准和规则,使得不同计算机之间 ...

随机推荐

  1. Java的位运算符—与(&)、非(~)、或(|)、异或(^)

    位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...

  2. CSS图片宽度设置百分比 , 高度同宽度相同

    在图片长宽不相等的情况下,想将长宽设置为相等并且自适应屏幕,可以通过 js 的方式进行设置并通过监听 resize 来实时更新,但是这种方式很麻烦. 这里通过 css 来达到我们想要的效果: < ...

  3. [USACO06NOV] Corn Fields

    https://www.luogu.org/problem/show?pid=1879 题目描述 Farmer John has purchased a lush new rectangular pa ...

  4. 关于ng-if的理论性知识你了解多少?

    ng-if简介: ● 使用ng-if指令可以完全根据表达式的值在DOM中生成或移除一个元素.如果赋值给ng-if 的表达式的值是false,那对应的元素将会从DOM中移除,否则对应元素的一个克隆将被重 ...

  5. .NET RabbitMQ

    在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这 种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方,比如发送短 ...

  6. IIS 搭建

    1. 在打开程序功能里面,点击IIS安装.注意要选择适当的各种有用的服务.例如默认文档就需要安装非IIS下面的选项. 2. IIS部署网站可以参考网上的步骤.会遇到500处理程序“Extensionl ...

  7. 「6月雅礼集训 2017 Day10」quote

    [题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...

  8. embed标签 阻止点击事件 让父元素处理点击事件

    由于规定页面显示的PDF文件要有固定大小,使得页面风格统一 最开始发现了CSS样式pointer-events 写出如下代码,在360急速浏览器急速模式中访问可在点击PDF控件时可跳转页面 <a ...

  9. Vue-$emit的用法

    1.父组件可以使用 props 把数据传给子组件.2.子组件可以使用 $emit 触发父组件的自定义事件. vm.$emit( event, arg ) //触发当前实例上的事件 vm.$on( ev ...

  10. rhel-server srpms iso

    http://ftp.redhat.com/pub/redhat/linux/enterprise/7Server/en/ ftp://ftp.pslib.cz/pub/linux/redhat-cz ...