- Session,即会话,是Web开发中的一种会话状态跟踪技术。固然,前面所讲述的Cookie也是一种会话跟踪技术。不一样的是Cookie是将会话状态保存在了客户端,而Session则是将会话状态保存到了服务器端。java
- 那么,到底什么是“会话”?当用户打开浏览器,从发出第一次请求开始,一直到最终关闭浏览器,就表示一次会话的完成。web
- Session并非JavaWeb开发所持有的,而是整个Web开发中所使用的技术。在JavaWeb开发中,Session是以javax.servlet.http.HttpSession的接口对象的形式出现的。算法
一、Session的访问:编程
a、Session对象的建立:浏览器
javax.servlet.http.HttpServletRequest接口中有两个方法,getSession()方法和getSession(boolean create)方法:缓存
- getSession()方法:用于返回与请求相关联的当前session,或者若是请求中没有session,建立一个并返回。安全
- getSession()方法:用于返回与请求相关联的当前session,或者传入的参数为true时,若是请求中没有session,建立一个并返回。(若是传入的参数为false时,不建立Session,返回null。)服务器
二、对Session域属性空间的操做:session
- Session是一个专门用于存放数据的集合,咱们通常称这个用于存放数据的内存空间为域属性空间,简称为域。HttpSession中具备三个方法,是专门用于对该域属性空间中数据进行写、读操做的。并发
三、Session的工做原理:在服务器中系统会为每一个会话维护一个Session。不一样的会话,对应不一样的Session。那么,系统是如何识别各个Session对象的?便是如何作到在同一个会话过程当中,一直使用的是同一个Session对象的?
a、写入Session列表:
- 服务器对当前应用中的Session是以Map的形式进行管理的,这个Map称之为Session列表。该Map的key为一个32位长度的随机串,这个随机串称之为JSessionID,value则为Session对象的引用。
- 当用户第一次提交请求时,服务器Servlet中执行到request.getSession()方法后,会自动生成一个Map.Entry对象,key为一个根据某种算法新生成的JSessionID,value则为新建立的HttpSession对象。
b、服务器生成并发送Cookie:
- 在将Session信息写入Session列表以后,系统还会自动将“JSESSIONID”做为name,这个32位长度的随机串做为value,以Cookie的形式存放到响应报头中,并随着响应,将该Cookie发送到客户端中。
c、客户端接收并发送Cookie:
- 客户端接收这个Cookie后会将其存放到浏览器的缓存中。即,只要客户端浏览器不关闭,浏览器缓存中的Cookie就不会失效。
- 当用户提交第二次请求时,会将缓存中的这个Cookie,伴随着请求的头部信息,一块发送给服务器
d、从Session列表中查找:
- 服务器从请求中读取到客户端发送来的Cookie,并根据Cookie的JSSESSIONID的值,从Map中查找相应key对应的value,即Session对象。而后,对该Session对象的域属性进行读写操做。
四、Session的失效:
- Web开发中引入的Session超时的概念,Session的失效就是指Session的超时。若某个Session在指定的时间范围内一直未被访问,那么Session将超时,即将失效。
- 在web.xml中能够经过<session-config>标签设置Session的超时时间,单位为分钟。默认Session的超时时间为30分钟。须要再次强调的是,这个时间并非从Session被建立开始计时的生命周期长,而是从最后一次被访问开始计时,在指定的时长内一直未被访问的时长。
- 若未到超时时限,也能够经过代码提早使Session失效。使用
javax.servlet.http.HttpSession接口中的invalidate()方法:五、Cookie禁用后使用Session进行会话跟踪:
- 从前面Session的工做原理可知,服务器之因此能够针对不一样的会话找到不一样的Session,是由于Cookie完成了会话的跟踪。可是,若客户端浏览器将Cookie禁用,那么服务器还怎么保证同一会话使用的是同一个Session呢?
- 若客户端浏览器禁用了Cookie,会发现向服务器所提交的每一次请求,服务器在给出的响应中都会包含名称为JSESSIONID的Cookie,只不过这个Cookie的值每一次都不一样。也就是说,只要客户端浏览器所提交的请求中没有包含JSESSIONID,服务器就会认为这是一个新的会话的开始,就会为其生成一个Map.Entry对象,key为新的32位长度的随机串,value为新建立的Session会话引用。这样的话,也就没法实现会话跟踪。
- 附加说明:
a、域属性空间范围对比:
- 在JavaWeb编程的API中,存在四个能够存放域属性的空间范围对象,这四个对象中所存储的域属性做用范围,由大到小分别为:
- ServletContext -> HttpSession -> HttpServletRequest -> PageContext
- ServletContext,即application,置入其中的域属性是整个应用范围的,能够完成跨会话共享数据。
- HttpSession,置入其中的域属性是会话范围的,能够完成跨请求共享数据。
- HttpServletRequest,置入其中的域属性是请求范围的,能够完成跨Servlet共享数据,可是这些Servlet必须在同一个请求中。
- PageContext,置入其中的域属性是页面范围的,不经常使用。
- 对于ServletContext,HttpSession,HttpServletRequest这三个域属性空间对象的使用原则是,在能够保证功能需求的前提下,优先使用小范围的。这样不只能够节省服务器内存,还能够保证数据的安全性。