2017-02-01 51 views
0

我使用Apache的HttpClient 4.5來處理的Java HTTP請求。單HttpClientContext多線程

根據文檔的HttpClient是線程安全的,所以我們可以使用的HttpClient的同一個實例所有線程,但HttpContext的應該是執行的每個線程維護。

對於身份驗證(NTLM身份驗證),我們需要CredentialsProvider設置的背景下,這將在服務器上進行驗證。

要求

所有請求將擊中相同的身份驗證信息在同一臺服務器。當應用程序初始化或首次請求服務器時,我只想驗證一次,所有其他請求應該在同一會話中服務,但可以來自不同的線程。

我可以用相同的情況下,因爲打與相同的認證信息相同的服務器,或有另一種方式來實現呢?

回答

1

即使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(); 
+0

你創建一個「上下文」,但你不使用它。 我認爲正確的是client.execute(HTTPGET,上下文) – Nightingale7

+0

你是絕對正確的。糾正。 – oleg