java网络通信:HTTP协议 之 Sessions与Cookies
通过前一篇博客的讲解,我们大体知道了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的更多相关文章
- Java程序员从笨鸟到菜鸟之(十三)java网络通信编程
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 首先声明一下,刚开始学习java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所 ...
- Java实现SOAP协议 之 HelloWorld
Java实现SOAP协议 之 HelloWorld SOAP是把基于HTTP的WEB技术与XML的灵活性和可扩展性组合在了一起. 准备: 1. 准备一个web server.Tomcat 下载地址 h ...
- 《转》Java与Http协议
引言 http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式.HTTP协议的主要特点是: 1.支持客户/服务器模式. 2.简单快速:客户向 ...
- Java远程方法协议(JRMP)
Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的.用于查找和引用远程对象的协议.这是运行在Java远程方法调用(RMI)之下.TCP ...
- java网络通信:异步非阻塞I/O (NIO)
转: java网络通信:异步非阻塞I/O (NIO) 首先是channel,是一个双向的全双工的通道,可同时读写,而输入输出流都是单工的,要么读要么写.Channel分为两大类,分别是用于网络数据的S ...
- java 网络通信传输层协议——UDP和TCP
本文原文由作者“zskingking”发表于:jianshu.com/p/271b1c57bb0b,本次收录有改动. 1.点评 互联网发展至今已经高度发达,而对于互联网应用(尤其即时通讯网专注的即时通 ...
- java网络通信:HTTP协议
熟悉java的同学,都知道javaEE当中很大一部分的内容,是WEB开发,那么在进行WEB开发的学习过程当中,除了需要学习SpringMVC/STRUTS2等框架以外,我们还需要对在WEB开发当中常用 ...
- java网络通信:TCP协议
面试的时候,面试官由于需要考察一个面试人对于网络编程的熟悉程度,往往会考察学生对于TCP.HTTP.UDP.这些常见的网络编程当中的协议的了解程度,而TCP协议则是首当其冲的,作为进程之间通信常用的一 ...
- Java 实现 SSH 协议的客户端登录认证方式--转载
背景 在开篇之前,让我们先对 SSH 协议有个宏观的大致了解,这样更有利于我们对本文的加深了解.首先要提到的就是计算机网络协议,所谓计算机网络协议,简单的说就是定义了一套标准和规则,使得不同计算机之间 ...
随机推荐
- [C#] 小记 new 和 override 关键字
C#要想实现函数的override,要求和C++一样,父类的函数必须用virtual关键字注明,随后在子类中用override关键字表明重写的函数. 子类同名函数定义时,如果什么都不写,或者使用new ...
- 关于微信内置浏览器安卓端session丢失问题
项目上线测试,发现微信安卓端存在用户登录无法验证session情况, 导致每次接口请求都无法识别,而苹果客户端不会出现此问题,非微信环境打开不会出现此问题,找到一些解决方案做下记录: 方案1: 由于微 ...
- 利用pdfJS实现以读取文件流方式在线展示pdf文件
第一步:下载源码https://github.com/mozilla/pdf.js 第二步:构建PDF.js 第三步:修改viewer.js var DEFAULT_URL = 'compressed ...
- 南阳ACM 题目811:变态最大值 Java版
变态最大值 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 Yougth讲课的时候考察了一下求三个数最大值这个问题,没想到大家掌握的这么烂,幸好在他的帮助下大家算是解决了 ...
- ZooKeeper翻译(一)
欢迎来到Apache ZooKeeper的世界 Apache Zookeeper是一个为了开发和维护一个开源的服务的一个尝试,这个服务使高可用的分布式协作成为可能. ZooKeeper是什么? Zoo ...
- 51Nod 1095 Anigram单词 | Hash
Input示例 5 add dad bad cad did 3 add cac dda Output示例 1 0 2 题意:一系列字符串,查询字符串S,能通过其他字符串交换串内字符顺序得到的字符串个数 ...
- linux sh脚本异常:/bin/sh^M:bad interpreter: No such file or directory
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory.这是不同系统编码格式引起的:在windows系统中编辑的. ...
- 关于scala 集合 List Map Set
1,数组 2,List,ListBuffer 3, Map , mutable.Map
- 【Windows使用笔记】使Onedrive同步任意文件夹
因为度盘实在是有点垃圾,经常看的剧之类的或者其他软件资源啥的动不动就被封. 所以跑去某宝买了一个5T的企业子账号,安全性不清楚,重要的隐私数据反正都用移动硬盘备份了.主要就是存一些资源性的文件吧.而且 ...
- TCP之Nagle算法与延迟ACK
(一)Nagle算法 为了减少网络中小分组的数目,减少网络拥塞的情况.Nagle算法要求在一条TCP连接上最多只能有一个未被确认的未完成小分组,在该分组ACK到达之前不能够发送其他的小分组,发送端需要 ...