【Java EE初阶二十七】深入了解cookie

1. 简单了解cookie

        Cookie是http请求里header 中的一个属性,浏览器持久化存储数据的一种机制,网页无法访问主机的文件系统,要想存储数据就得通过其他的方式;

        且cookie中保存的数据也是键值对的形式,最终还是要把这个键值对发送回服务器,服务器要使用 Cookie 来完成一些业务逻辑;其中有一个特殊的情况,就是会使用 Cookie 存储当前用户的身份信息;

        我们当前坐火车的时候都需要身份证,此时当前的身份证就可以理解是我们每一个人的特有cookie,当我们在进行出站和进战的时候,就需要拿身份证在机器上扫描,这时候通过身份证就可以读取到我们坐车的相关信息,这些信息肯定是从服务器中接收到的,我们每一个人的出行信息必然是存储在数据库中的,在服务器代码的逻辑展开执行的过程中,这些数据就也会被从数据库査询出来,先临时的保存到某个内存结构(session)中,后续要是修改数据,就要重新写入数据库

        Cookie 是客户端存储数据的机制,Session 是服务器存储数据的机制(不算持久化存储),当然两者往往会相互配合使用的,

        在 cookie 中存储的用户身份标识,也经常会理解成 sessionld; 每个用户都有一个自己的 session, 也有不同的 séssionld;

        服务器会通过类似于 hash 这样的键值对结构来存储 session 的。sessionld 就是 key,session 本身就是 value,在 session 里面又可以存储各种的用户自身的信息 (也是程序员自定义的);

        下图是cookie和session之间工作的原理图解:

2. 深入了解cookie

        通过 Servlet api 来操作上述结构;

        Cookie 是浏览器的机制,,Servlet 提供了 api 获取到 Cookie.
        Session 是服务器的机制,Servlet 内部已经实现好了,也提供了 api 可以让我们进行使用。

        

        这个方法主要是给登录场景应用的,就能够完成从 cookie 中获取到 sessionld,并且查询出对应 session 的过程,如果 sessionld 没有从 hash 表查到,也能帮咱们自动的创建出新的键值对(分配新的 sessionld,以及创建一个新的 HttpSession 对象)

        servlet中通过 httpsession这个类表示一个会话,服务器上同时具有很多个会话,服务器上就会存在一个如下所示的会话,

2.1 实现登录的原理

1、登录页面(html)

        

        点击登录buttion之后发起一个 HTTP 请求,触发登录逻辑(带上用户输入的用户名和密码)

2、通过一个 Servlet 处理上述的登录请求
        通过这个 Servlet 读取用户名和密码,并且验证是否登录成功,如果登录成功,就会给当前这个用户,创建一个会话(保存用户当前的信息),并且把得到的 sessionld, 通过 cookie 返回给客户端(客户端就把 cookie 保存起来了)

3、网站主页,通过另一个 Servlet 生成的动态页面
        在这个页面中,就会把刚才这里的用户数据给显示到页面上,比如是使用"smallye" 用户来登录
,主页上就会显示"欢迎你 smallye" 这样的标语;

2.2 项目逐步编写

 1、先开始搞真被登陆页面

        此处的登录, 使用 json 也不是不可以,但是使用 json 就无法使用 form 表单了,使用json
就雲要通过 ajax 的方式构造请;同时接下来,服务器这边处理的逻辑, 就按照这个格式来处理

 2、写一个 Servlet 处理上述登录请求.

  

        这个方法,就是根据请求的 cookie 中的 sessionld,查询服务器的hash 表,找到对应的 session 对象,如果 cookie 中没有 sessionld(首次登录的时候,就是没有的),或者 sessionld 没有査找到对应的 session 对象,就可以创建出一个sesion 对象出来;即会创建出一个 sessionld 和一个 session 对象,把这个键值对保存到 hash 表里(会再响应报头中加上 Set-cookie 字段),servlet并且会把 sessionld 设置到响应中, 传回给浏览器, 让浏览器使用 Cookie 来保存;

        在该方法中的设置参数为 true,即允许在不存在时自动创建session对象.参数为 false则不能创建session对象, 直接返回 null;

        文里使用 Attribute 的作用, 主要就是为了让多个数据,在多个 Servlet 之间共享,同时 Attribute 是会话级别的.每个用户/客户端都是有自己的数据, 相互之间都不会有干扰;

