当前位置: 首页 > news >正文

【Servlet篇4】cookie和session

在这一篇文章当中,我们提到了什么是cookiesession

【网络原理8】HTTP请求篇_革凡成圣211的博客-CSDN博客HTTP的常见属性,URL,User-Agent,Refer,get 和post的区别https://blog.csdn.net/weixin_56738054/article/details/129180661?spm=1001.2014.3001.5502它们分别是客户端会话技术和服务端会话技术。

分别把用户的信息保存在客户端磁盘服务端,二者一般是相互配合使用的。


       当用户访问一个网站之后,这个网站会把用户的关键信息(例如身份标识符)存储到cookie当中,也就是用户的本地磁盘当中。

       当后续用户再次访问这个网站的时候,就会携带这个cookie,然后在服务器当中根据这个cookie来获取这个用户的其他信息。

下面,就来聊一下session和cookie的常见api

目录

HttpSession session=req.getSession();

 当传入参数为true的时候:

当传入参数为false的时候:

当调用getSession()方法的时候,会做什么事情

步骤1:创建会话

步骤2:获取会话

HttpSession对象

setAttribute()和getAttribute()

Cookie[] getCookies方法

resp.addCookie()方法

实现登录-跳转页面的案例

第一步:约定登录前后端交互的格式

登录接口的请求方式:

登录接口的响应方式:

第二步:约定如何获取主页的交互

获取主页的请求方式:

响应的格式:

第三步:编写登录的接口,并且把用户登录的信息保存在session当中

第四步:编写访问index页面的servlet

实现一个用户访问页面的次数的功能

 如果在其中一个浏览器登录了,可以在另外一个浏览器直接访问登录页面吗?

总结:cookie和session的区别
​​​​​​​​​​​​​​


HttpSession session=req.getSession();

这一个方法,既可以用于获取到服务器上面的会话,又可以用于创建会话。

但是,这一个方法在HttpServletRequest当中是存在多态的。

 当传入参数为true的时候:

会话存在,则获取;会话不存在,则创建


当传入参数为false的时候:

会话存在,则获取;会话不存在,则返回null


当调用getSession()方法的时候,会做什么事情

步骤1:创建会话

首先先获取到HTTP请求头当中cookie这个属性里面的sessionId字段

接着,判断这一个sessionId是否在当前的服务器当中存在。

如果不存在,那么就进入创建会话的逻辑。

       第一步:首先创建一个HttpSession对象,并且生成一个sessionId(用16进制来表示);

       第二步:把sessionId作为key,这一个session对象作为value。保存到服务器的一个类似于"哈希表"的结构当中。(这个数据是保存到内存当中的,并不是持久化的)

       第三步:服务器返回一个HTTP响应,把sessionId通过Set-cookie字段返回给浏览器。

也就是返回给用户

       然后用户下次再次访问的时候,就可以通过这个cookie字段来获取了。 

下面,图解一下创建会话的流程:


步骤2:获取会话

先获取到请求的cookie里面的sessionId字段。

然后判断这个sessionId是否在当前的服务器上面存在(也就是是否在这个哈希表当中存在)

如果有,那么直接返回这个sessionId对应的对象。


HttpSession对象

每一个HttpSession对象都是通过键值对的形式来存储数据的。

当存储数据的时候,需要调用session.setAttribute(k,v)的方式来存储。

key是String的类型,value是Object的类型

看上去有点绕,怎么出现了套娃呢...那就画个图来解释一下吧~:

 一个服务器当中可以有多个session对象,每一个session对象都拥有一个sessionId

一个session对象都对应多个键值对


setAttribute()和getAttribute()

这两个方法,左边的那个是拥有设置key-value的。右边那个是通过key来获取value的。

当调用setAttribute之后,就相当于往已经创建的session对象当中存放key和value


Cookie[] getCookies方法

        通过调用req.getCookies方法,可以获取到用户提交的HTTP请求头当中的cookie字段对应哪些键值对:代码实现

@WebServlet("/servlet4")
public class Servlet4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie[] cookies= req.getCookies();for(int i=0;i<cookies.length;i++){Cookie cookie=cookies[i];System.out.println(cookie.getName()+"...."+cookie.getValue());}}
}

 运行结果:

 使用Fidller抓包:

可以看到,此时服务器就获取到了两个cookie对象。


resp.addCookie()方法

       此处传入的是一个Cookie类型的数据,Cookie也是由键值对组成的结构。键和值都是String类型的数据。

