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 信息,增加了工作量。

时间: 2024-08-04 20:06:32

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

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

本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 首先声明一下,刚开始学习java网络通信编程就对他有一种畏惧感,因为自己对网络一窍不通,所以...呵呵..你懂得,昨天又仔细的学习了一遍,感觉其实java网络编程也没想象的那么难,不信,咱一起看看...呵呵.. 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大

Java实现SOAP协议 之 HelloWorld

Java实现SOAP协议 之 HelloWorld SOAP是把基于HTTP的WEB技术与XML的灵活性和可扩展性组合在了一起. 准备: 1. 准备一个web server.Tomcat 下载地址 http://tomcat.apache.org/ 本例使用版本 apache-tomcat-7.0.54-windows-x64.zip 2. 写一个servlet send用来发送一个SOAP的message并添加一个附件. 3. 写一个servlet receive用来做SOAP message

Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar)

 该工具Jar包可在:http://download.csdn.net/detail/shenjianox/7769783及文档下载地址 ganymed-ssh2简介: Ganymed SSH-2 for Java是用纯Java实现SSH-2协议的一个包.在使用它的过程中非常容易,只需要指定合法的用户名口令, 或者授权认证文件,就可以创建到远程Linux主机的连接,在建立起来的会话中调用该Linux主机上的脚本文件,执行相关操作. 使用方法: 将 ganymed-ssh2-build210.

Java远程方法协议(JRMP)

Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的.用于查找和引用远程对象的协议.这是运行在Java远程方法调用(RMI)之下.TCP/IP之上的线路层协议. JRMP是一个Java特有的.适用于Java之间远程调用的基于流的协议,要求客户端和服务器上都使用Java对象.

java使用UDP协议传输数据

UDP协议(User Datagram Protocol,用户数据报协议)不同于TCP协议,它是不可能靠的,但是它比TCP协议具有更快的传输速度,UDP发送的数据单元称为数据报,当网络传输UDP传输UDP数据报是无法保证数据能够到达目的地,也无法保证按发送的顺序到达目的地,也就是说先发送了"hello",再发送了"world",但接收方可能会先收到"world",再收到"hello",也有可能收不到数据,为什么呢?因为它是不可

Java Web HTTP协议的提交方式

TTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式: OPTIONS 返回服务器针对特定资源所支持的HTTP请求方法.也可以利用向Web服务器发送'*'的请求来测试服务器的功能性. HEAD 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回.这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息. GET 向特定的资源发出请求.注意:GET方法不应当被用于产生“副作用”的操作中,例如在Web App

java网络通信:TCP协议

面试的时候,面试官由于需要考察一个面试人对于网络编程的熟悉程度,往往会考察学生对于TCP.HTTP.UDP.这些常见的网络编程当中的协议的了解程度,而TCP协议则是首当其冲的,作为进程之间通信常用的一种协议,只要岗位涉及到了进程之间的相互通信,则一定会被询问到TCP协议,那么本篇就来总结一下TCP协议吧~ TCP协议在OSI七层模型当中,是属于传输层的协议,它是一种可靠传输的协议,这个可靠,指的是TCP可以确保通信信息不会因为网络因素导致丢包,确保接受方一定可以接受到完整的数据.在TCP可靠传输

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

背景 在开篇之前,让我们先对 SSH 协议有个宏观的大致了解,这样更有利于我们对本文的加深了解.首先要提到的就是计算机网络协议,所谓计算机网络协议,简单的说就是定义了一套标准和规则,使得不同计算机之间能够进行正常的网络通信,不至于出现在一台机器上发出的指令到另一台机器上成了不可认的乱码,SSH 就是众多协议的其中之一.经典的七层 OSI 模型(Open System Interconnection Reference Model)出现后,大大地解决了网络互联的兼容性问题,它将网络划分成服务.接口

网络通信 --&gt; 互联网协议(二)

互联网协议(二) 一.对上一节的总结 我们已经知道,网络通信就是交换数据包.电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从而实现两台电脑之间的通信.数据包的结构,基本上是下面这样: 发送这个包,需要知道两个地址: * 对方的MAC地址 * 对方的IP地址 有了这两个地址,数据包才能准确送到接收者手中.但是,前面说过,MAC地址有局限性,如果两台电脑不在同一个子网络,就无法知道对方的MAC地址,必须通过网关(gateway)转发. 上图中,1号电脑要向4号电脑发送一个数据包.它先判断