`
yuwenlin2008
  • 浏览: 124772 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

WebApp之Session原理

阅读更多

  因为Http的无接连,无状态,所以造就了Cookie,Session的诞生。可以看我的上篇WebApp之Cookie原理。

  Session也是类似Cookie一样的功能,用于记录客户端浏览器与服务器端交互的会话状态。它与Cookie的重要区别是:
  1.Cookie是记录在客户端浏览器本地;(它是不可靠的,客户端浏览器可以不允许服务器记录,还可以删除。)
  2.Session是记录在服务器端的

  那么Session是如何记录的?
  当用浏览器访问服务器的一个请求时,如果要用到Session,服务器会为浏览器窗口开辟一块独一无二的session内存,当其它浏览器窗口再次访问服务器也想用Session时,服务器会为新的浏览器或窗口开辟一块的新的内存。


 
   那有个问题,比如当我第一个页面登陆以后,跳到第二个页面,服务器怎么就知道我是哪个浏览器,怎么知道我属于哪块Session内存呢?而是非常准确地定位到我第一次登陆时创建的那个Sesion,不是其它Session呢?其实这里有一个常用的方法解决这个问题,那就是标记——浏览器第一次来创建Session时,服务器创建一个独一无二的号码标记,标识这个浏览器窗口和这块Session内存是一对一的关系,并将这个标识存储在浏览器窗口中,同时也存储在对应的Session中,当浏览器窗口下次再来的时候把这个标识带过来,服务器就知道根据那个标识去定位Sesssion块了,这个标识就是sessionId,每个浏览器窗口都有一个独一无二的编号SessionId。

  那么就有个问题,SessionId存储在什么地方?假设Session已经存在,当浏览器访问过来,它应该要把SessionId带过来,因为只有这样,服务器才知道根据这个SessionId去定位内存中的哪个Session。所以这样一来,就有了两种创建Session的方式:
  1.通过Cookie,将SessionId存储在Cookie中
  2.通过URL重写,将SessionId作为参数传递

   先说第一种,存储在Cookie中有两种方法,可参考我的上篇WebApp之Cookie原理,即浏览器内存和本地文件。哪种存法比较好呢,显然是内存中,因为服务器端Session内存与浏览器窗口一一对应,浏览器窗口存在,SessionId就存在,浏览器窗口关闭了,SessionId留着就没意义了,新开一个浏览器窗口,SessionId就变了。因此通过Cookie创建Session是将SessionId存储在浏览器内存的Cookie中。这样浏览器每次访问服务器,服务器就可以取到SessionId了。

  那浏览器可以禁止服务器写入Cookie,当浏览器Cookie被禁止了以后,服务器根本无法写入SessionId,那Session就创建不了,也就用不了啦。所以就有了第二种方法:URL重写。
  第二种方法URL重写实现Session:
  response.encodeURL(String url);
  这个方法有两个作用:
  1.转码,当有中文时可以用它来编码,防止乱码。
  2.给URL后面加上SessionId

  测试时,我们可以将浏览器Cookie关闭,并将跳转到Session的URL地址用encodeURL()包起来。这时再访问就会发现,地址栏请求的URL后跟有参数jessionid。



 
  其实这种方式并不常用,如果要将一个网站的每个要访问Session的URL都这样包起来挺费劲的。只有少数大公司,写代码比较规范,严谨的公司才这么干,大部分公司都不会这么写,因为他们认为,你就应该开启Cookie,如果不开,那么你就用了Session,也就用不了他们服务,产品,像新浪,搜狐这样的大公司都这样。其实我们平时在公司做项目也从来不这样写,但那是因为我们不知道这个原理,至少我是到现在才知道的。现在知道了,也不会那样写,呵呵。

  下面以Java代码为例说明创建Session的方法:                                   
  HttpSessioin mySession= request.getSession(true);
  //这里的参数为true说明:如果窗口对应的Session已经有了,直接拿来用,不创建新的。如果窗口对应的Session没有,则创建一个新。反之参数为false的话:如果窗口对应的Session已经有了,直接拿来用,不创建新的。如果窗口对应的Session没有,也不创建新的。

  mySession.isNew();//看Session是不是新创建的

  mySession.getId();//得到SessionId即Cookie中存的Id

  mySession.getCreationTime();//创建时间

  mySession.getLastAccessTime();//最后一次访问Session 的时间,这个用于处理Session自动失效,后面说。

  request.getRequestedSessionId();//request也可以取得sessionId

  request.isRequestedSessionIdFromCookie();//sessionId是否来自Cookie

  request.isRequestedSessionIdFromURL();//sessionId是否来自URL重写

  Session的过期:
  我们知道Http是无连接的,浏览器请求服务器一个页面后,连接就断掉了。我们经常会发现登陆一个系统以后,很长时间不操作它,不去用它,过了些时间再用,它会提示我们重新登陆,这就是Session过期的原因。

  因为服务器不知道客户端浏览器还有没有在访问,可能客户端关机,断电了断网了等。但它服务器不知道,它没有必要为每个浏览器窗口一直保持Session内存不变,这消耗太大了,所以HttpSession有个过期设置,在tomcat的公共web.xml中有

  <session-config>
   <session-timeout>30</session-timeout>
  </session-config>
  Session超时设置,30单位为分钟,根据客户端浏览器最后一次访问服务器Session的时间算起超过个时间,服务器自动销毁Session,清除内存。这个时间我们自己可以改,把它拷到我们项目的web.xml重新设置时间可以了。

  Session的访问,只要是在一个WebApp下创建的Session,同一个WebApp下随便那个路径下都可以得到,不像Cookie一样有路径的问题,它没有。

  总结一下Session的规则:

  1.如果浏览器支持Cookie,创建Session时,会将sessionId存储于浏览器内存的Cookie中

  2.如果浏览器不支持Cookie,必须自己编程,使用URL重写的方式来实现Session:

   response.encodeURL();

 

  3.Session会过期,可以自己设置过期时间

 

  4.Session的访问没有路径问题,同一个WebApp下都可以访问得到。

  











 

  • 大小: 6.5 KB
  • 大小: 26.7 KB
1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics