单个HttpClientContext用于多个线程

时间:2017-02-01 09:47:54

标签: apache-httpclient-4.x

我正在使用apache HttpClient 4.5来处理java中的http请求。

根据文档,HttpClient是线程安全的,所以我们可以为所有线程使用相同的HttpClient实例,但HttpContext应该由每个执行线程维护。

对于身份验证(NTLM身份验证),我们需要将CredentialsProvider设置为上下文,该上下文将在服务器上进行身份验证。

要求

所有请求都将使用相同的身份验证详细信息访问同一服务器。我只想在应用程序初始化或首次请求服务器时进行一次身份验证,所有其他请求应在同一会话中提供,但可以来自不同的线程。

我是否可以使用相同的上下文,因为使用相同的身份验证详细信息命中相同的服务器,或者还有其他方法可以实现它?

1 个答案:

答案 0 :(得分:4)

即使线程之间不应该共享HttpContext实例,在多个上下文之间共享线程安全对象也没有错。例如,可以轻松地使用具有多个并发上下文的相同CredentialsProviderAuthCache实例。

// 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();