HttpClient(4.3.5) - HTTP Execution Context
Originally HTTP has been designed as a stateless, response-request oriented protocol. However, real world applications often need to be able to persist state information through several logically related request-response exchanges. In order to enable applications to maintain a processing state HttpClient allows HTTP requests to be executed within a particular execution context, referred to as HTTP context. Multiple logically related requests can participate in a logical session if the same context is reused between consecutive requests. HTTP context functions similarly to a java.util.Map<String, Object>
. It is simply a collection of arbitrary named values. An application can populate context attributes prior to request execution or examine the context after the execution has been completed.
HttpContext
can contain arbitrary objects and therefore may be unsafe to share between multiple threads. It is recommended that each thread of execution maintains its own context.
In the course of HTTP request execution HttpClient adds the following attributes to the execution context:
-
HttpConnection
instance representing the actual connection to the target server. -
HttpHost
instance representing the connection target. -
HttpRoute
instance representing the complete connection route -
HttpRequest
instance representing the actual HTTP request. The final HttpRequest object in the execution context always represents the state of the message exactly as it was sent to the target server. Per default HTTP/1.0 and HTTP/1.1 use relative request URIs. However if the request is sent via a proxy in a non-tunneling mode then the URI will be absolute. -
HttpResponse
instance representing the actual HTTP response. -
java.lang.Boolean
object representing the flag indicating whether the actual request has been fully transmitted to the connection target. -
RequestConfig
object representing the actual request configuation. -
java.util.List<URI>
object representing a collection of all redirect locations received in the process of request execution.
One can use HttpClientContext
adaptor class to simplify interractions with the context state.
HttpContext context = <...> HttpClientContext clientContext = HttpClientContext.adapt(context); HttpHost target = clientContext.getTargetHost(); HttpRequest request = clientContext.getRequest(); HttpResponse response = clientContext.getResponse(); RequestConfig config = clientContext.getRequestConfig();
Multiple request sequences that represent a logically related session should be executed with the same HttpContext
instance to ensure automatic propagation of conversation context and state information between requests.
In the following example the request configuration set by the initial request will be kept in the execution context and get propagated to the consecutive requests sharing the same context.
CloseableHttpClient httpclient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(1000) .setConnectTimeout(1000) .build(); HttpGet httpget1 = new HttpGet("http://localhost/1"); httpget1.setConfig(requestConfig); CloseableHttpResponse response1 = httpclient.execute(httpget1, context); try { HttpEntity entity1 = response1.getEntity(); } finally { response1.close(); } HttpGet httpget2 = new HttpGet("http://localhost/2"); CloseableHttpResponse response2 = httpclient.execute(httpget2, context); try { HttpEntity entity2 = response2.getEntity(); } finally { response2.close(); }