最初HTTP被设计为无状态的。然而,真实的应用中常常要能够通过几个逻辑相关的请求/响应保持状态信息。为了使应用程序能够保持一个处理状态,HttpClient允许HTTP请求在特定的执行上下文内执行,称为HTTP上下文。如果相同的上下文在连续的请求之间重用,多个逻辑相关的连续请求可以参与一个逻辑会话。HTTP上下文的功能类似于java.util.Map<String,Object>,它只不过是任意命名的值的集合。应用程序能在请求执行之前填充上下文属性,也能在请求执行完成之后检查上下文。
HttpContext能包含任意对象,因此,可能不是线程安全的。建议每个执行线程维护自己的上下文。
在HTTP请求执行的过程中,HttpClient添加以下属性到执行上下文:
- HttpConnection:它代表连接到目标服务器的实际连接。
- HttpHost:它代表连接目标。
- HttpRoute:它代表一个完整的连接路由。
- HttpRequest:它代表一个真实的HTTP请求。在上下文中的最后的HttpRequest对象总是代表一个精确的消息状态被发送到目标服务器。默认的HTTP1.0和HTTP1.1使用相对的请求URI,然而请求是在非隧道模式中通过代理发送的,那么它是绝对URI。
- HttpResponse:它代表当前的HTTP响应。
- java.lang.Boolean:它代表一个标志,标识当前请求是否已经被完全传送到连接目标。
- RequestConfig:它代表当前请求的配置。
- java.util.List<URI>:它代表在请求执行过程中接收到的所有重定向地址的集合。
我们可以使用HttpClientContext适配器类来简化与上下文状态之间的相互作用:
HttpContext context = <...> HttpClientContext clientContext = HttpClientContext.adapt(context); HttpHost target = clientContext.getTargetHost(); HttpRequest request = clientContext.getRequest(); HttpResponse response = clientContext.getResponse(); RequestConfig config = clientContext.getRequestConfig();
代表一个逻辑相关会话的多请求序列应执行在同一个HttpContext实体中,确保会话上下文与状态信息在请求间自动传播(示例衔接上面的示例):
CloseableHttpClient httpclient = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom(). setSocketTimeout(1000).setConnectTimeout(1000).build(); HttpGet httpget1 = new HttpGet("http://localhost/1"); httpget1.setConfig(requestConfig); //context上个示例中定义了 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(); }
时间: 2024-10-26 17:33:55