- 在 Servlet 环境中(最常见,如 Java Web 应用)
- 在非 Servlet 环境中(使用
java.net.HttpURLConnection发送 HTTP 请求)
在 Servlet 环境中获取 Cookie
这是最经典和常见的情况,当你的 Java Web 应用(运行在 Tomcat, Jetty 等服务器上)接收到一个 HTTP 请求时,你可以从 HttpServletRequest 对象中获取客户端发送过来的所有 Cookie。
核心步骤
- 获取
Cookie数组:通过request.getCookies()方法,可以获取一个Cookie对象的数组。注意:如果请求中没有携带任何 Cookie,这个方法会返回null,所以必须进行空值检查。 - 遍历数组:遍历这个
Cookie数组。 - 比较 Cookie 名称:在遍历过程中,使用
cookie.getName()方法获取每个 Cookie 的名称,并与你想要查找的 Cookie 名称进行比较。 - 获取 Cookie 值:当找到名称匹配的 Cookie 后,使用
cookie.getValue()方法获取其对应的值。
代码示例
这是一个完整的 Servlet 示例,展示了如何获取并打印出所有的 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;
@WebServlet("/GetCookieServlet") // 使用注解映射 Servlet
public class GetCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 从请求中获取所有 Cookie
Cookie[] cookies = request.getCookies();
// 2. 检查 Cookie 数组是否为空
if (cookies != null) {
// 3. 遍历 Cookie 数组
for (Cookie cookie : cookies) {
// 4. 获取 Cookie 的名称和值
String name = cookie.getName();
String value = cookie.getValue();
// 打印到控制台
System.out.println("Cookie Name: " + name);
System.out.println("Cookie Value: " + value);
System.out.println("------------------------");
// 你也可以将结果输出到网页上
response.getWriter().println("Found Cookie: " + name + " = " + value + "<br>");
}
} else {
System.out.println("No cookies found in this request.");
response.getWriter().println("No cookies found in this request.");
}
}
}
如何测试?
-
设置 Cookie:你需要先有一个 Servlet 或 JSP 页面来设置 Cookie,创建一个
SetCookieServlet。// SetCookieServlet.java @WebServlet("/SetCookieServlet") public class SetCookieServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 创建一个 Cookie 对象 Cookie userCookie = new Cookie("username", "john_doe"); Cookie themeCookie = new Cookie("theme", "dark"); // 设置 Cookie 的有效期(单位:秒),-1 表示会话 Cookie(浏览器关闭后删除) // 7天后过期 userCookie.setMaxAge(7 * 24 * 60 * 60); themeCookie.setMaxAge(7 * 24 * 60 * 60); // 设置 Cookie 的路径,`/` 表示在整个应用下都可见 userCookie.setPath("/"); themeCookie.setPath("/"); // 将 Cookie 添加到响应中,发送给客户端 response.addCookie(userCookie); response.addCookie(themeCookie); response.getWriter().println("Cookies have been set!"); } } -
访问测试:
- 首先访问
http://your-domain/SetCookieServlet,这会在你的浏览器中设置两个 Cookie。 - 然后访问
http://your-domain/GetCookieServlet,你会在控制台和浏览器页面上看到 Cookie 的值。
- 首先访问
在非 Servlet 环境中获取 Cookie
如果你使用的是 java.net.HttpURLConnection(或其他 HTTP 客户端库,如 Apache HttpClient 或 OkHttp)来模拟浏览器发送请求,Cookie 的处理方式是不同的,你需要手动管理 Cookie "罐"(Cookie Store)。
核心思路
- 创建一个
CookieManager:这是用来存储和管理所有 Cookie 的核心类。 - 将
CookieManager设置为系统默认值:这样HttpURLConnection在发送请求和接收响应时,会自动使用这个CookieManager。 - 发送请求:像平常一样创建
HttpURLConnection并发送请求。 - 接收响应:响应中的
Set-Cookie头部会被CookieManager自动解析并存储。 - 获取 Cookie:从
CookieManager中获取所有已存储的 Cookie,并根据名称查找你需要的值。
代码示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
public class NonServletCookieExample {
public static void main(String[] args) throws IOException {
// --- 1. 设置 Cookie Manager ---
// 创建一个 CookieManager
CookieManager cookieManager = new CookieManager();
// 设置 Cookie 策略,接受所有 Cookie
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
// 将其设置为系统默认的 CookieManager
CookieManager.setDefault(cookieManager);
// --- 2. 发送请求到一个设置 Cookie 的服务器 ---
// 假设这个服务器会返回 "Set-Cookie" 头
String setCookieUrl = "http://your-domain/SetCookieServlet"; // 使用上面例子中的 URL
String getCookieUrl = "http://your-domain/GetCookieServlet"; // 这个 URL 期望客户端带上 Cookie
try {
// 发送第一个请求,获取并存储 Cookie
System.out.println("Sending request to: " + setCookieUrl);
HttpURLConnection connection1 = (HttpURLConnection) new URL(setCookieUrl).openConnection();
connection1.setRequestMethod("GET");
// 读取响应(即使只是为了确保请求完成)
try (BufferedReader in = new BufferedReader(new InputStreamReader(connection1.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("Response from SetCookieServlet: " + response.toString());
}
connection1.disconnect();
System.out.println("Cookies have been stored by the CookieManager.");
// --- 3. 发送第二个请求,验证 Cookie 是否被带上 ---
System.out.println("\nSending request to: " + getCookieUrl);
HttpURLConnection connection2 = (HttpURLConnection) new URL(getCookieUrl).openConnection();
connection2.setRequestMethod("GET");
// 获取请求头,查看 "Cookie" 字段
Map<String, List<String>> headers = connection2.getRequestProperties();
List<String> cookieHeaders = headers.get("Cookie");
if (cookieHeaders != null && !cookieHeaders.isEmpty()) {
System.out.println("Cookies sent in the request:");
for (String cookieHeader : cookieHeaders) {
System.out.println(cookieHeader);
}
} else {
System.out.println("No cookies were sent in the request.");
}
// 读取第二个服务的响应
try (BufferedReader in = new BufferedReader(new InputStreamReader(connection2.getInputStream()))) {
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
System.out.println("\nResponse from GetCookieServlet: " + response.toString());
}
connection2.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:上面的 HttpURLConnection 示例展示了基本原理,从 Java 11 开始,推荐使用更现代的 java.net.http.HttpClient,它对 Cookie 的支持更好且更简洁。
重要知识点总结
-
request.getCookies()vs.response.addCookie()request.getCookies():从客户端的请求中读取 Cookie。response.addCookie():将 Cookie 写入响应中,发送给客户端的浏览器进行存储。
-
Cookie 的作用域
setPath():非常重要,它定义了 Cookie 在哪个 URL 路径下有效。/app路径下的 Cookie 不会被/api路径下的请求发送,如果设置为 ,则在整个域名下都有效。
-
Cookie 的生命周期
- 会话 Cookie:
setMaxAge(-1)或不设置,浏览器关闭后,Cookie 会被删除。 - 持久化 Cookie:
setMaxAge(seconds),设置一个正数,表示 Cookie 在多少秒后过期,即使浏览器关闭,只要在过期时间之前再次打开,Cookie 依然存在。
- 会话 Cookie:
-
Cookie 的安全性
setHttpOnly(true):防止 Cookie 被 JavaScript 通过document.cookie访问,有助于防止 XSS 攻击。setSecure(true):确保 Cookie 只能通过 HTTPS 连接发送,不会被 HTTP 协议泄露,有助于防止中间人攻击。- SameSite 属性:这是一个较新的属性,用于防范 CSRF 攻击,可以设置为
Strict,Lax, 或None。
希望这个详细的解释能帮助你完全理解在 Java 中如何获取和使用 Cookie!
