当前位置:网站首页>【Web】Cookie 和 Session
【Web】Cookie 和 Session
2022-06-13 03:35:00 【敲代码的布莱恩特】
博客主页:敲代码的布莱恩特
欢迎点赞收藏留言欢迎讨论!
本文由 【敲代码的布莱恩特】 原创,首发于 CSDN
由于博主是在学小白一枚,难免会有错误,有任何问题欢迎评论区留言指出,感激不尽!
精品专栏(不定时更新)【JavaSE】 【Java数据结构】【LeetCode】
【Web】Cookie 和 Session
回顾 Cookie
HTTP 协议自身是属于 “无状态” 协议.
“无状态” 的含义指的是:
默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.
但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了.

通过set-cookie返回给浏览器储存在Cookie字段中的东西就好比服务器给客户端的一个令牌用于身份确认和标识
此时在服务器这边就需要记录令牌信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.
理解会话机制 (Session)
服务器同一时刻收到的请求是很多的. 服务器需要清除的区分清楚每个请求是从属于哪个用户, 就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系.
就像去医院看病,就诊卡就是一张 “令牌”. 要想让这个令牌能够生效, 就需要医院这边通过系统记录每个就诊卡和患者信息之间的关联关系.
会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).
sessionId是由服务器生成的一个 “唯一性字符串”, 从 session 机制的角度来看, 这个唯一性字符串称为 “sessionId”. 但是站在整个登录流程中看待, 也可以把这个唯一性字符串称为 “token”. sessionId 和 token 就可以理解成是同一个东西的不同叫法(不同视角的叫法)

Servlet 的 Session 默认是保存在内存中的.
如果重启服务器则 Session 数据就会丢失.
Cookie 和 Session 的区别
- Cookie 是
客户端的机制. Session 是服务器端的机制. - Cookie 和 Session 经常会在一起配合使用. 但是不是必须配合.
- 完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是
token / sessionId - Session 中的 token / sessionId 也不需要非得通过 Cookie / Set-Cookie 传递.
核心方法
HttpServletRequest 类中的相关方法
| 方法 | 描述 |
|---|---|
| HttpSession getSession() | 在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null |
| Cookie[ ] getCookies() | 返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把Cookie 中的格式解析成键值对. |
HttpServletResponse 类中的相关方法
| 方法 | 描述 |
|---|---|
| void addCookie(Cookie cookie) | 把指定的 cookie 添加到响应中. |
HttpSession 类中的相关方法
一个 HttpSession 对象里面
包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息.
| 方法 | 描述 |
|---|---|
| Object getAttribute(Stringname) | 该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null. |
| void setAttribute(Stringname, Object value) | 该方法使用指定的名称绑定一个对象到该 session 会话boolean isNew() 判定当前是否是新创建出的会话 |
Cookie 类中的相关方法
每个 Cookie 对象就是一个键值对.
| 方法 | 描述 |
|---|---|
| String getName() | 该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 SetCooke 字段设置给浏览器的) |
| String getValue() | 该方法获取与 cookie 关联的值 |
| void setValue(StringnewValue) | 该方法设置与 cookie 关联的值。 |
- HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了一个Cookie 对象.
- 通过 HttpServletRequest.getCookies() 获取到请求中的一系列 Cookie 键值对.
- 通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.
代码示例: 实现用户登陆
实现简单的用户登陆逻辑
这个代码中主要是通过 HttpSession 类完成. 并不需要我们手动操作 Cookie 对象.
1.实现一个登陆页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登陆</title>
</head>
<body>
<form action="login" method="POST">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
2.实现一个Servlet用于处理登陆请求
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 doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
// 1. 获取到用户提交的用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
// 2. 判定用户名密码是否正确
if (!username.equals("kobe") || !password.equals("824")) {
// 登陆失败
resp.getWriter().write("登陆失败");
return;
}
// 登陆成功
System.out.println("登陆成功");
// 设置 Session
HttpSession session = req.getSession(true);
session.setAttribute("username", "Kobe Bryant");
session.setAttribute("loginCount", "");
resp.sendRedirect("index");
}
}