Cookie cookie=new Cookie("hello","hi");
Cookie cookie1=new Cookie("hello","hi");
resp.addCookie(cookie);
resp.addCookie(cookie1);

       这个addCookie方法,其实就相当于给客户端浏览器发送一个cookie类型的键值对。

       然后,可以在HTTP响应报头的set-cookie字段当中看到这一个字段。

   


下面,通过一个网页登录的案例来体会一下cookie和session。

实现登录-跳转页面的案例

第一步:约定登录前后端交互的格式

登录接口的请求方式:

协议版本:HTTP/1.1

请求方法:POST;

请求路径:/Servlet;

接收方式(Content-type)application/x-www.form-urlencoded

(也就是userName="***"&password="***")这样的格式


登录接口的响应方式:

响应行:HTTP/1.1 302(需要重定向);

重定向:Location: index。(重定向到index这个路径)


第二步:约定如何获取主页的交互

获取主页的请求方式:

HTTP版本:HTTP/1.1

请求方法:GET;

请求路径:/index;

没有参数需要提交


响应的格式:

HTTP版本:1.1;

状态码:200;

响应格式:Content-Type: text/html(返回一个html页面)


第三步:编写登录的接口,并且把用户登录的信息保存在session当中

 登录的时候,通过req.getSession()来创建一个session对象

并且把userName存放到session域当中。 

约定需要跳转的路径(/index)

     @WebServlet("/login")
public class Servlet5 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");//处理用户请求String userName=req.getParameter("userName");String password=req.getParameter("password");//此处简单模拟一下登录成功的情况if("张三".equals(userName)&& "123".equals(password)){//往会话当中存储键值对:用于保存用户登录的信息//此处指定的参数为true,那么:需要此时会创建一个sesion对象HttpSession session=req.getSession(true);//把用户名存入session当中,代表用户已经登录成功了session.setAttribute("userName",userName);resp.sendRedirect("index");}else{//登录失败resp.getWriter().write("login faild");}}
}

第四步:编写访问index页面的servlet

       再次调用req.getSession方法,但是此处需要指定参数为false

       因为此处的session就是为了验证用户登录与否,无需再次创建新的会话。

       此处的session对象和第三步当中的session期待是同一个session对象。

       因为期待是同一个会话。

@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取到用户名//此处getSession参数为false,原因:此处已经创建过会话了HttpSession session =req.getSession(false);resp.setCharacterEncoding("utf-8");//根据key来获取valueString userName= (String) session.getAttribute("userName");//返回一个主页resp.getWriter().write("<h3>欢迎你!"+userName);}
}


实现一个用户访问页面的次数的功能

无需太大的改动。只需在用户登录的时候,设置一个count统计用户登录的次数。这一个count需要使用session保存。

然后在页面(index)处,每一次用户取出来数据,都要+1。

代码实现:

登录页面

@WebServlet("/login")
public class Servlet5 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");//处理用户请求String userName=req.getParameter("userName");String password=req.getParameter("password");//此处简单模拟一下登录成功的情况System.out.println(userName+"..."+password);if("张三".equals(userName)&& "123".equals(password)){//往会话当中存储键值对:用于保存用户登录的信息//此处指定的参数为true,那么:需要此时会创建一个sesion对象HttpSession session=req.getSession(true);//把用户名存入session当中,代表用户已经登录成功了session.setAttribute("userName",userName);//登录成功,默认初始的值为0session.setAttribute("count",0);resp.sendRedirect("index");}else{//登录失败resp.getWriter().write("login faild");}}
}

index页面

@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取到用户名//此处getSession参数为false,原因:此处已经创建过会话了HttpSession session =req.getSession(false);//根据key来获取valueString userName= (String) session.getAttribute("userName");resp.setCharacterEncoding("utf-8");//获取一个count的值Integer count= (Integer) session.getAttribute("count");Integer newCount=count+1;//在session当中保存自增过后的countsession.setAttribute("count",newCount);//返回一个主页resp.getWriter().write("<h3>欢迎你!"+userName+"您访问此页面的次数为:"+newCount);}
}

 如果在其中一个浏览器登录了,可以在另外一个浏览器直接访问登录页面吗?

 不行的。来做个实验看一下:

 首先,启动Tomcat,默认在360安全浏览器打开页面。

然后登录(登录的接口跟上面的是一样的,都是/login),同时使用Fidler抓包

然后,再抓一下访问index页面的URL的包:


