会话技术之Cookie与Session讲解

好记性不如烂笔头

会话技术

  1. 会话:一次会话包含多个请求和响应.
    • 一次会话: 浏览器第一次给服务器发送请求时,会话建立,直到有一方断开连接为止. (浏览器关闭 || 服务器崩溃 等)
  2. 功能:在一次会话的范围内的多次请求间共享数据
  3. 方式:
    1. Cookie:客户端会话技术
    2. Session:服务器端会话技术

Cookie

在这里插入图片描述

  1. 概念:客户端会话技术,将数据保存在客户端浏览器中

  2. 快速入门:

    1. 创建Cookie对象,绑定数据

      • new Cookie(String name, String value) 构造具有指定名称和值的cookie。
      Cookie cookie = new Cookie("msg", "helloCookie");
      
    2. 发送Cookie对象

      • response.addCookie(Cookie cookie) 将指定的cookie添加到响应中。
      response.addCookie(cookie);
      
    3. 获取Cookie对象,拿到数据

      • Cookie[] getCookies() 返回一个数组,其中包含客户端使用此请求发送的所有 Cookie对象。
      Cookie[] cookies = request.getCookies();
      //获取数据
      for (Cookie cookie : cookies) {
          String name = cookie.getName();//通过cookie获取到其其存储数据的name值
          //获取其value
          String value = cookie.getValue();
          System.out.println(name+":"+value);
      }
      
      //Cookie cookie = new Cookie("msg", "helloCookie");前
      JSESSIONID:41C862EEDE5396BF7290143EC3D82283
      Idea-3ca48729:f25a110b-be41-4507-bd9b-4c443b8232b4
      
      //Cookie cookie = new Cookie("msg", "helloCookie");执行后
      JSESSIONID:41C862EEDE5396BF7290143EC3D82283
      msg:helloCookie
      Idea-3ca48729:f25a110b-be41-4507-bd9b-4c443b8232b4
      
    • 结论:当浏览器关闭后,cookie就失效了,当然其中存储的数据也就失效了
  3. 实现原理:

    • 基于第一次请求的响应头(set-cookie)和后续请求的请求头(cookie)实现.
  4. 使用cookie时的细节问题:

    1.发送cookie时一次可不可以发送多个cookie?

    • 可以

    • 可以创建多个cookie对象,使用response调用多次addCookie方法去保存

    • 如果多次存储的数据name值一致, 后续存储的值会将前面的进行覆盖处理

      2.cookie在浏览器中可以保存多久呢?

  • 默认情况下,当浏览器关闭时,cookie数据将被销毁

  • cookie持久化存储:

    void setMaxAge(int expiry) 设置此Cookie的最大年龄(以秒为单位)

Cookie cookie = new Cookie("name", "helloCookie");
//设置其存活周期:
//cookie.setMaxAge(-1);  //默认值
//cookie.setMaxAge(0);//删除cookie
cookie.setMaxAge(40);  //将cookie持久化到硬盘 40s后自动删除cookie文件
response.addCookie(cookie);
  • 参数:

    正数:正值表示cookie将在经过许多秒后过期。 请注意,该值是cookie过期时的最大年龄,而不是cookie的当前年龄。

    0:零值会导致cookie被删除。 (删除cookie信息)

    负数(默认值):负值表示cookie不会持久存储,并在Web浏览器退出时被删除。

    1. cookie共享问题?

      //设置path路径 让当前服务器下部署的所有项目共享该cookie信息
      cookie.setPath("/");
      

      假设在一个tomcat服务器中,部署了多个web项目,那么请问这些web项目中cookie的值是否可以共享呢?

    • 默认情况下cookie不能共享

      setPath(String path)  //设置path路径"/" 让当前服务器下部署的所有项目共享该cookie信息
      

在不同的tomcat服务器中 cookie能否共享呢?

  • 默认不可以

    • void setDomain(String domain) :如果设置两个服务器的一级域名相同,那么多个服务器之间cookie可以共享

      • setDomain(".baidu.com") 那么百度贴吧和百度百科的一级域名都为"baidu.com" 那么他们之间就可以进行cookie数据共享

        https://tieba.baidu.com/ 百度贴吧

        https://baike.baidu.com/ 百度百科

