本教程将专注于如何使用Apache HttpClient发送自定义Cookie。
配置HttpClient上的Cookie管理
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的域——如果不设置正确的域,客户端将不会发送该cookie!
此外,根据您使用的具体版本,您可能还需要设置:
cookie.setAttribute("domain", "true");
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");
HttpResponse response = client.execute(request);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
}
除了客户端构建的方式不同外,这与之前的例子没有其他区别。
在请求上设置Cookie
如果在整个HttpClient上设置cookie不是一个选项,我们可以使用HttpContext类单独为请求配置cookie:
@Test
final void whenSettingCookiesOnTheRequest_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));
}
}
以原始Header的形式设置cookie
另一种方法是在HTTP请求上以原始Header的形式设置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支持更容易出错。例如,请注意在这种情况下我们不再设置域名——这是不正确的。
结论
本文说明了如何使用HttpClient发送自定义、用户控制的Cookie。
请注意,这与让HttpClient处理服务器设置的cookies不同。相反,它是在较低级别手动控制客户端侧。