换一个浏览器,再次访问index页面的URL

       可以看到,换了一个浏览器,因为cookie当中包含的sessionID不一样了,也就没有办法保存原来sessionid当中的值,那么就无法获取到在原来的浏览器保存的session信息了。

        (每一个浏览器都会有自己的cookie,也就意味着不同的浏览器有不同的sessionId)


总结:cookie和session的区别

使用对象数据类型安全性存储大小存储位置
cookie

针对网站:

每一个网站都会被分配一组cookie

(String,String)比较低,容易丢失、篡改较小;一个cookie不超过3K保存在客户端浏览器(磁盘)
session

针对用户:

只有客户端才可以访问。

程序为客户端添加一个sessionId.

一个sessionId对应一个HttpSession对象

(String,Object)比较高可以存储任意大的数据保存在服务端

       

相关文章:

【Servlet篇4】cookie和session

在这一篇文章当中&#xff0c;我们提到了什么是cookie和session。 【网络原理8】HTTP请求篇_革凡成圣211的博客-CSDN博客HTTP的常见属性&#xff0c;URL&#xff0c;User-Agent&#xff0c;Refer,get 和post的区别https://blog.csdn.net/weixin_56738054/article/details/1291…...

考研流程,可以进来转一转(考研你不知道的事情)(详细版)

之前有听过好多人说要考研&#xff0c;那么&#xff0c;考研的信息&#xff0c;如何获取呢&#xff0c;考研都有哪些流程呢。 初试开始到考试&#xff1a;↓ 1、了解考研信息。 2、确定自己要报考的专业。&#xff08;本专业or跨考&#xff09; 3、选择地区 4、选择要报考的学…...

3.2 LED闪烁流水灯蜂鸣器

LED闪烁1.1 电路连接示意图LED采用低电平点亮的方式&#xff0c;利用ST-Link的3.3V进行供电。1.2程序设计1.21知识储备GPIO配置步骤步骤&#xff1a;1. 第⼀步&#xff0c;使⽤RCC开启GPIO的时钟2. 第⼆步&#xff0c;使⽤GPIO_Init()函数初始化GPIO3. 第三步&#xff0c;使⽤输…...

刷题笔记3 | 203. 移除链表元素、707设计链表,206.反转链表

目录 203. 移除链表元素 707、设计链表 206.反转链表 203. 移除链表元素 题意&#xff1a;删除链表中等于给定值 val 的所有节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 示例 2&#xff1a; 输入&#xff1a;h…...

[一篇读懂]C语言十一讲:单链表的删除和单链表真题实战

[一篇读懂]C语言十一讲&#xff1a;单链表的删除和单链表真题实战1. 与408关联解析及本节内容介绍1 本节内容介绍2. 单链表的删除操作实战3. 单链表真题解读与解题设计1 题目解读2 解题设计第一阶段&#xff1a;双指针找中间结点第二阶段&#xff1a;原地逆置第三阶段&#xff…...

【C++初阶】list的使用

大家好我是沐曦希&#x1f495; 文章目录一、前言二、构造三、迭代器四、增删查改1.头插头删2.尾插尾删3.查找和插入4.删除五、其他成员函数1.排序和去重2.splice和remove3.resize一、前言 list本质是带头双向循环链表&#xff0c;本文只对list的一些常用接口进行说明&#xf…...

HTML 布局

网页布局对改善网站的外观非常重要。 请慎重设计您的网页布局。 在线实例 使用 <div> 元素的网页布局 如何使用 <div> 元素添加布局。 使用 <table> 元素的网页布局 如何使用 <table> 元素添加布局。 网站布局 大多数网站会把内容安排到多个列中&a…...

如何在虚拟机中安装ikuai软路由系统

首先访问ikuai官网下载固件固件下载-爱快 iKuai-商业场景网络解决方案提供商 (ikuai8.com) 根据需求下载 然后创建一个虚拟机&#xff0c;点击下一步 选择更下载的ISO映像文件&#xff0c;点击下一步 点击下一步 设置一下名称和储存位置&#xff0c;点击下一步 根据需求设置&a…...

Java 多线程 --- 线程协作 wait/notify

Java 多线程 --- 线程协作 wait/notifywait / notifyObject.wait() , Object.notify() / notifyAll()notify 和 wait 的原理notify会导致死锁的问题wait / notify的开销以及问题wait / notify 在多线程中, 如果程序拿到锁之后, 但是没有满足指定条件而不能继续往下执行, 我们可…...

【PyTorch】教程:torch.nn.Hardsigmoid

