Cookie/Session

1.Cookie

HTTP 协议自身是属于 "无状态" 协议.
"无状态" 的含义指的是:
默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了.

上述图中的 "令牌" 通常就存储在 Cookie 字段中.

此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作。
理解Session
我们先来了解⼀下什么是会话.
会话: 对话的意思

 

在计算机领域, 会话是⼀个客户与服务器之间的不中断的请求响应.
对客户的每个请求,服务器能够识别出请求来自于同⼀个客户.
当⼀个未知的客户向Web应用程序发送第⼀个请求时就开始了⼀个会话.
当客户明确结束会话或服务器在⼀个时限内没有接受到客⼾的任何请求时,会话就结束了.

比如我们打客服电话
每次打客服电话, 是⼀个会话. 挂断电话, 会话就结束了
下次再打客服电话, ⼜是⼀个新的会话.
如果我们⻓时间不说话, 没有新的请求, 会话也会结束

服务器同⼀时刻收到的请求是很多的.

服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与用户的信息的对应关系.(不同的用户所接受的服务是不同的,session存取着用户的信息)

2.Session

Session是服务器为了保存用户信息而创建的⼀个特殊的对象

Session的本质就是⼀个 "哈希表", 存储了⼀些键值对结构.

Key 就是SessionID, Value 就是用户信息(用户信息可以根据需求灵活设计) 

SessionId 是由服务器生成的⼀个 "唯⼀性字符串",
从 Session 机制的角度来看, 这个唯⼀性字符串称 为 "SessionId".
但是站在整个登录流程中看待, 也可以把这个唯⼀性字符串称为 "token".
上述例子中的令牌ID, 就可以看做是SessionId, 只不过令牌除了ID之外, 还会带⼀些其他信息, 比如时间, 签名等.

 1. 当用户登陆的时候, 服务器在 Session 中新增⼀个新记录, 并把 sessionId返回给客户端. (通过
HTTP 响应中的 Set-Cookie 字段返回).--服务器生成一个session,并将sessionid返回给客户端
2. 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId. (通过 HTTP 请求中的
Cookie 字段带上
).
3. 服务器收到请求之后, 根据请求中的 sessionId在 Session 信息中获取到对应的用户信息, 再进行后续操作.

找不到则重新创建Session, 并把SessionID返回

Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.  

Cookie 和 Session 的区别
• Cookie 是客户端保存用户信息的⼀种机制. Session 是服务器端保存用户信息的⼀种机制.
• Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁
• Cookie 和 Session 经常会在⼀起配合使用. 但是不是必须配合.
◦ 完全可以用 Cookie 来保存⼀些数据在客户端. 这些数据不⼀定是用户身份信息, 也不⼀定是
SessionId
◦ Session 中的sessionId 也不需要⾮得通过 Cookie/Set-Cookie 传递, ⽐如通过URL传递. 

 3.Cookie的获取方式

  • Spring MVC是基于 Servlet API 构建的原始 Web 框架, 也是在Servlet的基础上实现的。
  • HttpServletRequest , HttpServletResponse 是Servlet提供的两个类, 是Spring MVC⽅法的内置对象. 需要时直接在方法中添加声明即可。
  • HttpServletRequest 对象代表客⼾端的请求, 当客⼾端通过HTTP协议访问服务器时,HTTP请
  • 求头中的所有信息都封装在这个对象中,通过这个对象提供的⽅法,可以获得客⼾端请求的所有信
  • HttpServletResponse 对象代表服务器的响应. HTTP响应的信息都在这个对象中, 比如向客户端发送的数据, 响应头, 状态码等. 通过这个对象提供的⽅法, 可以获得服务器响应的所有内容
  • Spring MVC在这两个对象的基础上进⾏了封装, 给我们提供更加简单的使用方法.

3.1 cookie的伪造方式 

1.postman的cookie设置

 

2.简洁获取Cookie 

@RequestMapping("/get")
@RestController
public class Method {@RequestMapping("/cookie")public String getCookie(@CookieValue("cookie") String cookie){if(cookie==null){return "你没有设置cookie值";}else{return "获取的cookie值:"+cookie;}}
}

4.Session  

4.1 存储和获取session

Session 存储和获取

Session是服务器端的机制, 我们需要先存储, 才能再获取

