杰瑞科技汇

Java Cookie 取值时如何处理编码问题?

  1. 在 Servlet 环境中(最常见,如 Java Web 应用)
  2. 在非 Servlet 环境中(使用 java.net.HttpURLConnection 发送 HTTP 请求)

在 Servlet 环境中获取 Cookie

这是最经典和常见的情况,当你的 Java Web 应用(运行在 Tomcat, Jetty 等服务器上)接收到一个 HTTP 请求时,你可以从 HttpServletRequest 对象中获取客户端发送过来的所有 Cookie。

核心步骤

  1. 获取 Cookie 数组:通过 request.getCookies() 方法,可以获取一个 Cookie 对象的数组。注意:如果请求中没有携带任何 Cookie,这个方法会返回 null,所以必须进行空值检查。
  2. 遍历数组:遍历这个 Cookie 数组。
  3. 比较 Cookie 名称:在遍历过程中,使用 cookie.getName() 方法获取每个 Cookie 的名称,并与你想要查找的 Cookie 名称进行比较。
  4. 获取 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.");
        }
    }
}

如何测试?

  1. 设置 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!");
        }
    }
  2. 访问测试

    • 首先访问 http://your-domain/SetCookieServlet,这会在你的浏览器中设置两个 Cookie。
    • 然后访问 http://your-domain/GetCookieServlet,你会在控制台和浏览器页面上看到 Cookie 的值。

在非 Servlet 环境中获取 Cookie

如果你使用的是 java.net.HttpURLConnection(或其他 HTTP 客户端库,如 Apache HttpClient 或 OkHttp)来模拟浏览器发送请求,Cookie 的处理方式是不同的,你需要手动管理 Cookie "罐"(Cookie Store)。

核心思路

  1. 创建一个 CookieManager:这是用来存储和管理所有 Cookie 的核心类。
  2. CookieManager 设置为系统默认值:这样 HttpURLConnection 在发送请求和接收响应时,会自动使用这个 CookieManager
  3. 发送请求:像平常一样创建 HttpURLConnection 并发送请求。
  4. 接收响应:响应中的 Set-Cookie 头部会被 CookieManager 自动解析并存储。
  5. 获取 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 的支持更好且更简洁。


重要知识点总结

  1. request.getCookies() vs. response.addCookie()

    • request.getCookies():从客户端的请求中读取 Cookie。
    • response.addCookie():将 Cookie 写入响应中,发送给客户端的浏览器进行存储。
  2. Cookie 的作用域

    • setPath():非常重要,它定义了 Cookie 在哪个 URL 路径下有效。/app 路径下的 Cookie 不会被 /api 路径下的请求发送,如果设置为 ,则在整个域名下都有效。
  3. Cookie 的生命周期

    • 会话 CookiesetMaxAge(-1) 或不设置,浏览器关闭后,Cookie 会被删除。
    • 持久化 CookiesetMaxAge(seconds),设置一个正数,表示 Cookie 在多少秒后过期,即使浏览器关闭,只要在过期时间之前再次打开,Cookie 依然存在。
  4. Cookie 的安全性

    • setHttpOnly(true):防止 Cookie 被 JavaScript 通过 document.cookie 访问,有助于防止 XSS 攻击。
    • setSecure(true):确保 Cookie 只能通过 HTTPS 连接发送,不会被 HTTP 协议泄露,有助于防止中间人攻击。
    • SameSite 属性:这是一个较新的属性,用于防范 CSRF 攻击,可以设置为 Strict, Lax, 或 None

希望这个详细的解释能帮助你完全理解在 Java 中如何获取和使用 Cookie!

分享:
扫描分享到社交APP
上一篇
下一篇