Session 会话与 Cookie 响应
Session 是服务器端的会话对象,用于存储用户的 “会话级” 数据(如登录状态、购物车信息)。每个用户(会话)对应一个唯一的 Session,服务器通过 **Cookie(JSESSIONID)** 识别不同用户的 Session。特性CookieSession存储位置客户端浏览器服务器内存(或持久化存储)存储容量小(一般 4KB 以内)大(取决于服务器资源)安全性低(数据在客户端,易被篡改)
一、Cookie
1. Cookie 的概述
Cookie 是服务器发送给客户端(浏览器)的一小段文本数据,客户端会将其保存起来,之后每次向该服务器发送请求时,都会携带该 Cookie。它的核心作用是在客户端存储少量状态数据(如用户偏好、登录状态标识)。
典型应用场景:
- 记录用户上次访问时间。
- 实现 “记住密码”“自动登录” 功能。
- 跟踪用户行为(如电商网站的购物车)。
2. Cookie 的相关方法
在 Java Web 中,通过javax.servlet.http.Cookie类操作 Cookie,核心方法如下:
| 方法 | 说明 |
|---|---|
Cookie(String name, String value) |
构造方法,创建 Cookie 对象(name 不能含空格、特殊字符) |
void setMaxAge(int expiry) |
设置 Cookie 的有效时间(单位:秒) |
int getMaxAge() |
获取 Cookie 的有效时间 |
void setPath(String uri) |
设置 Cookie 的有效路径 |
String getPath() |
获取 Cookie 的有效路径 |
void setValue(String newValue) |
设置 Cookie 的值 |
String getValue() |
获取 Cookie 的值 |
void setDomain(String pattern) |
设置 Cookie 的有效域名(极少使用) |
3. Cookie 的案例(记录上一次的访问时间)
需求:用户访问页面时,显示 “您上次访问的时间是:xxx”,并更新本次访问时间到 Cookie 中。
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/lastAccessTime")
public class LastAccessTimeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
// 1. 获取所有Cookie,查找记录上次访问时间的Cookie
Cookie[] cookies = req.getCookies();
String lastTime = "您是第一次访问";
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("lastAccessTime".equals(cookie.getName())) {
lastTime = "您上次访问的时间是:" + cookie.getValue();
// 更新Cookie的值为本次访问时间
cookie.setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
cookie.setMaxAge(24 * 60 * 60); // 有效时间1天
resp.addCookie(cookie);
break;
}
}
}
// 2. 如果是第一次访问,创建Cookie并设置
if (cookies == null || lastTime.equals("您是第一次访问")) {
Cookie cookie = new Cookie("lastAccessTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
cookie.setMaxAge(24 * 60 * 60);
resp.addCookie(cookie);
}
out.write(lastTime);
}
}
4. Cookie 的有效时间和有效路径
-
有效时间:通过
setMaxAge(int expiry)设置,单位为秒。expiry > 0:Cookie 在客户端硬盘中保存,过期时间到后自动删除。expiry = 0:立即删除客户端的 Cookie。expiry < 0:Cookie 仅保存在浏览器内存中,关闭浏览器即删除(默认值)。
-
有效路径:通过
setPath(String uri)设置,只有请求路径匹配该路径的请求才会携带该 Cookie。示例:cookie.setPath("/user");表示只有访问/user开头的路径(如/user/login、/user/info)时,才会携带该 Cookie。
5. Cookie 的编码问题
由于 Cookie 的name和value不支持中文,若需存储中文,需先编码(如URLEncoder.encode),获取时再解码(如URLDecoder.decode)。
示例:
// 存储中文Cookie
String chineseValue = "中文内容";
String encodedValue = URLEncoder.encode(chineseValue, "UTF-8");
Cookie cookie = new Cookie("chineseCookie", encodedValue);
resp.addCookie(cookie);
// 获取并解码中文Cookie
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie c : cookies) {
if ("chineseCookie".equals(c.getName())) {
String decodedValue = URLDecoder.decode(c.getValue(), "UTF-8");
System.out.println("解码后的值:" + decodedValue);
}
}
}
二、Session
1. Session 的概述
Session 是服务器端的会话对象,用于存储用户的 “会话级” 数据(如登录状态、购物车信息)。每个用户(会话)对应一个唯一的 Session,服务器通过 **Cookie(JSESSIONID)** 识别不同用户的 Session。
Session 与 Cookie 的区别:
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端浏览器 | 服务器内存(或持久化存储) |
| 存储容量 | 小(一般 4KB 以内) | 大(取决于服务器资源) |
| 安全性 | 低(数据在客户端,易被篡改) | 高(数据在服务器,客户端仅存 ID) |
| 生命周期 | 可设置较长时间 | 默认 30 分钟(无操作则过期) |
2. Session 的代码实现
示例:用 Session 存储用户登录状态。
// 登录Servlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
// 假设此处是登录校验逻辑(略)
if ("admin".equals(username) && "123456".equals(password)) {
// 登录成功,将用户信息存入Session
HttpSession session = req.getSession();
session.setAttribute("user", username);
resp.sendRedirect(req.getContextPath() + "/home");
} else {
resp.sendRedirect(req.getContextPath() + "/login.jsp");
}
}
}
// 首页Servlet
@WebServlet("/home")
public class HomeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
HttpSession session = req.getSession();
String user = (String) session.getAttribute("user");
if (user != null) {
out.write("欢迎回来," + user + "!");
} else {
out.write("请先登录!");
resp.sendRedirect(req.getContextPath() + "/login.jsp");
}
}
}
3. Session 的销毁和相关 API
-
Session 的销毁方式:
- 服务器正常关闭(会序列化 Session 到磁盘,重启后恢复)。
- Session 超时(默认 30 分钟无操作,可在
web.xml中配置<session-config><session-timeout>15</session-timeout></session-config>修改超时时间)。 - 手动调用
session.invalidate()方法。
-
Session 相关 API:
HttpSession session = req.getSession(); // 获取Session,不存在则创建 HttpSession session = req.getSession(false); // 获取Session,不存在则返回null session.setAttribute("key", "value"); // 存储属性 Object value = session.getAttribute("key"); // 获取属性 session.removeAttribute("key"); // 删除属性 session.invalidate(); // 销毁Session String id = session.getId(); // 获取Session的唯一标识(JSESSIONID)
4. 综合案例(Session 和 Cookie 实现自动登录功能)
需求:用户登录时勾选 “自动登录”,则下次访问时无需手动登录,直接进入首页。
(1)登录 Servlet(处理自动登录逻辑)
@WebServlet("/autoLogin")
public class AutoLoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String autoLogin = req.getParameter("autoLogin");
// 登录校验(略)
if ("admin".equals(username) && "123456".equals(password)) {
HttpSession session = req.getSession();
session.setAttribute("user", username);
// 如果勾选了自动登录,创建持久化Cookie
if ("on".equals(autoLogin)) {
Cookie cookie = new Cookie("autoLogin", username + "|" + password);
cookie.setMaxAge(7 * 24 * 60 * 60); // 有效时间7天
cookie.setPath("/"); // 所有路径都携带该Cookie
resp.addCookie(cookie);
}
resp.sendRedirect(req.getContextPath() + "/home");
} else {
resp.sendRedirect(req.getContextPath() + "/login.jsp");
}
}
}
(2)过滤器(拦截请求,自动登录校验)
@WebFilter("/*")
public class AutoLoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession();
// 如果Session中已有用户,直接放行
if (session.getAttribute("user") != null) {
chain.doFilter(request, response);
return;
}
// 否则,检查Cookie中是否有自动登录信息
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("autoLogin".equals(cookie.getName())) {
String[] info = cookie.getValue().split("\\|");
String username = info[0];
String password = info[1];
// 模拟登录校验(实际应查数据库)
if ("admin".equals(username) && "123456".equals(password)) {
session.setAttribute("user", username);
break;
}
}
}
}
chain.doFilter(request, response);
}
}
(3)登录页面(login.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>自动登录演示</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/autoLogin" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
自动登录:<input type="checkbox" name="autoLogin" value="on"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)