Advertisement

会话管理——Cookie和 Session

阅读量:

文章目录

    • 基本原理
    • Cookie
    • Session(会话)
    • Cookie VS Session

前言

前言

谁在跟http会话,该跟谁会话了——Cookie + Session机制

  • Cookie充当了请求会话的身份凭证,并且也作为标识对象的凭证。
  • Session存储了纯后台数据,并包含与相关联用户的记录信息。

基本原理

(1)Cookie角度

Cookie是浏览器-服务器之间的:

为了存储Cookie信息,在适当的请求中发送这些信息到客户端,并将其体现在HTTP请求头字段中

​ 服务器生成Cookie并传递给浏览器,表现为响应头中的set Cookie

当用户首次登录时

Cookie本质上相当于一个键值对,在其中一个是session-id的情况下,服务端通过解析Cookie中的session-id来唯一标识用户的专属数据。

(2)Session角度——通过Session-id找到唯一对应的一组客户数据

服务端方负责管理Session机制来存储与每个用户的关联信息,在此过程中确保每位用户的Session ID均为独一无二标识符,在接收完该Session ID后每位客户端必须在其每次连接时传递该标识符作为身份验证依据,在具体实施过程中可采用将此标识符嵌入到相关的网络请求头字段中以实现安全认证

(3)二者相互配合

Cookie作为身份凭证,在客户端使用;而Service端则采用Session这一机制。通常情况下,在发送该Session-id至客户端后(之后),客户端将携带该Session-id并将其嵌入到Cookie中(即共同作用于同一个会话管理过程中),从而完成会话管理的任务。

通常情况下,Servlet的Session会将数据存储在内存中。当服务器重启时,Session的数据可能会被清除或丢失。

第一次访问,需要办理Cookie,然后准备专属的数据柜(Session)

req.getSession(true);

复制代码
    //        true的含义:如果是会员,则返回之前的柜子,如果不是会员,则新建一个新柜子
    //		fals的含义:不创建会员
复制代码
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.util.Date;
    
    /**Cookie-Session机制
     * @author sunny
     * @date 2022/06/16 19:52
     **/
    @WebServlet("/firstVisited")
    public class FirseVisit extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        第一次访问,需要办理会员卡
    //        true的含义:如果是会员,则返回之前的柜子,如果不是会员,则新建一个新柜子
        HttpSession session = req.getSession(true);
        session.setAttribute("first_visit",new Date());
    
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");
        resp.getWriter().println("办理会员成功");
    
    }
    }

观察可以看到:

第一次访问时:响应头中有个 Set-Cookie

再次访问,请求头中开始携带Cookie

Session(会话)

(1)Session结构

Session结构:Map<key,value>

在该方案中,在这里指代的是session-id作为键值(每一个客户的独立数据存储空间),其对应的是HttpSession对象(具体而言,在此空间内同样包含name和value键值对,请注意例如name:xxx,age:13这样的实例)。

(2)HttpSession对象的常见方法

复制代码
    HttpSession session = req.getSession(true);

    // 根据name获取value,如果没有则返回null
    session.getAttribute("name");
复制代码
    session.setAttribute("first_visit",new Date());

    //插入或者更新name-value
复制代码
    //        根据name删除键值对

        session.removeAttribute("name");

(3)Session默认存储在内存中(重新运行进程就没了)

Servlet的Session以 default 的方式位于内存中。当重新启动服务器时,Session的数据会被清除。

Tomcat也支持其他持久化存储,比如存在本地文件,数据库里

不同浏览器视为不同的用户~

(3)小栗子:

/firstVisited被赋值为初始登录事件;该事件会生成Cookie对象,并新增一个键值对first_visit与当前日期相连。

复制代码
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.util.Date;
    
    /**Cookie-Session机制
     * @author sunny
     * @date 2022/06/16 19:52
     **/
    @WebServlet("/firstVisited")
    public class FirseVisit extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        第一次访问,需要办理会员卡
    //        true的含义:如果是会员,则返回之前的柜子,如果不是会员,则新建一个新柜子
        HttpSession session = req.getSession(true);
    //        session.getAttribute("name");
        session.setAttribute("first_visit",new Date());
        根据name删除键值对
    //        session.removeAttribute("name");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");
        resp.getWriter().println("办理会员成功");
    
    }
    }

/getfirstTime——查看是否获得Cookie,并返回首次获得的时间

复制代码
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Date;
    
    /** * @author sunny
     * @date 2022/06/16 20:35
     **/
    @WebServlet("/getfirstTime")
    public class GetFirstTime extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");
        PrintWriter writer = resp.getWriter();
    
        HttpSession session = req.getSession(false);
        if(session == null){
            writer.println("没有Session,说明还没有办理Cookie,不是会员");
            return;
        }
    
        Object o = session.getAttribute("first_visit");
        if(o == null){
            writer.println("文件柜有,但value为空,没有内容");
            return;
        }
        Date date = (Date) o;
        writer.println(date);
    }
    }

现象:

直接访问 localhost:8080/getfirstTime

因为并没有获得Cookie,所以

在这里插入图片描述

先访问 localhost:8080/firstVisited ,办理会员

在这里插入图片描述

再访问 localhost:8080/getfirstTime ,得到时间

在这里插入图片描述

那么,什么时候会打印“文件柜有,但value为空,没有内容”这句话呢?

当我们将get中的注册会员状态标记更改为true后直接访问get时会返回此信息这是因为注册了会员但未添加相应的键值对所以返回null值。

在这里插入图片描述

两者虽然常见都是配合使用,但其实均可独立使用

(1)Cookie的单独使用

Cookie是凭证,在请求头或者响应头中体现为Cookie,SetCookie

只设置Cookie,还可以设置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;
    
    /** * @author sunny
     * @date 2022/06/16 20:53
     **/
    @WebServlet("/onlysetcookie")
    public class OnlySetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("name","yiyi");
    //        设置Cookie的域名范围
    //        cookie.setDomain();//比如设置成“qq.com”,凡是什么什么qq.com的都可以
    //        设置Cookie的最大会话时间
        cookie.setMaxAge(120);
    //        设置Cookie的路径范围
        cookie.setPath("/");
        resp.addCookie(cookie);
        Cookie cookie1 = new Cookie("key","value");
        resp.addCookie(cookie1);
    }
    }

只获取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;
    
    /** * @author sunny
     * @date 2022/06/16 20:59
     **/
    @WebServlet("/onlygetcookie")
    public class OnlyGetCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for(Cookie cookie : cookies){
            System.out.println(cookie.getName() + "——》" + cookie.getValue());
        }
    }
    }

设置Cookie的最大会话时间,默认是浏览器关闭就没了

在这里插入图片描述

关闭浏览器后,再重新访问别的页面,可以发现,会话那个已经消失;了

在这里插入图片描述

(2)Session的单独使用
比如可以将session-id直接携带在url中等

Cookie+Session的核心功能是作为登录态管理工具,在判断用户是否已登录状态以及获取当前用户的登录状态信息方面发挥重要作用。

全部评论 (0)

还没有任何评论哟~