Cookie与Session

2016/9/2 posted in  Java  

在开发过程中我们经常需要保存一些状态信息如用户登录状态等,但是由于HTTP协议的无状态特性,这些功能无法直接实现。所以我们引入了Cookie与Session这两个概念用于保存一些信息。

Cookie

Cookie的作用通俗地说就是当一个用户通过HTTP协议访问一个服务器的时候,这个服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器的时候,数据又被完整地带回给服务器。

Cookie如何工作

  1. 用户通过浏览器请求某个Servlet,在请求过程中如果本地有该站点的Cookie信息,浏览器会将这些信息放入request请求的请求头中;
  2. 在Servlet中可以通过request.getCookies();获取当前的Cookie数组;
  3. 根据自己的业务需求,新建Cookie对象实例,分别设置key和value的值;
  4. 将需要添加的Cookie实例通过response.addCookie();方法添加到响应当中返回客户端,客户端根据Cookie的生命周期(MaxAge属性)来选择是否将此Cookie写入硬盘当中。

DemoCode

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

    @Override 
    public void doGet(HttpServletRequest 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", "user")); 
        } 
        if (userAge == null) { 
            response.addCookie(new Cookie("userAge", "28")); 
        } 
         
 }

使用Cookie的限制

Cookie是 HTTP 协议头中的一个字段,虽然HTTP协议本身对这个字段并没有多少限制,但是 Cookie 最终还是存储在浏览器里,所以不同的浏览器对Cookie的存储都有一些限制,下表是一些通常的浏览器对 Cookie的大小和数量的限制。

浏览器版本 Cookie数限制(个/域名) 总大小限制
IE6 20 4095B
IE7、8、9 50 4095B
Chrome 50 >8000
FireFox 50 4097B

Session

前面已经介绍了 Cookie 可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些 Cookie,如果 Cookie 很多,这无形地增加了客户端与服务端的数据传输量,而 Session 的出现正是为了解决这个问题。

Session如何工作

  1. session是基于Cookie的,同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 ID,客户端只要传回这个 ID 就行了,这个 ID 通常是 NANE 为 JSESIONID 的一个 Cookie;
  2. 有了Session ID服务端就可以创建HttpSession对象了,第一次触发通过request.getSession()方法。如果当前的Session ID 还没有对应的HttpSession对象,那么就创建一个新的,并将这个对象加到org.apache.catalina.Manager的sessions容器中保存。Manager类将管理所有Session的生命周期,如果该session存在则直接返回;
  3. 直接操作session对象对key/value键值对进行存储,数据保存在服务器端,可以通过api手工操作其声明周期