1. 概述
本文将重点介绍如何使用 Apache HttpClient 发送自定义 Cookie。
如果想深入了解 HttpClient 的其他高级用法,可以参考主教程。
2. 在 HttpClient 上配置 Cookie 管理
2.1. HttpClient 4.3+ 版本
在较新的 HttpClient 4.3+ 版本中,我们使用流畅的构建器 API 来构造和配置客户端。
首先创建一个 Cookie 存储并设置示例 Cookie:
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
然后通过 setDefaultCookieStore()
方法在 HttpClient 上设置 Cookie 存储,并发送请求:
@Test
final void whenSettingCookiesOnTheHttpClient_thenCookieSentCorrectly() throws IOException {
final BasicCookieStore cookieStore = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setAttribute("domain", "true");
cookie.setPath("/");
cookieStore.addCookie(cookie);
final HttpGet request = new HttpGet("http://www.github.com");
try (CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
}
⚠️ 关键点:必须正确设置 Cookie 的 domain
属性——否则客户端将完全不会发送该 Cookie!
根据具体版本,可能还需要添加:
cookie.setAttribute("domain", "true");
2.2. HttpClient 4.3 之前版本
在旧版 HttpClient(4.3 之前)中,Cookie 存储直接设置在 HttpClient 上:
@Test
public void givenUsingDeprecatedApi_whenSettingCookiesOnTheHttpClient_thenCorrect()
throws ClientProtocolException, IOException {
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
DefaultHttpClient client = new DefaultHttpClient();
client.setCookieStore(cookieStore);
HttpGet request = new HttpGet("http://www.github.com");
response = client.execute(request);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
除了客户端构建方式不同,其他与 4.3+ 版本无异。
3. 在请求级别设置 Cookie
如果不想全局配置 HttpClient,可以通过 HttpContext
为单个请求设置 Cookie:
@Test
final void whenSettingCookiesOnTheRequest_thenCorrect() throws IOException {
final BasicCookieStore cookieStore = new BasicCookieStore();
final BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", "1234");
cookie.setDomain(".github.com");
cookie.setAttribute("domain", "true");
cookie.setPath("/");
cookieStore.addCookie(cookie);
final HttpGet request = new HttpGet("http://www.github.com");
try (CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultCookieStore(cookieStore)
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
}
4. 在底层请求中设置 Cookie
更底层的做法是直接在 HTTP 请求头中设置 Cookie:
@Test
final void whenSettingCookiesOnARequest_thenCorrect() throws IOException {
final HttpGet request = new HttpGet("http://www.github.com");
request.setHeader("Cookie", "JSESSIONID=1234");
try (CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(request, new CustomHttpClientResponseHandler())) {
assertThat(response.getCode(), equalTo(200));
}
}
❌ 踩坑警告:这种方式比内置 Cookie 支持更容易出错。例如,这里我们完全没有设置 domain 属性——这是不正确的做法。
5. 总结
本文展示了如何使用 HttpClient 发送自定义的、用户可控的 Cookie。
注意:这不同于让 HttpClient 自动处理服务器设置的 Cookie,而是在底层手动控制客户端行为。
所有示例代码可在 GitHub 项目 中找到。