Session会话追踪的实现机制

会话跟踪技术:

        在Web应用程序中,我们经常要跟踪用户身份。例如:当一个用户登录成功后,如果他继续访问其他页面,Web程序如何才能识别出该用户身份?当一个用户在操作自己的购物车时,Web程序如何才能识别出该用户身份?

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

即:

  • 客户端第一次发送请求给服务器,服务器会获取session,如果获取不到,则创建新的,然后响应给客户端
  • 下次客户端给服务器发请求时,会把sessionID带给服务器,那么服务器就能获取到了,那么服务器就判断这一次请求和上次某次请求是同一个客户端,从而能够区分开客户端        

Session

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

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

HttpSession session = request.getSession();

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

  • void setAttribute(String name, Object value):将指定Key-Value键值对,存入当前Session会话中。
  • Object 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容器自动创建一个Session ID,然后通过一个名为JSESSIONID的Cookie发送给浏览器:

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

Cookie

        实际上,Servlet提供的HttpSession本质上就是通过一个名为"JSESSIONID"的Cookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie我们可以任意使用。
        创建一个新Cookie时,除了指定名称和值以外,通常需要设置setPath("/"),浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/user/"),那么浏览器只有在请求以/user/开头的路径时才会附加此Cookie(一般不建议设置路径)。通过setMaxAge()设置Cookie的有效期,单位为秒,最后通过resp.addCookie()把它添加到响应。
        通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。在Chrome浏览器中,单个 Cookie的长度不能超过 4069 个字符(包括 name,但不包括 = 号)。

        如果我们要读取Cookie,例如,在IndexServlet中,读取名为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。

总结:

  • Servlet容器提供了Session机制以跟踪用户;
  • 默认的Session机制是以Cookie形式实现的,Cookie名称为JSESSIONID;
  • 通过读写Cookie可以在客户端存储数据;
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值