3.再实现一个IndexServlet来表示重定向之后的主页
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 {
resp.setContentType("text/html; charset=utf-8");
// 1. 判定当前用户是否已经登陆
HttpSession session = req.getSession(false);
if (session == null) {
// 用户没有登陆, 重定向到 login.html
resp.sendRedirect("login.html");
return;
}
// 2. 如果已经登陆, 则从 Session 中取出访问次数数据
String userName = (String)session.getAttribute("username");
String countString = (String)session.getAttribute("loginCount");
int loginCount = Integer.parseInt(countString);
loginCount += 1;
session.setAttribute("loginCount", loginCount + "");
// 3. 展示到页面上.
StringBuilder html = new StringBuilder();
html.append(String.format("<div>用户名: %s</div>", userName));
html.append(String.format("<div>loginCount: %d</div>", loginCount));
resp.getWriter().write(html.toString());
}
}

实现效果


边栏推荐
- China Civil Aviation Statistical Yearbook (1996-2020)
- Coal industry database - coal price, consumption, power generation & Provincial Civil and industrial power consumption data
- Doris data import broker load
- MySQL 8.0 enables remote root user access and solves the problem of you are not allowed to create a user with Grant
- Neo4j auradb free, the world's leading map database
- Explain usage, field explanations, and optimization instances of MySQL
- Summary of virtualization technology development
- Isolation level, unreal read, gap lock, next key lock
- MySQL learning summary 10: detailed explanation of view use
- UDP connection map collection
猜你喜欢

MySQL 8.0 enables remote root user access and solves the problem of you are not allowed to create a user with Grant

Neil eifrem, CEO of neo4j, interprets the chart data platform and leads the development of database in the next decade

Figure data * reconstruction subgraph

基于华为云物联网设计的浇花神器(STM32+ESP8266)
![[figure data] how long does it take for the equity network to penetrate 1000 layers?](/img/ff/dc5160300db77ce7e47069e7eec065.jpg)
[figure data] how long does it take for the equity network to penetrate 1000 layers?
![[azure data platform] ETL tool (2) -- azure data factory](/img/31/3561a3c3f24bce098330218a1d9ded.jpg)
[azure data platform] ETL tool (2) -- azure data factory "copy data" tool (cloud copy)

Patrick Pichette, partner of inovia, former chief financial officer of Google and current chairman of twitter, joined the board of directors of neo4j

DTCC | 2021 China map database technology conference link sharing

【测试开发】博客系统——Loadrunner性能测试(发布博客功能 基准测试)

Druid query
随机推荐
Local simulation download file
MASA Auth - SSO与Identity设计
Understand the difference between reducebykey and groupbykey in spark
Pollution discharge fees of listed companies 2010-2020 & environmental disclosure level of heavy pollution industry - original data and calculation results
MySQL learning summary 12: system variables, user variables, definition conditions and handlers
Solve the error in CONDA installation PyMOL
Three ways of scala string interpolation
Summary of the latest rail transit (Subway + bus) stops and routes in key cities in China (II)
Understanding the ongdb open source map data foundation from the development of MariaDB
Neil eifrem, CEO of neo4j, interprets the chart data platform and leads the development of database in the next decade
(9) Explain broadcasting mechanism in detail
LVS four - tier Load Balancing Cluster (5) LVS Overview
Union, intersection and difference sets of different MySQL databases
Golang picks up: why do we need generics
Masa auth - SSO and identity design
LeetCode 178. Score ranking (MySQL)
LVS四层负载均衡集群(4)负载均衡的主要方式
Environmental pollution, enterprises, highways, fixed assets, foreign investment in all prefecture level cities in China - latest panel data
Complex network analysis capability based on graph database
[azure data platform] ETL tool (7) - detailed explanation of ADF copy data
