深入理解Session与Cookie

理解Cookie

       当一个用户通过HTTP访问一个服务器时,服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件;在条件符合时,这个用户再次访问这个服务器时,数据又被完整地带回给服务器;

       好比,你去超市购物,第一次给你办了张购物卡,在这张购物卡上存放了你的个人信息,下次再来购物的时候,超市会识别你的购物卡,直接购物即可;

       当初设计Cookie时,实际上考虑的是为了记录用户在一段时间内访问Web应用的行为路径;由于HTTP是一种无状态的协议,当用户的一次访问请求结束后,服务器就无法知道下次来访问的还是不是上次访问的用户;

       例如,在一个很短的时间内,如果与用户相关的数据被频繁访问,可以针对这个数据做缓存,这样可以大大提高数据的访问性能; Cookie的作用正是如此,由于是同一个客户端发出的请求,每次发出的请求都会带有第一次访问时服务端设置的信息,这样服务端就可以根据Cookie的值来划分访问的用户;

Cookie的属性项

       Cookie有两个版本:Version 0和Version 1;它们有两种设置响应头的标识,分别是"Set-Cookie"和"Set-Cookie2";



Servlet规范并不支持Set-Cookie2响应头,在实际应用中Set-Cookie2的一些属性项却可以设置在Set-Cookie中;

Cookie是如何工作的

String getCookie(Cookie[] cookies,String key){
     if(cookie != null){
         for(Cookie cookie : cookies){
              if(cookie.getName().equals(key)){
                  return cookie.getValue();
              }
         }
     }
     return null;
}

@Override
public void doGet(HttpServeltRequest request,
                  HttpServletResponse response) throws IOException,ServletException {
      Cookie[] cookies = request.getCookies();
      String userName = getCookie(cookies,"username");
      String userAge  = getCookie(cookies,"userAge");
      if(userName == null){
          response.addCookie(new Cookie("username","junshan"));
      }
      if(userAge == null){
          response.addCookie(new Cookie("userAge","28"));
      }
      response.getHeaders("Set-Cookie");
}

       当我们用Servlet 3.0规范创建一个Cookie对象时,该Cookie即支持Version 0也支持Version 1;如果你设置了Version 1中的配置项,即使你没有设置版本号,Tomcat在最后构建HTTP响应头时也会自动将Version的版本设置为1;

       下图是Tomcat创建Set-Cookie响应头的时序图;


       从上图可以看出,真正构建Cookie是在Response类中,调用generateCookieString()将Cookie对象构造成一个字符串,构造的字符串的格式如userName="junshan";Version="1";Domain="xulingbo.net";Max-Age=1000。最后将这个字符串命名为Set-Cookie添加到MimeHeaders中;


       当我们通过response.addCookie创建多个Cookie时,即每次调用addCookie时都会创建一个Header;但是,最终在请求返回时构造的HTTP响应头是否将相同Header标识的Set-Cookie值进行合并;在构建HTTP返回字节流的时候,是将Header中所有的项顺序地写出,而没有进行任何的修改;所以,浏览器在接收HTTP返回的数据的时候是分别解析每一个Header项的;

       当我们请求某个URL路径时,浏览器会根据这个URL路径将符合条件的Cookie放入Request请求头中传回给服务端,服务端根据request.getCookies()来取得所有的Cookie;

使用Cookie的限制

Cookie是HTTP头中的一个字段,不同浏览器对Cookie的大小和数量都有限制;


理解Session

       Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie;如果Cookie很多,就无形地增加了客户端和服务端的数据传输量,而Session就是为了解决这个问题;

       同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个ID,这个ID是客户端第一次访问服务器时生成的,每个客户端是唯一的;

Session与Cookie

       Session是如何基于Cookie来工作的;实际上有以下三种方式可以让Session正常工作;

       1.基于URL Path Parameter,默认支持;

       2.基于Cookie,如果没有修改Context容器的Cookies标识,则默认也是支持的;

       3.基于SSL,默认不支持,只有connector.getAttribute("SSLEnabled")为true时才支持;

Session是如何工作的

      有了SessionID,服务端就可以创建HttpSession对象了,第一次触发通过request.getSession()方法;如果当前SessionID还没有对应的HttpSession对象,那就创建一个新的,并将这个对象加到org.apache.catalina.Manager的sessions容器中保存;

      Manager类将管理所有的Session的生命周期,Session过期将被回收,服务器关闭,Session将被序列化到磁盘等;只要这个HttpSession对象存在,用户就可以根据Session ID来获取这个对象,也就做到了对状态的保持;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值