十四、Session底层的实现原理、Session对象的销毁、application与session、request的范围大小

1、关于web编程中的Session;
1)什么是会话:
 "目前"可以这样理解:用户打开浏览器,在浏览器上面发送多次请求,知道最终关闭浏览器,表示一次完整的会话。
在会话进行过程中,web服务器一直为当前这个用户维护着一个会话对象httpSessio
HttpSession 对象是一个会话级别的对象,一次会话对应一个HttpSession对象
Session表示会话,不止是在javaweb中存在,只要是web开发,都会有会话这种机制;
Cookie可以将回话状态保存在客户端,HttpSession可以将回话状态保存在服务器端。
备注:如果Cookie不设置有效期的话,被默认保存在浏览器缓存当中;当浏览器关闭的时候这个Cookie就没有了。

2)什么是一次会话?
 一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束
本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义上的一次完整会话。 

3)session底层的实现原理:
A、浏览器:
  在浏览器上发送首次请求给服务器;
B、服务器:
  服务器会创建一个HttpSession对象,该对象代表一次会话;
  同时生成HttpSession对象,对应的Cookie对象,并且Cookie对象的name名字是JSESSIONID,Cookie的value是32位长度的字符串
  服务器将Cookie的vaule和HttpSession对象绑定到session列表中
  服务器将Cookie完整发送给浏览器客户端
C、浏览器:
  浏览器客户端将Cookie保存到缓存中
备注:只要浏览器不关闭,Cookie不会消失(浏览器关闭的话,session对象是不销毁的,因为服务器和浏览器之间是基于http协议的,
http协议是一种无连接协议,或者说是无状态协议,因此不知道浏览器关了)
D、浏览器:
  当再次发送请求的时候,会自动提交缓存当中的Cookie。服务器接收到Cookie,验证Cookie的name(JSESSIONID)然后获取该Cookie的value
  通过Cookie的value去session列表中检索到对应的HttpSession对象。


2、浏览器禁用Cookie会出现什么问题?怎么解决?
1)浏览器禁用Cookie,则浏览器缓存中不再保存Cookie,导致在同一个会话中,无法获取到对应的会话对象。
2)禁用Cookie之后,每一次获取的会话对象都是新的。在浏览器中禁用Cookie之后很多web站点你是无法访问的。
备注:浏览器禁用Cookie之后,若还向拿到对应的Session对象,必须使用URL重写机制,怎么重写URL?
http://localhost/prj-servlet23/user/accessMySelfSession;jsessionid=D3E995BC5FD3B0518BF2966863E94D3E995BC5FD3B0518BF2966863E94
改值是通过httpwatch监听到的;
重写URL会给编程带来难度/复杂度,所以一般的web站点是不建议禁用Cookie的,建议浏览器开启cookie
  
3、浏览器关闭之后,服务器对应的session对象会被销毁吗?为什么?
1)浏览器关闭之后,服务器不会销毁session对象,因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议
2)什么是无连接/无状态的协议?
 请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束之后,通道关闭.这样做的目的是降低服务器的压力。
 
4、session对象在什么时候被销毁?
 web系统中引入了session超时的概念。
 当很长一段时间(这个时间可以配置)没有用户再访问session对象,此时session对象超时,web服务器自动回收session对象
 可配置:在web.xml文件中,默认是30分钟,实际开发过程中一般都配置成2个小时,表示2个小时之内没有人再访问就销毁该session对象;
 <session-config>
   <session-timeout>120</session-timeout>
 </session-config>

5、关于javax.servlet.http.HttpSession接口中常用的方法:
 void setAttribute(String name,Object value)
 Object getAttribute(String name)
 void removeAttribute(String name)
 void invalidate() 销毁Session

6、ServletContext、HttpSession、HttpServletRequest接口的对比:
 ServletContext application;是应用范围
 HttpSession session;是会话范围
 HttpServletRequest request;是请求范围 
 
 备注:三个范围的排序:application>session>request
 application完成跨会话共享数据
 session完成跨请求共享数据,但是这些请求必须在统一个会当中
 request完成跨servlet共享数据,但是这些Servlet必须在统一个请求当中【转发】
 
 使用原则:由小到大尝试
   越小越好,越小耗费的资源越小,优先使用小范围;
   例如向跨请求传递数据的话:
   ServletContext:可以完成跨请求共享数据,不是说不安全,是所有用户共享的。
   HttpSession:是一个用户一个,
   HttpServletRequest:一次请求一个。
   例如:登录成功之后,已经登录成功的状态需要保存起来,可以将登录成功的这个状态保存到session对象中
    登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象
    登录成功的状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享 
 备注:只要会话不关session永远之后一个,session中保存的数据你永远都能访问。只要你浏览器不关,你一直都能够访问。
 当你的浏览器关闭之后,你的session会话会超时,超时之后会自动销毁,销毁之后下次再访问就必须登录了。因为你的Session
 里面没有东西。
7、HttpServletRequest中的方法:
 HTTPSession session=request.getSession();获取当前的session,获取不到,则新建session
 HttpSession session=request.getSession(true);获取当前的session,获取不到则,新建Session
 HTTPSession session=request.getSession(false);获取当前的session,获取不到,则返回null;
  
   

posted @ 2017-02-17 11:27  爱笑的berg  阅读(2301)  评论(0编辑  收藏  举报