• Session会话追踪的实现机制


    目录

    什么是Session?

    Session的创建与销毁

    什么是Cookie?


    什么是Session?

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

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

    代码实现:

    1. package com.my.servlet;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import javax.servlet.http.HttpSession;
    9. @WebServlet("/test.do")
    10. public class TestSessionServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. System.out.println("被请求到了!");
    14. // 第一次在访问session时,服务器会创建session
    15. // 并根据Session_id,创建一个名称为JSESSIONID的Cookie,将Session_id保存至Cookie
    16. // 将该Cookie响应回至浏览器客户端保存
    17. // 接下来的每次发起请求时,客户端浏览器都会在请求头中 添加 JSESSIONID
    18. // 用于服务器确认身份
    19. HttpSession session=req.getSession();
    20. System.out.println( session.getId());
    21. }
    22. }

    在控制台输出的结果:

    由此可以看出重复的请求,创建的是同一个sessionId

     服务器识别Session的关键就是依靠一个名为JSESSIONID的Cookie。在Servlet中第一次调用req.getSession()时,Servlet容器自动创建一个Session ID,然后通过一个名为JSESSIONID的Cookie发送给浏览器(Session ID可以说是Session对象通过servlet给浏览器的一个响应):

    在浏览器中的显示如下:

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

    Session的创建与销毁

    1、创建

    浏览器向服务器发起请求的同时会创建出session会话,在服务器给浏览器响应的同时创建出session的对象,并且返回一个sessionId。浏览器关闭后,重新发起请求则会创建一个新的session。

    2,、销毁

    session的销毁有三种

    1、服务器的重启与关闭(session存活在服务器端)

    2、session默认是等待30分钟自动销毁(也可以在web.xml文件中设置过期的时间)

    3、调用session的invalidate()方法

    什么是Cookie?

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

    我们可以在浏览器看到服务器发送的Cookie,以cookie.do为例:

    代码实现:

    1. package com.my.servlet;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.Cookie;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. @WebServlet("/cookie.do")
    10. public class TestCookieServlet extends HttpServlet {
    11. @Override
    12. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. System.out.println("Cookie");
    14. // 创建Cookie
    15. Cookie cookie1 = new Cookie("userId", "1911111111");
    16. cookie1.setMaxAge(60 * 60 * 24 * 7);
    17. Cookie cookie2 = new Cookie("WeChat", "1111111111");
    18. cookie2.setMaxAge(60 * 60 * 24 * 7);
    19. Cookie cookie3 = new Cookie("weibo", "23457098765");
    20. cookie3.setMaxAge(60 * 60 * 24 * 7);
    21. // 响应
    22. resp.addCookie(cookie1);// 将Cookie添加至响应头
    23. resp.addCookie(cookie2);// 将Cookie添加至响应头
    24. resp.addCookie(cookie3);// 将Cookie添加至响应头
    25. }
    26. }

    浏览器中的展示:

     如果我们要读取Cookie,例如TestGetCookieServlet

    1. package com.my.servlet;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.Cookie;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. @WebServlet("/tgcs.do")
    10. public class TestGetCookieServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. System.out.println("测试获取Cookie");
    14. Cookie[] cookies=req.getCookies();
    15. if(cookies!=null) {
    16. for (Cookie cookie : cookies) {
    17. System.out.println(cookie.getName());
    18. System.out.println(cookie.getValue());
    19. System.out.println();
    20. }
    21. }
    22. }
    23. }

    结果如下:

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

    总结:

    • Servlet容器提供了Session机制以跟踪用户;
    • 默认的Session机制是以Cookie形式实现的,Cookie名称为JSESSIONID
    • 通过读写Cookie可以在客户端存储数据;

  • 相关阅读:
    重试队列-让服务更健壮
    RK3399平台开发系列讲解(内存篇)15.34、 Linux 进程内存布局
    在数据分析中,对缺失值解决方案的分析
    重温数据结构与算法之AVL树可视化
    程序员35岁之后如何规划?建议收藏!
    14:00面试,14:06就出来了,问的问题有点变态。。。
    问答机器人学习资料
    flink 事件处理 CEP
    深度学习论文精读[10]:Deeplab v1
    MySQL高级十四:索引的基本使用
  • 原文地址:https://blog.csdn.net/weixin_49137294/article/details/126530332