Session会话追踪的实现机制

一、概述

       因为HTTP协议是一个无状态协议,即Web应用程序无法区分收到的两个HTTP请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器可以向浏览器分配一个唯一ID,并以Cookie的形式发送到浏览器,浏览器在后续访问时总是附带此Cookie,这样,服务器就可以识别用户身份。

二、Session

       我们把这种基于唯一ID识别用户身份的机制称为Session,每个用户第一次访问服务器后,会自动获得一个Session ID。如果用户在一段时间内没有访问服务器,那么Session会自动失效,下次即使带着上次分配的Session ID服务器也认为这是一个新用户,会分配新的Session ID。一次Session会话中往往包含着若干次request请求。

        JavaEE的Servlet机制内建了对Session的支持。当我们需要获取Session时,可以通过request请求对象的getSession()方法: 

HttpSession session = request.getSession();

       获取Session后,常见的操作方法有:

  • void setAttribute(String name,Object value):将指定的Key-Value键值对,存入当前Session会话中。
  • Obejct getAttribute(String name):按照指定的Key从当前Session会话中获取Value,返回值为Object类型的对象,如果不存在,则返回null。
  • void removeAttribute(String name):按照指定的Key从当前Session会话中删除key-Value键值对。
  • long getCreationTime():获取当前Session会话的创建时间。
  • long getLastAccessedTime();获取当前Session会话最后一次请求的访问时间。
  • String getId():获取当前Session会话的Session ID。

              服务器识别Session的关键就是依靠一个名为JSESSIONID的Cookie。

              在Servlet中第一次调用req.getSession()时,Servlet容器会自动创建一个SessionI D .然后通过一个名为JSESSION的Cookie发送给浏览器:
         

        使用Session时,由于服务器把所有用户的Session都存储在内存中,如果遇到内存不足的情况,就需要把部分不活动的Session序列化到磁盘上,这会大大降低服务器的运行效率,因此,放入Session的数据不能太大,否则会影响服务器的运行。

三、Cookie

       实际上,Servlet提供的HttpSession本质上就是通过一个名为JESSION的Cookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie我们可以任意使用。

       创建一个新的Cookie时,除了指定名称和值外,通常需要设置setPath("/"),浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/uesr/"),那么浏览器只有在请求以/user/开头的路径才会附加此Cookie。通过setMaxAge()设置Cookie有效期,单位为秒,最后通过resp.addCookie()把它添加到响应。

        通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。

   我们可以在浏览器看到服务器发送的Cookie:

 如果我们要读取Cookie,例如:在IndexServelt中,读取名为lang的Cookie以获取用户设置的语言,可以写一个方法:

private String parseLanguageFromCookie(HttpServletRequest req) {
    // 获取请求附带的所有Cookie:
    Cookie[] cookies = req.getCookies();
    // 如果获取到Cookie:
    if (cookies != null) {
        // 循环每个Cookie:
        for (Cookie cookie : cookies) {
            // 如果Cookie名称为lang:
            if (cookie.getName().equals("lang")) {
                // 返回Cookie的值:
                return cookie.getValue();
            }
        }
    }
    // 返回默认值:
    return "en";
}

      所以 ,读取Cookie主要依靠遍历HttpServletRequest附带的所有的Cookie。

四、总结

      Session在服务端保存信息,Cookie在客户端保存信息,为了跟踪会话,服务器端在创建Session后,需要将SessionID交给客户端,因此在cookie中有JSessionID=value;但是它通常是保存在浏览器的内存中(因为Tomcat中设置为MaxAge为负数),并且也不能在多个浏览器之间共享。当不关闭浏览器在客户端再次请求时,这个ID随请求一起发送回来。如果关闭浏览器,那么保存该SessionID的cookie就被删除,导致sessionid丢失。无法找到先前的sessionid,服务器只能创建一个新的session。而这个时候先前的session是仍然存在的,知道超过设置的session超时时间间隔,那么服务器会清除该session。

         利用Cookie进行会话,即可以保存在浏览器内存中,也可以持久化(这时sessionid也是被保存到硬盘,因为sessionid就是一个cookie中的一个键值对).当cookie存储在浏览器内存中时,只能被同一个浏览器进程所共享;但是对于保存在硬盘上的Cookie,可以在多个浏览器所共享。因此SessionId是随着Cookie的保存位置而保存。

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...