我正在使用apache HttpClient 4.5来处理java中的http请求。
根据文档,HttpClient是线程安全的,所以我们可以为所有线程使用相同的HttpClient实例,但HttpContext应该由每个执行线程维护。
对于身份验证(NTLM身份验证),我们需要将CredentialsProvider设置为上下文,该上下文将在服务器上进行身份验证。
要求
所有请求都将使用相同的身份验证详细信息访问同一服务器。我只想在应用程序初始化或首次请求服务器时进行一次身份验证,所有其他请求应在同一会话中提供,但可以来自不同的线程。
我是否可以使用相同的上下文,因为使用相同的身份验证详细信息命中相同的服务器,或者还有其他方法可以实现它?
答案 0 :(得分:4)
即使线程之间不应该共享HttpContext
实例,在多个上下文之间共享线程安全对象也没有错。例如,可以轻松地使用具有多个并发上下文的相同CredentialsProvider
和AuthCache
实例。
// External dependencies
CloseableHttpClient client;
CredentialsProvider credentialsProvider;
AuthCache authCache;
CookieStore cookieStore;
Principal userPrincipal;
// request execution
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credentialsProvider);
context.setAuthCache(authCache);
context.setCookieStore(cookieStore);
context.setUserToken(userPrincipal);
HttpGet httpGet = new HttpGet("http://targethost/");
try (CloseableHttpResponse response1 = client.execute(httpGet, context)) {
System.out.println(response1.getStatusLine());
EntityUtils.consume(response1.getEntity());
}
非常重要:NTLM连接是有状态的,只有在与相同的用户身份相关联时才能在上下文之间重用。可以在连接HttpClient
实例(如下所示)时关闭连接状态跟踪,也可以在执行上下文中手动设置用户身份(如上所述)。
CloseableHttpClient client = HttpClientBuilder.create()
.disableConnectionState()
.build();