https|Cookie 和 Session

Cookie 和 Session
文章目录

  • Cookie 和 Session
    • 一、session
    • 二、Cookie和session的区别
    • 三、servlet中对Cookie和Session提供的封装

前言:
这篇帖子重点讲讲Cookie和Session之间的区别,以及作用,Cookie在http协议中就提到了他的定义,作用,小伙伴们可以跳转到 Http协议 这个页面看看Cookie的基本概念及作用。
前情回顾:
1、Cookie是浏览器提供的一种让程序员在本地存储数据的能力,让数据在客户端这边更持久化。
2、Cookie里面存的是键值对的格式数据,键值对用“;”分割,键和值之间用“,”分割。
3、浏览器里面存的Cookie都是从服务器的响应“报头”里面的 set-cookie 字段中来的,每个 set-cookie 字段里面都包含一个Cookie 这样的键值对,浏览器拿到响应之后就会把 set-cookie中的内容保存到本地,而 set-cookie 就是程序员自己在服务器中构造填写的。
经典cookie运用场景,保存用户登录信息:
https|Cookie 和 Session
文章图片

在传输的过程中,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代码是禁止访问电脑磁盘,而不是浏览器本身不能访问
https|Cookie 和 Session
文章图片

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("用户名和密码位空
"); return; }if (!username.equals("admin") || !password.equals("123")) { resp.getWriter().write("用户名或密码错误
"); 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。
https|Cookie 和 Session
文章图片

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("当前你尚未登录
"); return; } // 因为getAttribute()是object类,所以要强制转换成Integer Integer visitCount = (Integer) session.getAttribute("visitCount"); // 拿到上次的访问次数的值,现在有访问了一次所以 + 1 visitCount +=1; // 把这个值写回到 session 中, 以备下次访问中使用. session.setAttribute("visitCount",visitCount); resp.getWriter().write("visitCount:"+ visitCount+"
"); } }

这段代码是实现一个登录的案列,记录的是当前客服访问的次数。在上一段代码中session.setAttribute("visitCount", 0); 就已经在HttpServlet中设置了访问次数,然后这段代码就是获取到上次代码的访问次数0,然后然后访问成功就visitCount+=1,最后就是把值写到session中,以备下次使用,然后在从页面中打印出来。
总结:(八股文)
实现一个登录的常规流程:
1、读取用户的用户名和密码(这个需要前端代码)
2、对用户名和密码进行校验
3、判断是否登录成功
4、创建会话,保存自定义信息
5、重定向到登录成功的主页面。
以上信息存储在session(会话)中都是,存储在内存中的,也就是说服务器重新启动过后,session信息就会没有,需要重新登录获取信息才行。
【https|Cookie 和 Session】第一次登录抓包:
https|Cookie 和 Session
文章图片

登录成功后:
https|Cookie 和 Session
文章图片

登录成功后,服务器就会存储这个Session(会话),下一次客服端拿着SessionId就可在服务器会话中找到对应的键值对。
如果重启服务器,session里面的数据就会全部消失!!!
再次请求,原来的SessionId都还在,但是拿着这个SessionId去服务器找的话,就会找不到。
只有客服端再次登录成功生成新的SessionId,再给客服端分配新的SessionId,客户端又可以反复使用了。
这篇帖子的代码,在gitee上:servlet02
这是在我们进行网络传输登录中Cookie和Session的工作流程,两个都是互相配合,共同实现的。觉得博主写的不错就,收藏关注呗?,你们支持就是我写博客最大的动力!!!!

    推荐阅读