3、关于多客户端显示的不同界面的问题

        如果这个 Servlet 是通过第一个浏览器调用的,此时Servlet 里面拿到的就是 zhangsan 这个 Session 对象,及其里面的数据;如果这个 Servlet是通过第二个浏监器调用的,此时 Servlet 里面拿到的就是 lisi 这个 Session 对象,及其里面的数据,通过 sessionld 取会话对象,(两个浏览器的sessionld 不同);

        综上所述,同样的页面,不同用户看到的数据肯定也是不同的,对于b站的页面我们自己访问这个页面看到的数据和其他人访问的这个页面看到的数据是必然是完全不同的;

        上述代码就是重定向跳转到 index 页面上(后续会写一个 Servlet 生成这个页面);

4、实现登录后的主页

        会话就可以理解成"用户身份信息”体现,在通过登录操作,验证了用户身份之后,才能够创建会话.,其他页面没有做"验证身份",不应该创建会话;

2.3 服务器代码如下

登录代码:

package login;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 {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 读取请求传来的参数 (用户名和密码)//    最好先给请求设置一下字符集. 否则如果 username 是中文, 此处的 getParameter 可能会乱码.req.setCharacterEncoding("utf8");String username = req.getParameter("username");String password = req.getParameter("password");// 2. 验证用户名密码, 是否是正确的. 一般来说, 验证用户名密码, 是要通过数据库的.//    此处为了简单一点, 先把用户名和密码, 写死. 比如此处假设正确的用户名是 zhangsan, 正确的密码是 123//    此处还要注意, 上述 getParameter 可能会拿到 null .  为了避免 空指针异常, 下面这种比较方式是更合适的写法.if (!"zhangsan".equals(username) || !"123".equals(password)) {// 登录失败// 给用户返回一个提示.resp.setContentType("text/html; charset=utf8");resp.getWriter().write("当前的用户名或者密码错误!");return;}// 3. 登录成功了, 给这个用户创建一个会话出来.//    可以给会话中保存一些自定义的数据, 通过 Attribute 的方式来保存.HttpSession session = req.getSession(true);//    此处 Attribute 也是键值对. 这里的内容存储什么都可以. 程序员自定义的.//    这样的数据存储好了之后, 后续跳转到其他的页面, 也随时可以把这个数据从会话中取出来.session.setAttribute("username", username);session.setAttribute("loginTime", System.currentTimeMillis());// 4. 此时相当于登录成功!! 让页面跳转到网站首页.resp.sendRedirect("index");}
}

重定向代码:

package login;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;// 通过这个 Servlet 生成一个 主页
@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 先获取到当前用户对应的会话对象. 生成的页面要根据当前用户信息来构造.HttpSession session = req.getSession(false);if (session == null) {// sessionId 不存在, 或者 sessionId 没有在 hash 表中查到.resp.setContentType("text/html; charset=utf8");resp.getWriter().write("您当前尚未登录!");return;}// 2. 从会话中拿到之前存储的用户信息//    此处的强转, 需要程序员自行保证, 类型是靠谱的.String username = (String) session.getAttribute("username");Long loginTime = (Long) session.getAttribute("loginTime");// 3. 生成一个页面, 把上述数据显示到页面上.resp.setContentType("text/html; charset=utf8");String respBody = "欢迎你 " + username + "! 上次登录时间为: " + loginTime;resp.getWriter().write(respBody);}
}

2.4 过程分析

1)、点击登录之后,就会触发一个 POST 请求

2)、服务器响应

        此处 getSession 会创建新会话:
        1、生成 sessionld 和 HttpSession对象

        2、把上述 sessionld 和 HttpSession 对象保存到 内存 hash 表中.
        3、把 sessionld 设置到响应报文的 header 中Set-Cookie 字段,如下所示:

        浏览器拿到响应,就会把这个 Set-Cookie 的内容保存到浏览器的 Cookie 中:

3、重定向到主页.(index)

        

