Cookie 和 Session

Cookie 和 Session


前言:

这篇帖子重点讲讲Cookie和Session之间的区别,以及作用,Cookie在http协议中就提到了他的定义,作用,小伙伴们可以跳转到 Http协议 这个页面看看Cookie的基本概念及作用。

前情回顾:

1、Cookie是浏览器提供的一种让程序员在本地存储数据的能力,让数据在客户端这边更持久化。

2、Cookie里面存的是键值对的格式数据,键值对用“;”分割,键和值之间用“,”分割。

3、浏览器里面存的Cookie都是从服务器的响应“报头”里面的 set-cookie 字段中来的,每个 set-cookie 字段里面都包含一个Cookie 这样的键值对,浏览器拿到响应之后就会把 set-cookie中的内容保存到本地,而 set-cookie 就是程序员自己在服务器中构造填写的。

经典cookie运用场景,保存用户登录信息:

image-20220409153516176

在传输的过程中,cookie不仅保存了我们的用户名和密码还保存了我们账户的其他信息,像这样明文传过来传过去,显然是不安全的,再加上cookie存储的信息数据也是非常庞大,每次传输都需要传很多数据,也是非常占用带宽,之前也说了带宽占的资源多,成本也多,像这么数据庞大的传输,钱也在烧,然后传输的数据也不安全,所以就有了一个解决的办法,就是用session!!!

一、session

session中文翻译是“会话”,session是在服务器的一种机制,因为cookie是客户端保存的数据,而这些数据又是跟用户强烈相关联的,显然保存在客户端这边就不太合适(太多,也占资源),所以把数据都保存在服务器这边就比较的合适;保存的方式就是通过session的方式来进行保存的。

1.怎么保存?

a、服务器这边根据用户登录成功,就会生成一个键值对:

​ key:SessionId,是一个随机,不重复的,唯一的字符串

​ value:是用来保存客户身份信息

​ 服务器以“键值对”的方式来把这些session(会话)给管理起来,每个用户的登录都会生成一个会话。

里面的键值对就可以直观想象成一个哈希表!!!

b、客户端只需要保存 sessionId就可以了,后续的请求带上 sessionId,服务器就会根据 sessionId 就会找到对应的用户数据详细的信息。

用session的好处:

1、客服端很轻量,不用存储大多的数据

2、客户端和服务器之间传输的数据量小,节省带宽

3、数据都在服务器中保存,如果客户端出现问题,数据是不会丢失的。

二、Cookie和session的区别

面试官常考题,赶快拿小本本记下来😁😁😁

1、Cookie是客户端(浏览器)存储数据的一种机制,键值对结构,可以存储身份信息,也是可以存储关键的信息,都是程序员自定义,

题外话,浏览器中网页JS代码是禁止访问电脑磁盘,而不是浏览器本身不能访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SCrBirbN-1649601037257)(https://cdn.jsdelivr.net/gh/power152/Image/202204091613832.png)]

2、Session是服务器存储数据的一种机制,键值对结构的,主要用来存储身份相关的信息。

3、Cookie和Session经常在一起配合使用,但也不是必须配合

三、servlet中对Cookie和Session提供的封装

HttpServletRequest 类中的相关方法 :

方法描述
HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果 为 false, 则当不存在会话时返回 null
Cookie[] getCookies()返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把 Cookie 中的格式解析成键值对.

getCookies()方法,是在HttpServletRequest对象中,能够获取到当前请求中的所有Cookie,一个请求中有多个Cookie键值对,每个Cookie键值对,就对应到一个Cookie对象,Cookie对象里面有两个核心的方法:getKey,getValue

但是实际上使用getCookies()方法很少用,更多的时候使用的是getSession()这个方法。

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;


@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
        // 设置utf8,防止页面乱码
        resp.setContentType("text/html;charset=utf-8");
        // 获取用户名和密码,以username=admin&password=123 这种形式获取就用 getparameter() 来操作。
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if (username == null || "".equals(username) || password == null || "".equals(password)) {
            resp.getWriter().write("<h3>用户名和密码位空</h3>");
            return;
        }

        if (!username.equals("admin") || !password.equals("123")) {
            resp.getWriter().write("<h3>用户名或密码错误</h3>");
            return;
        }
		
        // 在服务器中获取会话,参数true,则没有SessionId就会创建SessionId键值对插入到服务器当中。
        HttpSession session = req.getSession(true);  //!!!!!!!!!!!!!
        // HttpSession对象中,根据Key来设置value
        session.setAttribute("visitCount", 0);

        // 登录结果反馈给客户端,反馈的是跳转页面,而不是登录成功
        //  我们需要重定向这个操作
        resp.sendRedirect("index");
    }
}

