session机制与servlet中的session

      借鉴了这两篇文章: https://www.cnblogs.com/lonelydreamer/p/6169469.htmlhttps://www.cnblogs.com/lonelydreamer/p/6169197.html

      在网络协议中,session包含着“面向连接”或“保持状态”含义,之所以有人会理解成session指的是浏览器从打开到关闭的过程,那是因为session id可以存储在cookie中。在web开发环境中,session指的是用来在客户端和服务器之间保持状态的解决方案。各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持,比如经常把Java里提供的javax.servlet.http.HttpSession简称为session。

        HTTP协议本身是无状态的,由于种种原因也最好不要使其变得有状态,但是按需生成动态信息会使web变得更加方便、有用。所以就出现了一些为了解决HTTP无状态缺陷的解决方案,就出现了cookie和session。

       现在来看看cookie和session的区别和联系。举一个例子来说明,一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:

1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。 

    2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。 

    3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。 

    这三种解决方案,第一种类似于让HTTP协议变为有状态的协议,第二种类似于cookie,让客户端保留状态的方案,第三种类似于session,在服务端保留状态的方案。同时注意到,在服务端保留状态的同时,在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。 

cookie机制

      cookie机制的原理和方案二类似,由客户端保留状态,但还需要明白这样几个问题,cookie如何分发(产生),cookie中包含哪些内容,以及客户端如何使用cookie。

     首先来解决第一个问题,cookie通过扩展HTTP协议来实现,服务器通过在HTTP响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。另外,纯粹的客户端脚本如JS也可以生成cookie。

     再来看第二个问题,浏览器按照一定原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在位置,则把cookie负载请求资源的HTTP请求头上发送给服务器。

     cookie的内容主要包括:名字,值,过期时间,路径和域。其中域可以是一级域名,也可以是二级域名。路径就是跟在域名后的URL路径,路径和域组合构成cookie的作用范围。若不设置过期时间,则表示cookie的生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就会消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。 

存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。

session机制

        session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

        首先来看创建session的过程,简单说就是首先看请求有没有session,有就用,没有就自己创建。

        当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。

       那么session id保存在哪里呢?session id可以采用cookie保存,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。

但是cookie是可以被人为禁止的,此时需要使用其他的方法将session id传回服务器。比较常用的一种方式是URL重写, 就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 

另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 

这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。 
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。

        如果session id被保存在会话cookie中,将导致浏览器一旦关闭,session id就会消失。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。 恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。 

       HTTP Session 

       HttpSession是Java平台对session机制的实现规范,因为它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。但web服务器中都会提供一系列的参数来控制它的HttpSession的实现,包括使用cookie的开关选项,使用URL重写的开关选项,session持久化的设置,session失效时间的设置,以及针对cookie的各种设置,比如设置cookie的名字、路径、域,cookie的生存时间等。 


    一般情况下,session都是存储在内存里,当服务器进程被停止或者重启的时候,内存里的session也会被清空,如果设置了session的持久化特性,服务器就会把session保存到硬盘上,当服务器进程重新启动或这些信息将能够被再次使用,Weblogic Server支持的持久性方式包括文件、数据库、客户端cookie保存和复制。 

      在Java中,HTTP的Session对象用javax.servlet.http.HttpSession来表示。在这里基于Java Servlet理解Session的概念与原理,这里所说Servlet已经涵盖了JSP技术,因为JSP最终也会被编译为Servlet,两者有着相同的本质。

     1、概念:Session代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续的。在Servlet中,session指的是HttpSession类的对象。

      2、Session创建的时间:一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用 HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 <% @page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句 HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的 session对象的来历。

       由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。

       需要注意的两点是

      (1)访问*.html的静态资源因为不会被编译为Servlet,也就不涉及session的问题。

       (2)当JSP页面没有显示禁止session的时候,在打开浏览器第一次请求该jsp的时候,服务器会自动为其创建一个session,并赋予其一个sessionID(session的创建和使用总在服务端,而浏览器从来都没得到过session对象。但浏览器可以请求Servlet来获取session的信息。),发送给客户端的浏览器。以后客户端接着请求本应用中其他资源的时候,会自动在请求头上添加:

Cookie:JSESSIONID=客户端第一次拿到的session ID。这样,服务器端在接到请求时候,就会收到session ID,并根据ID在内存中找到之前创建的session对象,提供给请求使用。这也是session使用的基本原理。

      

3、Session删除的时间是:

1)Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。

2)程序调用HttpSession.invalidate()

3)服务器关闭或服务停止

 

4、session存放在哪里:服务器端的内存中。不过session可以通过特殊的方式做持久化管理。

       

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值