3. 在说cookie和session

        浏览器首次访问登录操作的时候,就会在服务器这边验证身份。验证通过,就会创建会话,服务器就会保存会话信息 (hash),客户端也会保存身份标识(sessionld),后续浏览器再访问这个网站(网站的其他页面) 都会带上 cookie(sessionld),服务器不需要让浏览器重新登录,也能识别出浏览器的用户身份信息.

        一个网站,只要登录成功之后,后续访问这个网站的其他页面,也都是会处在一个 登录 状态
上述过程都是可以借助 cookie 和 session 来完成的;

        上述已登录的状态也会有时间限制,有的网站过期时间比较长(B 站),有的过期时间比较短.(网银),可以给 Cookie 设置过期时间,(即时间一到,浏览器就会自动把 Cookie 删除掉),也可以给 session 设置过期时间,(时间到,服务器自动删除会话 )

ps:关于cookie和session的深入学习就到这里了,如果大家感兴趣的话就请一键三连哦!!!

        

 

        

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/265487.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vite是什么

vite 是什么 vite —— 一个由 vue 作者尤雨溪开发的 web 开发工具 Vite由两个主要部分组成 dev server:利用浏览器的ESM能力来提供源文件,具有丰富的内置功能并具有高效的HMR生产构建:生产环境利用Rollup来构建代码,提供指令用…

【Ubuntu】通过网线连接两台电脑以实现局域网连接的方法

有时我们需要将多台计算机连接在一起,以便实现数据共享、资源访问等功能。本文将介绍如何通过网线连接两台运行Ubuntu操作系统的电脑,以便它们能够直接通信,从而实现局域网连接。 1. 准备工作 在开始之前,请准备好: …

QT摄像头采集

主界面为显示框&#xff0c;两个下拉框&#xff0c;一个是所有相机&#xff0c;一个是相机支持的分辨率 系统根据UI界面自动生成的部分不再描述&#xff0c;以下为其他部分源码 widget.h #include <QWidget> #include <QMouseEvent> class QCamera; class QCamer…

技术派数据库表自动初始化(学习)

不需要在db中手动创建或者导入相关的schema、data&#xff0c;项目启动自动创建对应的表&#xff0c;并初始化。实现该过程。 Liquibase数据库版本管理 依赖配置 在paicoding-web模块中&#xff0c;pom.xml 文件中添加 <dependency><groupId>org.liquibase</g…

Rocky Linux 运维工具 mv

一、mv的简介 ​​mv​是Linux系统中的命令&#xff0c;用于移动文件或重命名文件。它可以在同一文件系统内将文件从一个目录移动到另一个目录&#xff0c;也可以修改文件的名称。 二、mv的参数说明 1、 三、mv的实战示例 1、重命名 ###查看目录/root/下的文件列表 [rootloc…

Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件

场景 Pythont通过request以及BeautifulSoup爬取几千条情话&#xff1a; Pythont通过request以及BeautifulSoup爬取几千条情话_爬取情话-CSDN博客 Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本&#xff1a; Node-RED中使用html节点爬取HTML网页资料之爬…

Java JVM虚拟机面试题

Java JVM虚拟机面试题 前言1、ThreadLocal的底层原理和应用&#xff1f;2、Java中的锁池和等待池&#xff1f;3、wait()&#xff0c;yield()&#xff0c;join()&#xff0c;sleep()的区别&#xff1f;4、你们项⽬如何排查JVM问题&#xff1f;5、YGC和FGC发生时间&#xff1f;6、…

vue.config.js publicPath 和 vue-router base 结合配置项目根目录为二级目录案例

