
在 HTTP 无状态协议的背景下Cookie 是客户端会话跟踪技术的核心实现与服务器端的 Session 协同共同解决用户状态保持问题。Cookie 是服务器发送给客户端浏览器的 “小数据块”存储在客户端下次请求时自动携带常用于记住用户名、自动登录、跟踪用户偏好等场景。一、Cookie1 概念Cookie 是 HTTP 协议的一部分指服务器在响应客户端请求时通过响应头发送给客户端浏览器的小型文本数据键值对形式。客户端浏览器会将 Cookie 保存起来当再次访问该服务器时会将 Cookie 通过请求头携带回服务器从而实现 “跟踪客户端状态” 的功能。存储位置客户端浏览器内存或硬盘取决于生命周期设置数据格式键值对namevalue支持字符串类型不能直接存储中文需编码限制文档规范单个 Cookie 最大 4KB浏览器最多保存 300 个 Cookie不同浏览器之间不共享 Cookie如 Chrome 的 Cookie 无法被 Firefox 读取2. 作用记住用户身份如登录后下次访问无需重复输入用户名实现自动登录如 “7 天内自动登录” 功能跟踪用户行为如电商网站记录用户浏览过的商品存储用户偏好如网站主题、语言设置3 工作流程客户端首次请求服务器服务器创建 Cookie 对象通过响应头Set-Cookie发送给客户端客户端浏览器接收 Cookie 后按规则保存内存或硬盘客户端再次访问该服务器时将 Cookie 通过请求头Cookie携带回服务器服务器读取 Cookie 中的数据识别客户端身份或状态进行针对性处理二、Cookie API 与基础用法1. 创建 Cookie 并发送到客户端Cookie 的创建和发送是服务器端的响应行为通过HttpServletResponse的addCookie()方法实现。1 APICookie(String name, String value)构造方法创建 Cookie 对象name 为键value 为值response.addCookie(Cookie cookie)将 Cookie 添加到响应中发送给客户端可多次调用添加多个 Cookie2 基础示例CookieDemo1.java包名cn.tx.servlet创建 Cookie 并发送到客户端package cn.tx.servlet; import javax.servlet.ServletException; 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; public class CookieDemo1 extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 创建Cookie对象键名username值txjava Cookie cookie new Cookie(username, txjava); // 2. 可选设置Cookie生命周期默认仅存于浏览器内存 // cookie.setMaxAge(60 * 60); // 1小时秒为单位 // 3. 将Cookie发送到客户端 response.addCookie(cookie); // 响应提示 out.write(h3Cookie已发送到客户端/h3); out.write(可通过浏览器开发者工具查看CookieF12→Application→Cookies); } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }3 配置 web.xml!-- 注册CookieDemo1 -- servlet servlet-nameCookieDemo1/servlet-name servlet-classcn.tx.servlet.CookieDemo1/servlet-class /servlet servlet-mapping servlet-nameCookieDemo1/servlet-name url-pattern/cookie/send/url-pattern /servlet-mapping4 验证效果访问地址http://localhost:8080/javaweb0315/cookie/send打开浏览器 F12→Application→Cookies→http://localhost:8080可看到usernametxjava的 Cookie查看响应头F12→网络→当前请求→响应头存在Set-Cookie: usernametxjava; Path/javaweb0315Path 为 Cookie 的默认路径。2. 服务器端读取客户端携带的 Cookie客户端再次访问服务器时会自动携带 Cookie服务器通过HttpServletRequest的getCookies()方法读取文档要求精通。1 APICookie[] request.getCookies()获取客户端携带的所有 Cookie无 Cookie 时返回null需判空String Cookie.getName()获取 Cookie 的键名String Cookie.getValue()获取 Cookie 的值2 读取示例CookieDemo2.javapackage cn.tx.servlet; import javax.servlet.ServletException; 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; public class CookieDemo2 extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); out.write(h3服务器读取客户端Cookie/h3); // 1. 获取客户端携带的所有Cookie需判空无Cookie时返回null Cookie[] cookies request.getCookies(); if (cookies ! null cookies.length 0) { // 2. 遍历Cookie数组获取键名和值 for (Cookie cookie : cookies) { String name cookie.getName(); String value cookie.getValue(); out.write(Cookie名 name → 值 value br/); System.out.println(Cookie名 name → 值 value); // 控制台同步打印 } } else { out.write(客户端未携带任何Cookie); } } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }3 配置 web.xml!-- 注册CookieDemo2 -- servlet servlet-nameCookieDemo2/servlet-name servlet-classcn.tx.servlet.CookieDemo2/servlet-class /servlet servlet-mapping servlet-nameCookieDemo2/servlet-name url-pattern/cookie/read/url-pattern /servlet-mapping4 验证效果先访问/cookie/send发送 Cookie再访问/cookie/read读取 Cookie页面和控制台均会显示Cookie名username → 值txjava证明读取成功3. Cookie 生命周期文档重点要求熟练Cookie 的生命周期指 Cookie 在客户端的存活时间默认情况下Cookie 仅存于浏览器内存中关闭浏览器后即失效。可通过setMaxAge(int expiry)方法自定义生命周期单位秒。1 生命周期的 3 种设置设置方式代码示例效果存储位置会话级默认cookie.setMaxAge(-1)负数均可关闭浏览器后 Cookie 失效浏览器内存持久化自定义时长cookie.setMaxAge(60 * 60 * 24)Cookie 存活 24 小时即使关闭浏览器、重启电脑也有效客户端硬盘立即失效删除 Cookiecookie.setMaxAge(0)立即删除客户端已存在的同名 Cookie无内存 硬盘均删除2 生命周期示例CookieDemo3.javapackage cn.tx.servlet; import javax.servlet.ServletException; 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; public class CookieDemo3 extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 创建Cookie键名需与要操作的Cookie一致 Cookie cookie new Cookie(username, txjava); // 2. 设置生命周期三选一测试 // 方式1会话级默认关闭浏览器失效 // cookie.setMaxAge(-1); // 方式2持久化1小时60秒*603600秒 cookie.setMaxAge(3600); // 方式3立即删除Cookie需确保键名和路径与原Cookie一致 // cookie.setMaxAge(0); // cookie.setPath(/javaweb0315); // 路径需与原Cookie一致 // 3. 发送Cookie持久化/删除均需重新发送 response.addCookie(cookie); out.write(h3Cookie生命周期设置成功/h3); out.write(1小时内关闭浏览器再次访问/cookie/read仍能读取到该Cookie); } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }3 配置 web.xml!-- 注册CookieDemo3 -- servlet servlet-nameCookieDemo3/servlet-name servlet-classcn.tx.servlet.CookieDemo3/servlet-class /servlet servlet-mapping servlet-nameCookieDemo3/servlet-name url-pattern/cookie/lifecycle/url-pattern /servlet-mapping4 验证效果访问/cookie/lifecycle设置 Cookie 生命周期为 1 小时关闭浏览器重新打开访问/cookie/read仍能读取到usernametxjava的 Cookie1 小时后再次访问Cookie 失效无法读取或调用方式 3 立即删除访问后无法读取4. Cookie 的路径Cookie 的path属性用于控制 “客户端在哪些请求路径下会携带该 Cookie”并非指 Cookie 在客户端的存储路径。1 路径的默认规则若不手动设置pathCookie 的默认路径为 “当前请求路径的上一级”例如请求路径为/javaweb0315/cookie/send默认路径为/javaweb0315例如请求路径为/javaweb0315/cookie/path/son默认路径为/javaweb0315/cookie/path2 路径的作用客户端请求的路径包含Cookie 的path时才会携带该 Cookie示例 1Cookie 路径为/javaweb0315请求/javaweb0315/xxx如/javaweb0315/user会携带 Cookie示例 2Cookie 路径为/javaweb0315/cookie请求/javaweb0315/cookie/read会携带请求/javaweb0315/user不会携带3 手动设置路径APIcookie.setPath(String path)设置 Cookie 的路径推荐设置为项目根路径/项目名确保整个项目都能访问该 Cookie。4 路径示例CookieDemo4.javapackage cn.tx.servlet; import javax.servlet.ServletException; 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; public class CookieDemo4 extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 创建Cookie Cookie cookie new Cookie(pathCookie, pathValue); // 2. 手动设置路径为项目根路径确保整个项目都能访问该Cookie String contextPath request.getContextPath(); // /javaweb0315 cookie.setPath(contextPath); // 3. 持久化1小时 cookie.setMaxAge(3600); // 4. 发送Cookie response.addCookie(cookie); out.write(h3设置路径为 contextPath 的Cookie成功/h3); out.write(访问项目内任意路径如/user、/cookie/read均可携带该Cookie); } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }5 配置 web.xml!-- 注册CookieDemo4 -- servlet servlet-nameCookieDemo4/servlet-name servlet-classcn.tx.servlet.CookieDemo4/servlet-class /servlet servlet-mapping servlet-nameCookieDemo4/servlet-name url-pattern/cookie/path/url-pattern /servlet-mapping5. Cookie 保存中文Cookie 的name和value不能直接存储中文会抛出异常需通过URLEncoder编码获取时通过URLDecoder解码。1 编码与解码示例CookieDemo5.javapackage cn.tx.servlet; import javax.servlet.ServletException; 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.net.URLDecoder; import java.net.URLEncoder; public class CookieDemo5 extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 存储中文URLEncoder编码 String chineseName 张三; String encodedName URLEncoder.encode(chineseName, UTF-8); // 编码为%E5%BC%A0%E4%B8%89 Cookie cookie new Cookie(chineseUser, encodedName); cookie.setPath(request.getContextPath()); cookie.setMaxAge(3600); response.addCookie(cookie); // 2. 读取中文URLDecoder解码 out.write(h3中文Cookie已存储解码后/h3); Cookie[] cookies request.getCookies(); if (cookies ! null) { for (Cookie c : cookies) { if (chineseUser.equals(c.getName())) { String decodedValue URLDecoder.decode(c.getValue(), UTF-8); // 解码为张三 out.write(中文用户名 decodedValue br/); } } } } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }2 配置 web.xml!-- 注册CookieDemo5 -- servlet servlet-nameCookieDemo5/servlet-name servlet-classcn.tx.servlet.CookieDemo5/servlet-class /servlet servlet-mapping servlet-nameCookieDemo5/servlet-name url-pattern/cookie/chinese/url-pattern /servlet-mapping三、Cookie 实战实现自动登录利用 Cookie 的持久化特性实现 “一天内自动登录” 功能用户登录时勾选自动登录服务器将用户名密码加密后存入 Cookie下次访问时自动验证登录。1. 实现思路登录页面提供 “自动登录” 复选框登录成功且勾选自动登录时将用户名密码加密后存入 Cookie持久化 24 小时用户下次访问时服务器读取 Cookie解密后验证身份验证通过则自动登录2. 编写登录页面auto_login.jsp% page contentTypetext/html;charsetUTF-8 languagejava % html head title自动登录测试/title /head body h3用户登录支持自动登录/h3 form action${pageContext.request.contextPath}/autoLogin methodpost 用户名input typetext nameusername requiredbrbr 密码input typepassword namepassword requiredbrbr input typecheckbox nameautoLogin value1 一天内自动登录brbr input typesubmit value登录 /form /body /html3. 编写自动登录 ServletAutoLoginServlet.java使用 BASE64 加密用户名密码文档示例避免明文存储package cn.tx.servlet; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.servlet.ServletException; 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; public class AutoLoginServlet extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决中文乱码 request.setCharacterEncoding(UTF-8); response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 获取表单参数或Cookie中的登录信息 String username request.getParameter(username); String password request.getParameter(password); String autoLogin request.getParameter(autoLogin); // 2. 无表单参数时尝试从Cookie读取自动登录信息 if (username null password null) { String cookieValue null; Cookie[] cookies request.getCookies(); if (cookies ! null) { for (Cookie cookie : cookies) { if (autoLoginCookie.equals(cookie.getName())) { cookieValue cookie.getValue(); break; } } } // 无Cookie信息未登录跳转到登录页 if (cookieValue null) { out.write(h3您尚未登录请先登录/h3); out.write(a href request.getContextPath() /auto_login.jsp前往登录/a); return; } // 有Cookie信息解码并验证 BASE64Decoder decoder new BASE64Decoder(); String decodedValue new String(decoder.decodeBuffer(cookieValue), UTF-8); String[] info decodedValue.split(:); // 格式前缀:用户名:密码:有效期 username info[1]; password info[2]; } // 3. 模拟登录验证实际项目查询数据库 if (admin.equals(username) 123456.equals(password)) { // 登录成功判断是否勾选自动登录 if (1.equals(autoLogin)) { // 加密用户名密码BASE64编码 String value txjava: username : password : (24 * 3600); BASE64Encoder encoder new BASE64Encoder(); String encodedValue encoder.encode(value.getBytes(UTF-8)); // 创建Cookie持久化24小时 Cookie cookie new Cookie(autoLoginCookie, encodedValue); cookie.setPath(request.getContextPath()); cookie.setMaxAge(24 * 3600); // 1天有效期 response.addCookie(cookie); } // 响应登录成功 out.write(h3登录成功欢迎您 username /h3); out.write(a href request.getContextPath() /logoutAutoLogin退出登录/a); } else { // 登录失败 out.write(h3用户名或密码错误/h3); out.write(a href request.getContextPath() /auto_login.jsp返回登录/a); } } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }4. 编写退出登录 ServletLogoutAutoLoginServlet.java退出登录时删除自动登录 Cookiepackage cn.tx.servlet; import javax.servlet.ServletException; 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; public class LogoutAutoLoginServlet extends HttpServlet { Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetUTF-8); PrintWriter out response.getWriter(); // 1. 创建同名Cookie设置maxAge0删除 Cookie cookie new Cookie(autoLoginCookie, ); cookie.setPath(request.getContextPath()); cookie.setMaxAge(0); // 立即删除 response.addCookie(cookie); // 2. 响应退出结果 out.write(h3退出登录成功自动登录已取消/h3); out.write(a href request.getContextPath() /auto_login.jsp重新登录/a); } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }5. 配置 web.xml!-- 注册自动登录Servlet -- servlet servlet-nameAutoLoginServlet/servlet-name servlet-classcn.tx.servlet.AutoLoginServlet/servlet-class /servlet servlet-mapping servlet-nameAutoLoginServlet/servlet-name url-pattern/autoLogin/url-pattern /servlet-mapping !-- 注册退出登录Servlet -- servlet servlet-nameLogoutAutoLoginServlet/servlet-name servlet-classcn.tx.servlet.LogoutAutoLoginServlet/servlet-class /servlet servlet-mapping servlet-nameLogoutAutoLoginServlet/servlet-name url-pattern/logoutAutoLogin/url-pattern /servlet-mapping6. 运行验证访问登录页http://localhost:8080/javaweb0315/auto_login.jsp输入用户名admin、密码123456勾选 “自动登录”点击登录关闭浏览器重新打开直接访问http://localhost:8080/javaweb0315/autoLogin无需输入账号密码自动登录成功点击 “退出登录”再次访问/autoLogin提示 “尚未登录”Cookie 已删除四、要点总结API创建new Cookie(name, value)、发送response.addCookie()、读取request.getCookies()、生命周期setMaxAge()、路径setPath()中文处理需通过URLEncoder编码、URLDecoder解码不能直接存储中文生命周期默认会话级内存setMaxAge(正数)持久化硬盘setMaxAge(0)删除路径作用控制客户端在哪些请求路径下携带 Cookie推荐设置为项目根路径场景示例自动登录、记住用户名、跟踪用户偏好1Cookie 的工作原理是什么服务器创建 Cookie 对象通过响应头Set-Cookie发送给客户端客户端浏览器保存 Cookie内存或硬盘客户端再次访问服务器时通过请求头Cookie携带 Cookie 回服务器服务器读取 Cookie 数据识别客户端状态实现会话跟踪2Cookie 的生命周期如何控制默认setMaxAge(-1)仅存于浏览器内存关闭浏览器失效持久化setMaxAge(秒数)存于硬盘到期或手动删除前有效删除setMaxAge(0)立即删除客户端同名 Cookie需保证路径一致3Cookie 和 Session 的区别是什么对比维度CookieSession存储位置客户端浏览器内存 / 硬盘服务器端内存 / 文件 / 数据库数据安全性低明文存储可篡改高数据不暴露给客户端数据大小限制单个 4KB最多 300 个无明确限制受服务器资源影响生命周期可设置会话级 / 持久化会话级超时 / 注销失效依赖关系独立存在无需依赖其他组件依赖 Cookie 传递 SessionIDCookie 禁用则失效场景自动登录、记住用户名登录状态保持、跨请求数据共享4Cookie 如何保存中文Cookie 不能直接存储中文需通过URLEncoder.encode(String value, UTF-8)编码后存储读取时通过URLDecoder.decode(String value, UTF-8)解码。5Cookie 禁用后Session 还能使用吗默认不能因为 Session 依赖 Cookie 传递 SessionID。可通过URL 重写规避在 URL 后拼接;jsessionidSessionID但存在安全风险SessionID 暴露不推荐使用。五、所有地址汇总发送 Cookiehttp://localhost:8080/javaweb0315/cookie/send读取 Cookiehttp://localhost:8080/javaweb0315/cookie/read生命周期测试http://localhost:8080/javaweb0315/cookie/lifecycle路径测试http://localhost:8080/javaweb0315/cookie/path中文 Cookie 测试http://localhost:8080/javaweb0315/cookie/chinese自动登录页面http://localhost:8080/javaweb0315/auto_login.jsp自动登录接口http://localhost:8080/javaweb0315/autoLogin退出自动登录http://localhost:8080/javaweb0315/logoutAutoLogin结尾Cookie 是 JavaWeb 客户端会话跟踪的技术虽然数据存储在客户端存在安全风险如 Cookie 劫持、篡改但通过加密如 BASE64、MD5和合理的生命周期设置可在一定程度上规避风险。如果觉得本文对你有帮助欢迎点赞 收藏 关注~