4. cookie是否可以存储中文?
  • tomcat 8 之前不能直接存储中文数据

    ​ 需要将中文数据转码–>URL编码(%E3)

  • tomcat 8 及以上版本 支持中文数据 但不支持特殊字符(例如 空格 #$%&*) 建议使用URL编码存储 URL编码解析

  1. cookie的特点和作用
    1. 特点:
      1. cookie存储数据在客户端浏览器上
      2. 浏览器对于单个cookie的大小有限制(4kb) 以及对同一个域名下的总的cookie数量有限制(20)
    2. 作用:
      1. cookie一般用于存储少量的不太敏感的数据(不安全)
      2. 在不登录的情况下,cookie可以完成服务器对客户端的身份识别.
  2. 案例:如何让浏览器记住你上次登陆过.
    1. 需求:
      1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
      2. 如果不是第一次访问 则提示:欢迎回来,您上次访问的时间为:yyyy-MM-dd HH:mm:ss
    2. 分析:
      1. 可以采用cookie实现该案例
      2. 在服务器的Servlet代码中判断是否有一个名字叫lastTime的cookie
        1. 有:不是第一次访问:
          1. 响应数据:欢迎回来,您上次访问的时间为:yyyy-MM-dd HH:mm:ss
          2. 写回cookie:将当前系统时间写入到cookie中,将之前时间覆盖掉
        2. 没有:是第一次访问:
          1. 响应数据:您好,欢迎您首次访问
          2. 写回cookie:将当前系统时间写入到cookie中
@WebServlet("/cookieTest")
public class CookieTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1.设置响应消息体的数据格式以及编码字符集
        response.setContentType("text/html;charset=utf-8");

        boolean flag = false;  //设置是否有一个名字叫lastTime的cookie   默认 false 没有

        //2.获取所有的cookie数据 遍历数组 看里面是否有一个叫lastTime的cookie
        Cookie[] cookies = request.getCookies();  //2.1:获取所有的cookie数据
        if (cookies != null && cookies.length>0){
            for (Cookie cookie : cookies) {    //2.2:遍历数组
                String name = cookie.getName(); //2.3:获取每一个cookie的name值
                if ("lastTime".equals(name)){   //2.4:看里面是否有一个叫lastTime的cookie
                    // 有  不是第一次访问
                    flag = true;
                    String lastValue = cookie.getValue();  //获取上一次访问的时间 用于在页面展示

                    String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
                    System.out.println("编码前的时间为:"+str_date);
                    str_date = URLEncoder.encode(str_date,"utf-8");
                    System.out.println("编码后的时间为:"+str_date);
                    cookie.setValue(str_date);
                    cookie.setMaxAge(60*60*24*30); //设置存活时间为一个月
                    response.addCookie(cookie);

                    System.out.println("解码前的上一次时间为:"+lastValue);
                    lastValue = URLDecoder.decode(lastValue,"utf-8");
                    System.out.println("解码后的上一次时间为:"+lastValue);
                    response.getWriter().write("<h1>欢迎回来,您上次登陆的时间为:"+lastValue+"</h1>");
                    break;  //终止当前循环
                }
            }
        }

        // 第一次访问
        if (cookies == null || cookies.length == 0 || flag == false){
            String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
            System.out.println("编码前的时间为:"+str_date);
            str_date = URLEncoder.encode(str_date,"utf-8");
            System.out.println("编码后的时间为:"+str_date);
            Cookie cookie = new Cookie("lastTime", str_date);
            cookie.setMaxAge(60*60*24*30); //设置存活时间为一个月
            response.addCookie(cookie);
            response.getWriter().write("<h1>您好,欢迎您首次访问!</h1>");
        }



    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

Session

1.概念

服务器端会话技术,在一次会话的多次请求中共享数据, 将数据保存在服务器中的对象中(HttpSession)

2.快速入门

  1. 获取HttpSession对象:
    • HttpSession session = request.getSession();
  2. 使用HttpSession对象:
    • session.getAttribute("");
    • session.setAttribute("","");
    • session.removeAttribute("");

3.原理

在这里插入图片描述

  • Session的实现是基于cookie的
    1. 第一次访问 会创建session对象 将其id与值通过 set-cookie 响应头传递给客户端浏览器,客户端浏览器会在本地缓存将id值保存
    2. 第二次访问 会在请求头中将id值 通过cookie 传递给服务器 第二次创建就可以根据id值找到第一次创建的session对象
  1. 细节:

    1.客户端关闭,服务器不关闭 获取到的session是否为同一个?

    • 默认情况 不是

    • 如果需要相同, 创建一个cookie 键为JSESSIONID 设置最大存活时间 让cookie持久化存储.

      Cookie cookie = new Cookie("JSESSIONID", session.getId());
      cookie.setMaxAge(60*60);
      response.addCookie(cookie);
      
    1. 客户端不关闭,服务器关闭 获取到的session是否为同一个?
    • 不是同一个, 要确保数据不丢失, tomcat自动帮你完成以下操作:

      • session的钝化:

        在服务器正常关闭之前,将session对象序列化到硬盘上

      • session的活化:

        在服务器启动后,将session文件转化为内存中的session对象

  2. session什么时候会被销毁?

    • 服务器关闭时被销毁

    • session.invalidate():自动销毁

    • session默认关闭时间为30min

C:\Users\MrDong\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_8_5_31_java_123_9\conf
//可以手动修改web.xml中配置(项目中的该配置) 
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
  1. session的特点

    1. session用于存储一次会话的多次请求的数据 存储在服务器端

    2. session可以存储任意类型 任意大小的数据

  2. session域cookie的区别 面试考点

    1. session 在服务器端,cookie 在客户端(浏览器)
    2. session存储没有数据大小限制 cookie 有
    3. session存储的数据比较安全 cookie相对不安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值