zoukankan      html  css  js  c++  java
  • Cookie&Session

    会话技术

    1. 会话:一次会话包含多次请求和响应。
      • 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
    2. 功能:在一次会话的范围内的多次请求间,共享数据
    3. 方式:
      1. 客户端会话技术:Cookie
      2. 服务器端会话技术:Session

    Cookie

    快速入门

    1. 概念:客户端会话技术,将数据保存到客户端
    2. 快速入门:
      • 使用步骤:
        1. 创建Cookie对象,绑定数据
          • new Cookie(String name, String value)
        2. 发送Cookie对象
          • void addCookie(Cookie cookie)
          • 例如: response.addCookie(Cookie cookie)
        3. 获取Cookie,拿到数据
          • Cookie[ ] getCookies()
          • 例如:Cookie[ ] request.getCookies();

    实现原理

    Cookie原理分析:
    基于响应头:set-cookie 和 请求头:cookie

    Cookie_原理分析

    cookie的细节

    一次可不可以发送多个cookie?

    • 可以

    • 可以创建多个 cookie 对象,使用 response 对象多次调用 addCookie 方法发送 cookie 即可。

    • 示例:

    @WebServlet("/cookieDemo3")
    public class CookieDemo3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 创建cookie对象
            Cookie c1 = new Cookie("msg", "java");
            Cookie c2 = new Cookie("name", "zhangsan");
    
            // 通过response对象,发送cookie对象
            response.addCookie(c1);
            response.addCookie(c2);
    
        }
    
    @WebServlet("/cookieDemo2")
    public class CookieDemo2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 3.获取Cookies,遍历获取
            Cookie[] cs = request.getCookies();
            if (cs != null) { // 判断为非空
                for (Cookie c : cs) {
                    String name = c.getName();
                    String value = c.getValue();
                    System.out.println(name + ":" + value);
                }
            }
        }
    

    cookie在浏览器中保存多长时间?

    1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
    2. 持久化存储
      • void setMaxAge(int seconds)
        1. 正数:将 Cookie 数据写到硬盘的文件中。持久化存储。 seconds:cookie的存活时间,单位为:秒
        2. 负数:默认值
        3. 零:删除 Cookie 信息
    • 示例:
    // 创建cookie对象,存储数据
    Cookie c = new Cookie("name", "zhangsan");
    
    // 设置cookie生命周期(存活时间)
    // c.setMaxAge(40); // 持久化存储到硬盘,40秒后会自动删除cookie文件
    // c.setMaxAge(-1); // 默认浏览器关闭,cookie文件被删除
    c.setMaxAge(0); // 删除cookie
    
    // 发送cookie对象
            response.addCookie(c);
    

    cookie能不能存中文?

    • 在 tomcat 8 之前,cookie中不能直接存储中文数据。
      • 需要将中文数据转码 ---- 一般采用URL编码(%E3)
    • 在 tomcat 8 之后,cookie支持中文数据

    cookie共享问题?

    1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
      • 默认情况下cookie不能共享
      • void setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
        • 如果要共享,则可以将path设置为:"/"
    2. 不同的tomcat服务器间cookie共享问题?
      • void setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
        • 例如:setDomain(".baidu.com"),那么tieba.baidu.com 和 news.baidu.com中cookie可以共享。
    • 示例:
    Cookie c = new Cookie("msg" ,"你好");
    // c.setPath("/day16"); // 默认是在当前虚拟目录
    c.setPath("/"); // 在同一个服务器不同web项目下共享数据
    response.addCookie(c);
    

    Cookie的特点和作用

    1. cookie存储数据在客户端浏览器
    2. 浏览器对于单个 cookie 的大小有限制(4KB),以及对同一域名下的总的 cookie 数量也有限制(对于浏览器的不同,限制不同,一般20个)
    • 作用:
      1. cookie 一般用于存储少量的不太敏感的数据
      2. 在不登录的情况下,完成服务器对客户端的身份识别

    如果登录了,数据会保存在数据库中

    案例:记住上一次的访问时间

    1. 需求:

      1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
      2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
    2. 分析:

      1. 可以采用 Cookie 来完成
      2. 在服务器中的Servlet判断是否有一个名为 lastTime 的cookie
        1. 有:不是第一次访问
          1. 响应数据:欢迎回来,您上次访问时间为:10点28分
          2. 写回Cookie:lastTime=10点25分
        2. 没有:是第一次访问
          1. 响应数据:您好,欢迎您首次访问。
          2. 写回Cookie:lastTime=10点28分
    3. 代码实现:

    package com.my.cookie;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    @WebServlet("/cookieTest")
    public class CookieTest extends HttpServlet {
    
        /**
         * 更新时间
         *
         * @return 格式化的时间字符串格式
         * @throws UnsupportedEncodingException
         */
        private String updateTime() throws UnsupportedEncodingException {
            // 写回cookie,更新时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String str_date = sdf.format(new Date());
            // URL编码
            str_date = URLEncoder.encode(str_date, "utf-8");
            return str_date;
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 设置响应的消息体的数据格式以及编码
            response.setContentType("text/html;charset=utf-8");
    
            // 1.获取所有的cookie
            Cookie[] cookies = request.getCookies();
            // 2.遍历cookies
            boolean flag = false; // 没有cookie,则为false
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    // 3.获取cookie的名称
                    String name = cookie.getName();
                    // 4.判断名称是否是:lastTime
                    if ("lastTime".equals(name)) {
                        // 有该cookie,不是第一次访问
                        flag = true;
                        System.out.println("有cookie");
                        // 响应数据
                        String value = cookie.getValue();
                        // URL解码
                        value = URLDecoder.decode(value, "utf-8");
                        response.getWriter().write("<h1>您上次的访问时间为:" + value + "</h1>");
                        String str_date = this.updateTime();
                        cookie.setValue(str_date);
                        // 设置cookie的存活时间
                        //cookie.setMaxAge(0); // 删除cookie
                        response.addCookie(cookie); // 发送cookie
                        // 找到lastTime的cookie后,退出,不再继续循环判断
                        break;
                    }
                }
                if (cookies == null || cookies.length == 0 || flag == false) {
                    // 没有lastTime的cookie,第一次访问
    
                    System.out.println("没有cookie,设置cookie");
                    // 响应数据
                    response.getWriter().write("<h1>您好,欢迎首次登录!</h1>");
    
                    String str_date = this.updateTime();
                    Cookie cookie = new Cookie("lastTime", str_date);
    //                System.out.println(cookie.getValue().length());
                    // 设置cookie的存活时间
                    cookie.setMaxAge(60 * 60 * 24 * 30); // cookie存活1个月
                    response.addCookie(cookie); // 发送cookie
                }
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    

    Session

    1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession

    快速入门

    1. 获取 HttpSession 对象:
      • HttpSession session = request.getSession();
    2. 使用 HttpSession 对象:
      • Object getAttribute(String name)
      • void setAttribute(String name, Object value)
      • void removeAttribute(String name)

    Session原理

    Session的实现是依赖于Cookie的

    服务器是如何确保在一次会话范围内,多次获取的Session对象是同一个?

    在第一次获取Session时,没有Cookie,服务器会在内存中创建一个新的Session对象
    Session对象有一个JSESSIONID,借助于 set-cookie 这个头,将JSESSIONID响应给客户端浏览器,当客户端浏览器第二次访问时,会 request 头中自动带着 cookie 头,cookie头中保存的JSESSIONID会被服务器自动检索,在服务器中查找是否有相同值的JSESSIONID的Session,如果有就返回这个 JSESSIONID对象的引用
    request.getSession();,该方法返回一个HTTPSession,也就是 JSESSIONID

    Session_原理分析

    Session细节

    当客户端关闭后,服务器不关闭,两次获取session是否为同一个?

    默认情况下,不是。
    如果需要相同,则可以创建 Cookie,键为 JSESSIONID,值为 session.getId(),设置最大存活时间,让 Cookie 持久化存储

    // 1.获取session
    HttpSession session = request.getSession();
    // 确保浏览器关闭后,再次访问获取的是同一个session,依赖于cookie的响应头和请求头
    Cookie cookie = new Cookie("JSESSIONID", session.getId());
    // 持久化存储1小时
    cookie.setMaxAge(60 * 60);
    System.out.println(session);
    

    客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

    不是同一个,但是要确保数据不丢失

    • session的钝化(对象的序列化):
      • 在服务器正常关闭之前,将session对象序列化到硬盘上。
    • session的活化(对象的反序列化):
      • 在服务器启动后,将session文件转化为内存中的session对象即可。

    小提示:

    1. session的钝化和活化在本地tomcat 8 中已经自动实现了,会在work(存放服务为动态生成的数据,例如:jsp,session的序列化SESSIONS)中
    2. session的钝化在IDEA中可以,但活化不行,原因是IDEA一旦重启,会自动删除work目录,然后重行创建一个空的work目录,将原本序列化好的SESSIONS删除

    session什么时候被销毁?

    1. 服务器关闭
    2. session对象调用 invalidate()
    3. session默认失效时间:30分钟
    • 选择性配置修改
      <!-- ==================== Default Session Configuration ================= -->
      <!-- You can set the default session timeout (in minutes) for all newly   -->
      <!-- created sessions by modifying the value below.                       -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    

    Session特点

    1. session用于存储一次会话的多次请求间的数据,存在服务器端
    2. session可以存储任意类型(Object),任意大小的数据
    • session与cookie的区别:
      1. session存储数据在服务器端,cookie在客户端
      2. session没有数据大小限制,cookie有
      3. session相对安全,cookie相对于不安全
  • 相关阅读:
    css笔记
    js面向对象开发之--元素拖拽
    git命令笔记
    数据扁平化笔记。
    手写冒泡排序
    ant design-Table组件实现每一行某个特定字段连续相同进行行合并。
    Array.prototype.reduce()。
    I/O多路复用
    TCP/IP四层体系结构
    TCP的三次握手和四次挥手,为什么?
  • 原文地址:https://www.cnblogs.com/rainszj/p/12188795.html
Copyright © 2011-2022 走看看