torch.nn.Hardsigmoid 原型 CLASS torch.nn.Hardsigmoid(inplaceFalse) 参数 inplace (bool) – 默认为 False 定义 Hardsigmoid(x){0if x≤−3,1if x≥3,x/61/2otherwise\text{Hardsigmoid}(x) \begin{cases} 0 & \text{if~} x \le -3, \\ 1 & \text{if~} x \ge 3…...

【手把手一起学习】(八) Altium Designer 20修改和自定义原理图标题栏

1 修改原理图标题栏 直接对原理图标题栏属性进行修改&#xff0c;操作如图所示&#xff1a; 修改后&#xff0c;并不会显示&#xff0c;故该方法不可用&#xff1a; 正确的操作如下&#xff0c;先选择合适的模板&#xff1a; 然后&#xff0c;进行属性的修改&#xff1a; 此时…...

业务流程测试

用例设计主要问题主要问题存在于&#xff1a;1、测试点分析&#xff1a;逻辑性不强对于整个页面功能划分不清晰&#xff1b;不同测试点归类不清晰&#xff1b;不能形成相对固定的套路&#xff0c;书写耗费大量时间...2、测试用例&#xff1a;关于&#xff0c;要细致到什么程度&…...

[极客大挑战 2019]EasySQL 1

[极客大挑战 2019]EasySQL 1解题POC一、解题思路之暴力破解1. 弱口令2. 暴力破解二、解题思路之万能密码1. 什么是万能密码2. 测试过程解题POC 直接点击登录获取flagflag{62f0d2ca-579e-450e-941f-5f7c23a8baf7} 一、解题思路之暴力破解 这题是万能密码&#xff0c;所以暴力破解…...

vulnhub raven2复现

1.扫描全网段&#xff0c;找出了存活主机ip为192.168.85.144 nmap 192.168.85.0/24 2.nmap扫描端口 nmap -p1-65535 192.168.85.144 3.访问此网站&#xff0c;没找到什么地方可以利用漏洞 &#xff0c;查看中间件为wordpress 4.使用dirb对该网站进行目录扫描 dirb http://1…...

LeetCode 剑指 Offer II 079. 所有子集

给定一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1,2],[3…...

打印名片-课后程序(Python程序开发案例教程-黑马程序员编著-第二章-课后作业)

实例3&#xff1a;文本进度条 进度条以动态方式实时显示计算机处理任务时的进度&#xff0c;它一般由已完成任务量与剩余未完成任务量的大小组成。本实例要求编写程序&#xff0c;实现图1所示的进度条动态显示的效果。 下载中下载完成图1文本进度条 实例分析 在本实例中可以将…...

为什么我们在判断字符串不为null后还要判断字符串长度大于0?

我们在做字符串判断时一般会&#xff1a; if (s ! null && s.length() > 0) {} 但是我就在想&#xff0c;字符串不为空了&#xff0c;那么他一定有值&#xff0c;字符串长度不就大于0吗&#xff0c;所以s.length()>0是不是有点多余&#xff1f; 我的思维误区是…...

javaEE 初阶 — 应用层中的 DNS 协议(域名解析系统)

文章目录什么是域名1. 如何建立 域名 与 IP 的对应关系2. 域名的分级什么是域名 域名也就是平常所说的网址&#xff0c;比如 www.baidu.com。 其实网络上的服务器要访问这个网址&#xff0c;需要的是 IP 地址。、 但是 IP 地址比较拗口不方便记忆&#xff0c;于是就有使用一些…...

【网络】-- 网络编程套接字(铺垫、预备)

目录 理解源IP地址和目的IP地址 认识端口号 端口号 理解源端口号和目的端口号 套接字 认识TCP与UDP协议 网络字节序 socket编程接口 socket 常见API sockaddr结构 理解源IP地址和目的IP地址 就如同我们唐僧的取经路&#xff1a; 唐僧的出发地到目的地&#xff1a;东…...

一文打通@SentinelResource

Sentinel 提供了 SentinelResource 注解用于定义资源&#xff0c;并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等 如果使用的是Sentinel Annotation AspectJ Extension&#xff0c;需要导这个依赖 <dependency><groupId>com.alibaba.csp</…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...

dvwa11——XSS(Reflected)

LOW 分析源码&#xff1a;无过滤 和上一关一样&#xff0c;这一关在输入框内输入&#xff0c;成功回显 <script>alert(relee);</script> MEDIUM 分析源码&#xff0c;是把<script>替换成了空格&#xff0c;但没有禁用大写 改大写即可&#xff0c;注意函数…...