Anoop Kumar
Anoop Kumar

Reputation: 488

Single HttpClientContext for multiple threads

I am using apache HttpClient 4.5 to process http request in java.

According to documentation HttpClient is thread safe so we can use same instance of HttpClient for all the threads but HttpContext should be maintain by each thread of execution.

For authentication (NTLM authentication) we need to set CredentialsProvider to the context, which will authenticate on the server.

Requirement

All the request will hit the same server with same authentication details. I want to authenticate only once when application will initialise or first request to the server, all other request should serve in same session but can be from different threads.

Can I use same context because hitting to the same server with same authentication details, or there is another way to achieve it?

Upvotes: 3

Views: 4076

Answers (1)

ok2c
ok2c

Reputation: 27538

Even though HttpContext instances ought not be shared between threads, there is nothing wrong with sharing thread-safe objects between multiple contexts. For instance, one can easily use the same CredentialsProvider and AuthCache instances with multiple concurrent contexts.

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

VERY IMPORTANT: NTLM connections are stateful and can be re-used between contexts only if associated with the same user identity. One can either turn off connection state tracking when wiring up HttpClient instance (as below) or manually set up user identity in the execution context (as above).

CloseableHttpClient client = HttpClientBuilder.create()
        .disableConnectionState()
        .build();

Upvotes: 7

Related Questions