Session 也是基于HttpServletRequest 来存储和获取的

    @RequestMapping("/setSession")public String setSession(HttpServletRequest request){HttpSession httpSession=request.getSession();if(httpSession!=null){httpSession.setAttribute("userNanme","lay");
//前面是存储的名字,后面是你要存的东西。我们通过前者拿session
//前者是sessionid后者是value}return "session设置成功";}

 这个代码中看不到 SessionId 这样的概念的. getSession 操作内部提取到请求中的Cookie ⾥的
SessionId, 然后根据SessionId获取到对应的Session 对象, Session 对象⽤HttpSession来描述

 获取Session有两种⽅式

HttpSession getSession ( boolean create);
HttpSession getSession ();
HttpSession getSession(boolean create) :
参数如果为 true, 则当不存在会话时新建会话;
参数如果 为 false, 则当不存在会话时返回 null
HttpSession getSession(): 和getSession(true) 含义⼀样, 默认值为true.
void setAttribute(String name, Object value): 使⽤指定的名称绑定⼀个对象到该 session 会话

 4.2 session读取

读取 Session 可以使⽤ HttpServletRequest

    @RequestMapping("/getSess")public String sess(HttpServletRequest request) {// 如果 session 不存在, 不会⾃动创建HttpSession session = request.getSession(false);String username = null;if (session != null && session.getAttribute("username") != null) {username = (String) session.getAttribute("username");}return "username:" + username;}

此时我们来读取session,发现为空,那是因为我们并没有存进去。 

我们设置的sessionid是userName,而我们读取的是username。通过改变4.1的代码来看结果。

 

设置成功!!!

简洁写法

    @RequestMapping("/setSession1")public String setSession1(HttpSession httpSession){if(httpSession!=null){httpSession.setAttribute("username","lay");//前面是存储的名字,后面是你要存的东西。我们通过前者拿session}return "session设置成功";}@RequestMapping("/getSession1")public String getSess1(HttpSession session) {// 如果 session 不存在, 不会⾃动创建String username = null;if (session != null && session.getAttribute("username") != null) {username = (String) session.getAttribute("username");}System.out.println(username);return "username:" + username;}

 同样是成功的!!!

5.获取header 

    @RequestMapping("/header")public String header(@RequestHeader("User-Agent") String userAgent) {return "userAgent:"+userAgent;}

//记住@绑定时,前者是改正前,后者是改正后。

//我们返回的是后者

6.设置状态码

Spring MVC会根据我们⽅法的返回结果⾃动设置响应状态码,

程序员也可以⼿动指定状态码

通过Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置

 通过Fiddler来观察设置的结果:

状态码不影响⻚⾯的展⽰ 

7 设置header

这些信息通过 @RequestMapping 注解的属性来实现
先来看 @RequestMapping 的源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {String name() default "";@AliasFor("path")String[] value() default {};@AliasFor("value")String[] path() default {};RequestMethod[] method() default {};String[] params() default {};String[] headers() default {};String[] consumes() default {};String[] produces() default {};
}

1. value: 指定映射的URL
2. method: 指定请求的method类型, 如GET, POST等
3. consumes: 指定处理请求(request)的提交内容类型(Content-Type),例如application/json,
text/html;
4. produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
5. Params: 指定request中必须包含某些参数值时,才让该⽅法处理
6. headers: 指定request中必须包含某些指定的header值,才能让该⽅法处理请求 

7.1 设置Content-Type

我们通过设置 produces属性的值, 设置响应的报头Content-Type

@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {return "{\"success\":true}";
}

7.2 设置其他Header

设置其他Header的话, 需要使⽤Spring MVC的内置对象HttpServletResponse 提供的⽅法来进⾏设置 

@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {response.setHeader("MyHeader","MyHeaderValue");return "设置Header成功";
}

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

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

相关文章

创建数据库管理账户以及授权

一、创建数据酷管理账户命令 为了保障数据库系统的安全性,以及让 其他用户协同管理数据库,可以在MariaDB数据库管理系统中为他们创建多个专用的数据库管理账户,然后再分配合理的权限,以满足他们的工作需求. 使用root管理员 登录…

自定义类型(二)结构体位段,联合体,枚举

这周一时兴起,想写两篇文章来拿个卷吧,今天也是又来写一篇博客了,也是该结束自定义类型的学习与巩固了。 常常会回顾努力的自己,所以要给自己的努力留下足迹。 为今天努力的自己打个卡,留个痕迹吧 2024.03.30 小闭…

LInux|命令行参数|环境变量

LInux|命令行参数|环境变量 命令行参数main的参数之argc&#xff0c;argv几个小知识<font color#0099ff size 5 face"黑体">1.子进程默认能看到并访问父进程的数据<font color#4b0082 size 5 face"黑体">2.命令行创建的程序父进程都是bash 环…

微分方程错题本

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

【Qt】:信号与槽(二)

信号与槽 一.带参数的信号和槽二.信号与槽的多对多连接三.信号与槽的断开四.lamda表达式定义槽函数 一.带参数的信号和槽 Qt的信号和槽也⽀持带有参数,同时也可以⽀持重载.此处我们要求,信号函数的参数列表要和对应连接的槽函数参数列表⼀致.&#xff08;一致指的是类型一致&a…

mysql安装遇到的问题

最近mysql安装遇到了许多问题 这个界面是下载器界面&#xff0c;reconfigure是重新配置这个版本&#xff0c;要新安装要点add 进入这个界面选择对应的版本下载

MySQL 数据库基础操作详解

文章目录 MySQL 数据库基础操作详解1. 基本概念2. 库的操作3. 表的操作4. 数据操作5. 示例示例一&#xff1a;创建表和插入数据示例二&#xff1a;查询数据示例三&#xff1a;更新数据示例四&#xff1a;删除数据 MySQL 数据库基础操作详解 MySQL 是一种常用的关系型数据库管理…

【目录整理】(五)

​​​​​Git 基础 Git 详细安装教程文章浏览阅读10w次&#xff0c;点赞9.6k次&#xff0c;收藏1.7w次。Git 是个免费的开源分布式版本控制系统&#xff0c;下载地址为git-scm.com 或者 gitforwindows.org&#xff0c;本文介绍 Git-2.40.0-64-bit.exe 版本的安装方法&#x…

python电商结合双轨制

最近又重新整合翻看以前的数据&#xff0c;图片&#xff0c;绘画&#xff0c;还有各种编程代码&#xff0c;python,leetcode,还有关于商业方面的一些见解,想起了大学时候和同学们并肩作战&#xff0c;熬夜编码的时光。还有大数据&#xff0c;八爪鱼爬虫。 下面是我的手稿电商打…

算法学习——LeetCode力扣动态规划篇9

算法学习——LeetCode力扣动态规划篇9 1035. 不相交的线 1035. 不相交的线 - 力扣&#xff08;LeetCode&#xff09; 描述 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#x…

JavaSE day16笔记 - string

第十六天课堂笔记 学习任务 Comparable接口★★★★ 接口 : 功能的封装 > 一组操作规范 一个抽象方法 -> 某一个功能的封装多个抽象方法 -> 一组操作规范 接口与抽象类的区别 1本质不同 接口是功能的封装 , 具有什么功能 > 对象能干什么抽象类是事物本质的抽象 &…

2536. 子矩阵元素加 1

跳转题目 本题暴力可以做&#xff0c;猜到用差分&#xff0c;但是不熟&#xff0c;不知道二维差分怎么用&#xff0c;碰到用差分的题目太少了。 暴力算法&#xff1a; class Solution { public:vector<vector<int>> rangeAddQueries(int n, vector<vector<…

Docker 部署 FRP 内网穿透 实现端口映射

Frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议&#xff0c;且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 官网地址&#xff1a;https://github.com/fatedier/frp 准备工作…

数据结构算法刷题笔记——题型解法

数据结构算法刷题笔记——题型解法 一、常用容器1.1 vector1.1.1 vector基本操作1.1.1.0 头文件#include<vector>1.1.1.1 构造一个vector容器1.1.1.2 元素访问1.1.1.3 元素个数 .size()1.1.1.4 最大容量 .capacity()1.1.1.5 改变容器有效元素个数 .resize(n)1.1.1.6 改变…

STM32 | PWM脉冲宽度调制(第五天按键中断,控制电机正/反转、加速、减速、暂停与继续源码解析)

​ STM32 | PWM脉冲宽度调制(第五天)STM32 | PWM脉冲宽度调制(第五天呼吸灯源码解析)STM32 | PWM脉冲宽度调制(第五天电机速度控制源码解析)PWM 技术在以下其他机器学习领域和应用中也可以发挥作用: 自然语言处理 (NLP):调节文本生成模型(例如 GPT-3)的输出长度和多样…

NFT-前端开发(一)

使用 在我们想要保存项目的目录下打开终端运行npx create-react-app test2命令初始化&#xff0c;test2是我们的项目名字&#xff0c;可以自己去更改。 初始化完成后&#xff0c;我们目录下就会多出一个test2文件夹 &#xff0c;然后我们在vscode中打开该文件夹 然后我们打开j…

Java8之接口默认方法

Java8之接口默认方法 一、介绍二、代码1、接口2、实现类3、测试代码4、效果 一、介绍 在Java8中&#xff0c;允许为接口方法提供一个默认的实现。必须用default修饰符标记这样一个方法。默认方法也可以调用其他方法 二、代码 1、接口 public interface PersonService {void…

代码随想录算法训练营第二十五天| 回溯算法理论基础、LeetCode77.组合

一、216.组合总和III 题目链接/文章讲解/视频讲解&#xff1a; https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html 状态&#xff1a;已解决 1.思路 做过77题&#xff08;上篇博客&#xff09;后&#xff0c;这道题也就不难了&#xff0c;无非是多…

python--sys模块,time模块

1&#xff1a;sys模块 time.struct_time 实现时间转换 >>> import sys >>> dir(sys) getallocatedblocks, getdefaultencoding, getfilesystemencodeerrors, getfilesystemencoding, getprofile, getrecursionlimit, getrefcount, getsize…

python中pow()函数的使用

在Python中&#xff0c;pow() 函数用于计算指定数字的幂。它的语法如下&#xff1a; pow(x, y) 这个函数返回 x 的 y 次方。相当于 x**y。 pow() 函数也可以接受一个可选的第三个参数&#xff0c;用于指定一个取模值&#xff0c;即计算结果与该模值的余数。其语法如下&#…