这段代码是实现用户登录成功的案列,成功的结果就是重定向跳转其他的页面

HttpSession session = req.getSession(true); //getSession()里面的参数是Boolean类型

1、如果参数是true,就会看看请求中是否会有 SessionId,以及SessionId合不合法,如果有SessionId,就会根据这个SessiuonId找到对应 HttpServlet 对象(查hash表),在服务器这边以一个hash表的形式,把若干个Session给组织起来;

​ 如果没有SessionId,那么服务器就会生成一个SessionId,同时创建一个HttpServlet 对象,把这一组键值对再插入到服务器管理的Session的hash表中,同时把 sessionId,通过Set-cookie 在响应中返回给客服端

2、如果参数是false,也是会看请求中是否有SessionId,以及是否合法,如果有SessionId,直接找到对应的 HttpServlet对象,查询各方面的信息,

​ 如果没有SessionId,那么直接返回就是null

关于HttpServlet,再次强调,HttpSerblet对象里面存储的是身份数据信息,每个用户登录都会有自己的身份数据信息,此时服务器上就会有很多的HttpSerblet对象了,而这个HttpServlet对象,是有键值对hash表的方式组织管理而成的

**HttpSession ** 类中的相关的方法:

一个 HttpSession 对象里面包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息

方法描述
Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象,如果没 有指定名称的对象,则返回 null.
void setAttribute(String name, Object value)该方法使用指定的名称绑定一个对象到该 session 会话

在HttpServlet对象中,也是存储了键值对的,根据 Key 获取 value值,就叫 getAttribute,根据 Key 设置 value,就叫setAttribute。

image-20220410214743193

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;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置utf8,防止页面乱码
        resp.setContentType("text/html;charset=utf-8");
        // 获取会话,false说明没有Session,则返回null
        HttpSession session=req.getSession(false);
        if (session == null) {
            resp.getWriter().write("<h3>当前你尚未登录</h3>");
            return;
        }
        // 因为getAttribute()是object类,所以要强制转换成Integer
        Integer visitCount = (Integer) session.getAttribute("visitCount");
        // 拿到上次的访问次数的值,现在有访问了一次所以 + 1
        visitCount +=1;
        // 把这个值写回到 session 中, 以备下次访问中使用.
        session.setAttribute("visitCount",visitCount);
        resp.getWriter().write("<h3>visitCount:"+ visitCount+"</h3>");

    }
}

这段代码是实现一个登录的案列,记录的是当前客服访问的次数。在上一段代码中session.setAttribute("visitCount", 0);就已经在HttpServlet中设置了访问次数,然后这段代码就是获取到上次代码的访问次数0,然后然后访问成功就visitCount+=1,最后就是把值写到session中,以备下次使用,然后在从页面中打印出来。


总结:(八股文)

实现一个登录的常规流程:

1、读取用户的用户名和密码(这个需要前端代码)

2、对用户名和密码进行校验

3、判断是否登录成功

4、创建会话,保存自定义信息

5、重定向到登录成功的主页面。


以上信息存储在session(会话)中都是,存储在内存中的,也就是说服务器重新启动过后,session信息就会没有,需要重新登录获取信息才行。

第一次登录抓包:

image-20220410194338661

登录成功后:

image-20220410214143070

登录成功后,服务器就会存储这个Session(会话),下一次客服端拿着SessionId就可在服务器会话中找到对应的键值对。

如果重启服务器,session里面的数据就会全部消失!!!

再次请求,原来的SessionId都还在,但是拿着这个SessionId去服务器找的话,就会找不到。

只有客服端再次登录成功生成新的SessionId,再给客服端分配新的SessionId,客户端又可以反复使用了。

这篇帖子的代码,在gitee上:servlet02


这是在我们进行网络传输登录中Cookie和Session的工作流程,两个都是互相配合,共同实现的。觉得博主写的不错就,收藏关注呗❤🧡💛💚💙💜🤎🖤🤍💟,你们支持就是我写博客最大的动力!!!!

  • 41
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸢也

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值