• Session会话追踪的实现机制


    一、概述

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

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

    二、Session和Cookie

    1.Session

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

    • 当我们第一次在访问Session时,服务器会创建Session
    • 并根据Session_ID,创建一个名称为“JSESSIONID”的Cookie,将Session_ID保存至Cookie
    • 将该Cookie响应回至浏览器客户端保存
    • 接下来的每次发起请求时,客户端浏览器都会在请求头中,添加JSESSIONID
    • 用于服务器确认“身份”
    • (需要获取Session时,可以通过request请求对象的getSession()方法。String getId():获取当前         Session会话的SESSION ID。)
    1. package com.my.web.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_session.do")
    10. public class TestSessionServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    13. System.out.println("GET请求:TestSessionServlet被请求到了!");
    14. HttpSession session = req.getSession();
    15. System.out.println("SESSIONID:" + session.getId());
    16. }
    17. }

    8320f5d5fe99410fa810668c0e7b536f.png

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

    9049e1d8a0a545858d124a6231c1a9f2.png

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

    2、Cookie

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

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

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

    1. package com.my.web.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("/test_cookie.do")
    10. public class TestCookieServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13. System.out.println("Cookiiiiiiiiiiiiiiiie");
    14. //创建Cookie对象
    15. Cookie cookie1 = new Cookie("phone_number", "13309270719");
    16. cookie1.setMaxAge(60*60*24*7);//7天
    17. Cookie cookie2 = new Cookie("name", "YY");
    18. cookie1.setMaxAge(60*60*24*7);//7天
    19. Cookie cookie3 = new Cookie("QQ", "2452845234");
    20. cookie1.setMaxAge(60*60*24*7);//7天
    21. //响应
    22. response.addCookie(cookie1);//将Cookie添加至响应头
    23. response.addCookie(cookie2);
    24. response.addCookie(cookie3);
    25. }
    26. }

    aafa4b3300bf4f81b604e787daad7b9d.png

     这样就成功保存了想要保存的信息至客户端浏览器啦。

    ②如果想要获取该客户端浏览器本次请求头(request header)中的所有Cookie

    1. package com.my.web.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("/test_get_cookie.do")
    10. public class TestGetCookieServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13. System.out.println("测试获取Cookie!");
    14. //获取该客户端浏览器本次请求头(request header)中的所有Cookie
    15. Cookie[] cookies = request.getCookies();
    16. for (Cookie cookie : cookies) {
    17. System.out.println(cookie.getName());
    18. System.out.println(cookie.getValue());
    19. System.out.println();
    20. }
    21. }
    22. }

    1f9545d9d8444c5fb8489b8ab75b60dd.png③获取应用范围的总访问量

    1. package com.my.web.servlet;
    2. import java.io.IOException;
    3. import javax.servlet.ServletContext;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. @WebServlet("/test_app.do")
    10. public class TestApplicationServlet extends HttpServlet{
    11. @Override
    12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    13. //应用范围
    14. ServletContext application = request.getServletContext();
    15. System.out.println("Context Path :" + application.getContextPath());
    16. System.out.println("Real Path:" + application.getRealPath("/"));
    17. if(application.getAttribute("app_counter") == null) {
    18. application.setAttribute("app_counter", 1);
    19. System.out.println("总访问量:1");
    20. }else {
    21. int appCounter = Integer.parseInt(application.getAttribute("app_counter").toString());
    22. application.setAttribute("app_counter",appCounter+1);
    23. System.out.printf("总访问量:%d\n" , appCounter+1);
    24. }
    25. }
    26. }

    6593e05e47c1441b891aa0475b49a0e2.png

     

     

     

  • 相关阅读:
    设计模式-解释器模式
    点云库PCL学习——点云的格式、PCD文件的打开和显示
    面试不到10分钟就被赶出来了,问的实在是太变态了...
    CopyOnWriteArrayList源码分析
    钉钉自动打卡
    【Linux】Linux+Nginx部署项目
    C语言实现带头双向循环链表
    Webpack介绍大全
    Python是“真火”还是“虚火”?
    lsblk 硬盘属性查看
  • 原文地址:https://blog.csdn.net/weixin_49187233/article/details/126506796