• 会话管理


    目录

    状态和会话

    HTTP协议的无状态性

    Cookie

    Cookie的API

    向客户端发送cookie

     从客户端读取cookie

     Cookie的安全性问题

    Session

    SessionAPI

     会话超时与失效


    状态和会话

    状态:协议记住用户及其请求的能力

    HTTP协议的无状态性

    HTTP协议是无法记住用户和其请求的,表现为客户端第二次请求时不知道客户端的身份信息

     客户A第一次请求登录,登录成功了;第二次请求加货物到购物车,因为HTTP协议是无状态的,不可以记录用户信息和追踪请求,导致服务器不知道当前请求的用户是谁,也就不知道加到谁的购物车里,无法做出响应

    但是,按照设想,客户端是可以实现多次加货物到购物车的,并且服务器追踪所有请求,记录购物车的商品并计算总价;为了实现这一点,就需要追踪所有请求并和用户相关联

    会话跟踪技术就成了对HTTP无状态协议的一种扩展

    Cookie和Session就是保持状态的记录,session底层依赖于cookie

    cookie类似于你去坐火车,买票的时候有一个票据,记录了你的位置信息,比如(8号车厢20座位),根据这个位置你就可以知道自己的座位在哪,这个票据就是cookie

    Cookie是服务器响应给客户端,并且存储在客户端的一份小数据。下次客户端访问服务器时,会自动带上这个Cookie。服务器通过Cookie就可以区分客户端

    Cookie的API

    对cookie的管理需要使用javax.servlet.http.Cookie类

    1. @Override
    2. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. //1、创建cookie实例
    4. //键值对的形式,name是键值对的key,”张三“是value
    5. Cookie cookie = new Cookie("name", "张三");
    6. //key固定了 value可以修改
    7. //2、获取cookie名称
    8. System.out.println(cookie.getName());
    9. //3、获取cookie的值
    10. System.out.println(cookie.getValue());
    11. //4、给cookie设置新的值
    12. cookie.setValue("李四");
    13. //5、设置cookie的所在的域名
    14. cookie.setDomain("127.0.0.1");
    15. //6、返回cookie的域名
    16. System.out.println(cookie.getDomain());
    17. }
    18. }

     Cookie的管理,应该包括两个方面,服务器给客户端发送cookie,从客户端读取cookie

    向客户端发送cookie

    1. @WebServlet("/sendcookie")
    2. public class SendCookie extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. //1、创建cookie对象
    6. Cookie cookie = new Cookie("username", "张三");
    7. //2、设置cookie的最大存活时间 这个cookie是存储在浏览器的内存中的,随着浏览器关闭,cookie就会消失
    8. //如果想让cookie存储在磁盘上,就可以设置cookie的最大存活时间
    9. //单位是s,如果参数为负数,表示不在硬盘存储,=0,表示删除这个cookie
    10. cookie.setMaxAge(60*60);
    11. //3、给客户端发送cookie对象
    12. resp.addCookie(cookie);
    13. resp.setContentType("text/html;charset=utf8");
    14. PrintWriter out=resp.getWriter();
    15. out.println("" +
    16. ""
    17. +"

      "+"已经发送了cookie

      "
    18. +""
    19. );
    20. }
    21. }

     执行之后,服务器将会在浏览器上写一个cookie文件

    查看浏览器cookie

    如果不设置持久化存储,cookie是保留在浏览器的内存的,随着浏览器的关闭,cookie就消失了,下一次用户就要重新登录

    • 不设置MaxAge,默认响应会话Cookie(MaxAge<0),存在浏览器内存。Cookie随浏览器关闭而消失
    • 设置MaxAge>0,响应持久性Cookie,会存在电脑硬盘的特定文件夹下(浏览器自定义的)
    • 设置特定Cookie的MaxAge=0,则会删除已经存在客户端的此Cookie

     从客户端读取cookie

    1. @WebServlet("/readcookie")
    2. public class ReadCookie extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. String name = "username";
    6. String value = null;
    7. Cookie[] cookies = req.getCookies();//得到请求的所有cookie对象
    8. if (cookies != null) {
    9. for (int i = 0; i < cookies.length; i++) {
    10. if (cookies[i].getName().equals(name)) {
    11. value = cookies[i].getValue();
    12. break;
    13. }
    14. }
    15. }
    16. resp.setContentType("text/html;charset=utf8");
    17. resp.getWriter().write("" + "

      " + name + value + "

      "
      + "");
    18. }
    19. }

     Cookie的安全性问题

    cookie是保留在客户端的,可以被人为删除,而且只要你的电脑被黑,数据就可能丢失

    并且,cookie是有大小限制的。通常,一个浏览器只允许最多存放300个Cookie,每一个站点的Cookie最多20个,每一个Cookie的大小限制为4kb

    Session

    可能是出于cookie的安全性和cookie的大小限制,cookie每一次都要在请求中传输导致的速率等问题,提出了Session

    Session,会话,是一个客户与服务器之间的不间断的请求响应序列。

    session是存在于服务器的

     如果使用cookie,那么可能账户,密码等信息直接保存在客户端,并且每次都要传输到客户端

     使用Session,那么Cookie内不将会保存密码等重要信息,数据更加安全,而且Cookie内的数据也会减少,可以提高传输效率

    sessionid通常是一个32位的16进制数字

    SessionAPI

    通过javax.servlet.http.HttpSession来管理会话

    1. @WebServlet("/new")
    2. public class SessionAPI extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. //1、创建会话
    6. // 使用HttpServletRequest的getSession()方法 创建和请求关联的会话,如果会话存在,直接返回会话,如果不存在,创建新的会话
    7. HttpSession session = req.getSession();
    8. System.out.println("SessionId" + session.getId());//返回SessionId
    9. System.out.println("会话创建的时间" + session.getCreationTime());//会话创建的时间 时间从1970.1.1午夜到现在的毫秒数
    10. System.out.println("新会话" + session.isNew());//如果这个会话没有和任何对象关联 返回true
    11. session.setAttribute("name", "张三");//将一个键值对属性 写入session
    12. // session.invalidate();//删除session
    13. System.out.println(session.getAttribute("name"));//得到key对应的value
    14. session.setMaxInactiveInterval(10);//设置在会话失效之前,两个请求之间的最大间隔时间 单位s
    15. Enumeration<String > names= session.getAttributeNames();//得到所有属性的name
    16. while(names.hasMoreElements()) {
    17. String name = names.nextElement();
    18. System.out.println(name + session.getAttribute("name"));
    19. }
    20. session.removeAttribute("name");//删除某一属性
    21. }
    22. }

     

    我们并没有说把这个SessionId打包到了Cookie里

    resp.addCookie(cookie);这个语句我们并没有写,也就是Session会自己打包进入Cookie,那么这个Cookie就是一个会话Cookie,是在内存存储的

     会话超时与失效

     会话对象会占用一定的资源,因此会话是不需要长久保留的

    HTTP协议没有提供任何机制让服务器知道用户已经离开了,但是规定当一个用户在指定时间内没有请求产生,就去终止会话,这称为会话超时

    这个时间默认30分钟

    可以在web.xml内修改

    1. <session-conflg>
    2. <session-time>
    3. 10
    4. </session-time>
    5. </session-conflg>

    元素内指定以分钟为单位的默认超时时间,如果值<=0,表示永不会过期

     

  • 相关阅读:
    知名啤酒百威布局NFT,试图揭开“蓄谋已久”的上链面纱?
    Chrome 插件推荐
    js for循环设置循环变量和循环体内部是两个单独作用域
    leetcode10--正则表达式
    Linux ls的三个选项(l、h、a)
    综合应用QGIS软件,实现商场选址分析
    移动端H5页面调试vConsole
    一笑的大型连续剧之第一集
    SpringBoot学习笔记(二)自动装配
    Ubuntu LTS 坚持 10 年更新不动摇
  • 原文地址:https://blog.csdn.net/m0_58342797/article/details/126538924