背景: 同个域名下需要有 PC 管理后台, H5 端, 企业微信 ......等多个端, 需要在一个域名下通过不同的路径来区分不同的项目; 例如: abc.com/pc, abc.com/h5, abc.com/wx-work.... 此处做个记录 步骤: 1. 修改 vue.config.js 中的 publicPath module.exports {outputDir:…

React18源码: Fiber树中的全局状态与双缓冲

Fiber树构造 在React运行时中&#xff0c;fiber树构造位于 react-reconciler 包在正式解读 fiber 树构造之前&#xff0c;再次回顾一下renconciler的4个阶段 1.输入阶段&#xff1a;衔接react-dom包&#xff0c;承接fiber更新请求2.注册调度任务&#xff1a;与调度中心(schedu…

(二十三)Flask之高频面试点

目录&#xff1a; 每篇前言&#xff1a;Q1&#xff1a;为什么把request和session放在一起&#xff1f;Q2&#xff1a;Local对象的作用&#xff1f;Q3:&#xff1a;LocalStack对象的作用&#xff1f;Q4&#xff1a;一个运行中的Flask应用程序分别包括几个Local/LocalStack&#…

Spring11、整合Mybatis

11、整合Mybatis 步骤&#xff1a; 导入相关jar包 junit <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version> </dependency> mybatis <dependency><groupId>org.my…

docker小知识:linux环境安装docker

安装必要软件包&#xff0c;执行如下命令 yum install -y yum-utils device-mapper-persistent-data lvm2目的是确保在安装 Docker 之前&#xff0c;系统已经安装了必要的软件包和服务&#xff0c;以支持 Docker 的正常运行。设置yum源&#xff0c;添加Docker官方的CentOS存储…

sonar-java 手写一个规则-单元测试分析

前言 最近做项目&#xff0c;定制sonar规则&#xff0c;提高Java代码质量&#xff0c;在编写的sonar规则&#xff0c;做验证时&#xff0c;使用单元测试有一些简单的心得感悟&#xff0c;分享出来。 自定义规则模式 sonar的自定义规则很简单&#xff0c;一般而言有2种模式可…

udp服务器【Linux网络编程】

目录 一、UDP服务器 1、创建套接字 2、绑定套接字 3、运行 1&#xff09;读取数据 2&#xff09;发送数据 二、UDP客户端 创建套接字&#xff1a; 客户端不用手动bind 收发数据 处理消息和网络通信解耦 三、应用场景 1、服务端执行命令 2、Windows上的客户端 3…

【亚马逊云新春特辑②】构生成式 AI 文生图工具之借助ControlNet进行AI绘画创作【生成艺术二维码】

文章目录 1.1 生成艺术二维码1&#xff09;制作基础二维码2&#xff09;确定艺术风格3&#xff09;生成艺术二维码4&#xff09;结果优化 AIGC 的可控性是它进入实际生产最关键的一环。在此之前&#xff0c;许多用户希望 AI 生成的结果尽可能符合要求&#xff0c;但都不尽如人意…

linux服务器调度数据库的存储过程

1、需要安装数据库的客户端 2、安装sqlplus 3、编写sh脚本 脚本内容如下&#xff1a; 4、设置调度任务

【GPTs分享】每日GPTs分享之Image Generator Tool

今日GPTs分享&#xff1a;Image Generator Tool。Image Generator Tool是一种基于人工智能的创意辅助工具&#xff0c;专门设计用于根据文字描述生成图像。这款工具结合了专业性与友好性&#xff0c;鼓励用户发挥创造力&#xff0c;同时提供高效且富有成效的交互体验。 主要功能…

4. client-go 编程式交互

Kubernetes 系统使用 client-go 作为 Go 语言的官方编程式交互客户端库&#xff0c;提供对 Kubernetes API Server 服务的交互访问。Kubernetes 的源码中已经集成了 client-go 的源码&#xff0c;无须单独下载。client-go 源码路径为 vendor/k8s.io/client-go。 开发者经常使用…

rviz显示双臂ur10

注意有线网的连接 注意这里rviz只做显示用&#xff0c;并没有结合moveit 步骤总结如下&#xff1a; launch文件&#xff1a;这里tf加上域名&#xff0c;是tool0_controller和base两个tf的前缀 在luanch文件最后就统一加载一次模型&#xff0c;传递两个参数 这里加上另一个机…

【Go语言】Go语言中的切片

Go语言中的切片 1.切片的定义 Go语言中&#xff0c;切片是一个新的数据类型数据类型&#xff0c;与数组最大的区别在于&#xff0c;切片的类型中只有数据元素的类型&#xff0c;而没有长度&#xff1a; var slice []string []string{"a", "b", "c…