解析源码
Cookie:
java
public class Cookie implements Cloneable, Serializable{
}
创建一个新的Cookie,可以看出value只能能是String
java
public Cookie(String name, String value) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException(lStrings.getString("err.cookie_name_blank"));
}
if (!isToken(name) || name.equalsIgnoreCase("Comment") || // rfc2019
name.equalsIgnoreCase("Discard") || // 2019++
name.equalsIgnoreCase("Domain") || name.equalsIgnoreCase("Expires") || // (old cookies)
name.equalsIgnoreCase("Max-Age") || // rfc2019
name.equalsIgnoreCase("Path") || name.equalsIgnoreCase("Secure") || name.equalsIgnoreCase("Version")
|| name.startsWith("$")) {
String errMsg = lStrings.getString("err.cookie_name_is_token");
Object[] errArgs = new Object[1];
errArgs[0] = name;
errMsg = MessageFormat.format(errMsg, errArgs);
throw new IllegalArgumentException(errMsg);
}
this.name = name;
this.value = value;
}
我们可以在里面写很多东西
java
private String name; // NAME= ... "$Name" style is reserved
private String value; // value of NAME
//
// Attributes encoded in the header's cookie fields.
//
/注释信息,描述 Cookie 用途<br>⚠️ Netscape v0 不支持
private String comment;
//指定哪些域名可以访问此 Cookie<br>必须以 . 开头(如 .example.com)
private String domain; // ;Domain=VALUE ... domain that sees cookie
// 正数(如 3600)Cookie 将在指定秒数后过期(例如 3600 秒 = 1 小时)
//负数(如 -1,默认值)Cookie 是会话级的,浏览器关闭时自动删除
//零(0)立即删除该 Cookie(常用于退出登录时清除 Cookie)
private int maxAge = -1;
//指定哪些 URL 路径可以访问该 Cookie
private String path;
//是否只在 HTTPS 下传输 Cookie
private boolean secure;
//Cookie 协议版本:<br>- 0:Netscape 原始规范<br>- 1:RFC 2109 规范
private int version = 0;
//是否禁止 JavaScript 访问 Cookie(防 XSS)
private boolean isHttpOnly = false;
日常开发中最需要掌握的方法
方法 | 用途 |
---|---|
new Cookie(name, value) | 创建 Cookie |
setMaxAge() / getMaxAge() | 控制生命周期 |
setPath() / getPath() | 控制访问路径 |
setDomain() / getDomain() | 控制域名范围 |
setSecure() / getSecure() | 控制协议安全性 |
setHttpOnly() / isHttpOnly() | 控制前端脚本访问权限 |
setValue() / getValue() | 设置/读取值 |
Session
Session通过req的getSession()方法获得
java
HttpSession session = request.getSession();
java
public interface HttpSession {
}
Session最重要的方法:setAttribute。value能放Object,
java
public void setAttribute(String name, Object value);
基本方法 | 说明 | 使用频率 |
---|---|---|
getId() | 获取会话的唯一标识符(Session ID) | ⭐⭐⭐⭐⭐ |
getCreationTime() | 获取会话创建时间(毫秒时间戳) | ⭐⭐⭐☆☆ |
getLastAccessedTime() | 获取最后一次访问时间(毫秒时间戳) | ⭐⭐⭐☆☆ |
isNew() | 判断是否是新创建的会话 | ⭐⭐⭐☆☆ |
invalidate() | 销毁当前会话(如用户登出) | ⭐⭐⭐⭐☆ |
setAttribute(String name, Object value) | 绑定一个对象到会话中(类似 Map) | ⭐⭐⭐⭐⭐ |
getAttribute(String name) | 获取绑定的对象 | ⭐⭐⭐⭐⭐ |
removeAttribute(String name) | 移除指定名称的对象 | ⭐⭐⭐☆☆ |
getAttributeNames() | 获取所有绑定对象的名称 | ⭐⭐☆☆☆ |
setMaxInactiveInterval(int interval) | 设置最大非活动时间(秒) | ⭐⭐⭐⭐☆ |
代码示范:
java
// 获取或创建 Session
HttpSession session = request.getSession();
// 存储用户信息
session.setAttribute("username", "admin");
session.setAttribute("role", "administrator");
// 设置会话超时时间为30分钟
session.setMaxInactiveInterval(30 * 60); // 单位:秒
// 获取用户信息
String username = (String) session.getAttribute("username");
// 检查是否是新会话
if (session.isNew()) {
System.out.println("这是一个新的会话");
}
// 用户登出时销毁会话
session.invalidate();
Cookie与Session的区别
-
Cookie是把用户的数据写给浏览器,浏览器保存,同一终端并且使用同一个浏览器用户配置文件,打开浏览器看到的Cookie值都相同。缺点是只能传入字符串。
-
Session是把用户的数据写到用户单独的Session里,每个浏览器打开的Session不相同,即使同一台电脑用同一个浏览器打开两个独立的窗口(非标签页),通常也会创建两个Session。Session可以传Object
-
非常重要的一点是:Session的实现依赖于Cookie(在绝大多数情况下)。
- 当服务器创建一个Session时,它必须有一种方法将Session ID(这个Session的唯一标识符)返回给浏览器,以便浏览器在下次请求时能告诉服务器"我是谁"。
- 最常用、最方便的方法就是使用一个特殊的Cookie,通常名为
JSESSIONID
(Java)、PHPSESSID
(PHP)等,它的值就是这个ID。 - 所以,可以理解为:Session是一种服务器端的用户状态管理机制,而Cookie是维持这种机制的"通行证"或"钥匙" 。
使用Cookie与Session
Cookie 主要用于与服务器交互的、小型的标识性数据;而 Session 用于存储在服务器端的、临时的、敏感或量大的用户状态数据。
下面这个表格清晰地展示了两者的典型分工。
存储项 | 通常存于 Cookie 🍪 | 通常存于 Session 💻 |
---|---|---|
核心用途 | 用户身份标识、偏好记录 | 用户会话状态、敏感数据暂存 |
具体例子 | 会话ID(Session ID)、登录状态令牌(Token)、语言或主题偏好 | 用户登录凭证(如用户名/用户ID)、购物车商品列表、多步骤表单的临时数据、敏感信息(如手机号) |
安全备注 | 不应直接存储密码等敏感信息。关键标识(如Token)需设置 HttpOnly 、Secure 等安全属性。 |
数据在服务器端,相对更安全 |