《HttpClient 官方文档》第三章 HTTP 状态管理

通常 HTTP 被设计为无状态,面向请求/响应的协议,对于有一些逻辑相关的请求/响应交换的有状态会话没有特别的规定。正当 HTTP 协议越来越流行和被认可,越来越多之前没有打算使用它的系统,现在也开始为了应用程序而使用它。例如电子商务应用的内容传输。因此,支持 HTTP 状态管理变得非常有必要。
NetScape(网景公司),曾经引领网页客户端和服务器端软件的发展,在他们的产品中基于专有的规范,提供了 HTTP 状态管理的支持。之后,NetScape 尝试通过发布规范草案来标准化这种机制。这些努力通过 RFC 标准促进了正式的规范定义。但是,状态管理在很多应用程序中仍然支持 Netscape 的草案而不兼容官方的标准。很多Web浏览器的主要开发人员觉得有必要保留这些极大地促进标准兼容性的草案。

3.1. HTTP cookies

一个 HTTP cookie 是 HTTP 代理或者目标服务器保持会话和交流状态信息的一个令牌或者短数据包。Netscape 工程师过去称它为 “魔力 cookie”,一个非常有粘力的名字。
HttpClient 使用 Cookie 接口来表示一个抽象 cookie 令牌。在 HTTP 中,简单的形式是指一个键/值对。通常一个 HTTP cookie 也包含一系列的属性,cookie 提供的属性有例如一个域名是否可用,源服务器上指定的url子集路径,cookie 最长的有效时间等。
SetCookie 接口表示由源服务器发送给HTTP代理的响应头中的Set-Cookie,以此来维持一个会话状态。
ClientCookie接口继承自 Cookie 接口并且自身扩展了客户端特有的功能,例如从源服务器中恢复原始的 cookie。这对于生成 Cookie 的头信息是非常重要的,因为一些特殊的 cookie 规范需要Cookie头信息中必须包含特定的属性,这些需要在 Set-Cookie 头中定义。下面是一些创建客户端 cookie 的实例:

BasicClientCookie cookie = new BasicClientCookie("name", "value");
// Set effective domain and path attributes
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
// Set attributes exactly as sent by the server
cookie.setAttribute(ClientCookie.PATH_ATTR, "/");
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");

3.2. Cookie 规范

CookieSpec 接口定义了一个 cookie 管理规范。下面这些是 cookie 管理规范强制的:

  • Set-Cookie 的解析规则
  • 验证解析 cookies的规则
  • 给定的主机,端口和源路径来格式化Cookie 头信息

HttpClient 附带了一些 CookieSpec 的实现规范:

  • Standard strict: State management policy compliant with the syntax and semantics of the well-behaved profile defined by RFC on6265, section 4.
  • Standard: State management policy compliant with a more relaxed profile defined by RFC 6265, section 4 intended for interoperability with existing servers that do not conform to the well behaved profile.
  • Netscape draft (obsolete): This policy conforms to the original draft specification published by Netscape Communications. It should be avoided unless absolutely necessary for compatibility with legacy code.
  • RFC 2965 (obsolete): State management policy compliant with the obsolete state management specification defined by RFC 2965. Please do not use in new applications.
  • RFC 2109 (obsolete): State management policy compliant with the obsolete state management specification defined by RFC 2109. Please do not use in new applications.
  • Browser compatibility (obsolete): This policy strives to closely mimic the (mis)behavior of older versions of browser applications such as Microsoft Internet Explorer and Mozilla FireFox. Please do not use in new applications.
  • Default: Default cookie policy is a synthetic policy that picks up either RFC 2965, RFC 2109 or Netscape draft compliant implementation based on properties of cookies sent with the HTTP response (such as version attribute, now obsolete). This policy will be deprecated in favor of the standard (RFC 6265 compliant) implementation in the next minor release of HttpClient.
  • Ignore cookies: All cookies are ignored.

在新的应用实现中,强烈建议使用Standard 或者 Standard strict两种规范。过时的规范仅仅在一些遗留的系统上为了兼容性而使用。支持的过时规范会在下一个发布的 HttpClient 主要版本中移除。

3.3. 选择 cookie 策略

Cookie 策略可以在 HTTP 客户端中设置,如果需要也可以在 HTTP 请求中重写。

RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(globalConfig)
.build();
RequestConfig localConfig = RequestConfig.copy(globalConfig)
.setCookieSpec(CookieSpecs.STANDARD_STRICT)
.build();
HttpGet httpGet = new HttpGet("/");
httpGet.setConfig(localConfig);

3.4. 自定义 cookie 策略

为了实现自定义 cookie 策略你必须实现一个 CookieSpec 接口,创建 CookieSpecProvider 的实现类,用它来初始化自定义的规范和 HttpClient 的注册工厂。一旦自定义策略被注册,它就可以像标准的 cookie 规范一些样使用。

PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();

Registry r = RegistryBuilder.create()
.register(CookieSpecs.DEFAULT,
new DefaultCookieSpecProvider(publicSuffixMatcher))
.register(CookieSpecs.STANDARD,
new RFC6265CookieSpecProvider(publicSuffixMatcher))
.register("easy", new EasySpecProvider())
.build();

RequestConfig requestConfig = RequestConfig.custom()
.setCookieSpec("easy")
.build();

CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCookieSpecRegistry(r)
.setDefaultRequestConfig(requestConfig)
.build();

3.5. Cookie 持久化

HttpClient 可以和任何一个实现了CookieStore 接口的物理 cookie 一起使用。默认的 CookieStore 实现类是 BasicCookieStore,它是使用 java.utils.ArrayList 来实现的。当容器对象被进行垃圾回收时,储存在BasicClientCookie中的Cookies对象也会丢失。如果必要的话,使用者可以提供一个复杂的实现。

// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Populate cookies if needed
BasicClientCookie cookie = new BasicClientCookie("name", "value");
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
// Set the store
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();

3.6. HTTP 状态管理和执行上下文

在HTTP请求执行过程中,HttpClient将下面相关状态管理对象添加到执行的上下文中:

  • Lookup instance representing the actual cookie specification registry. The value of this attribute set in the local context takes precedence over the default one.
  • CookieSpec instance representing the actual cookie specification.
  • CookieOrigin instance representing the actual details of the origin server.
  • CookieStore instance representing the actual cookie store. The value of this attribute set in the local context takes precedence over the default one.

本地HttpContext对象可以用于在请求执行之前定制HTTP状态管理的上下文,或者在请求执行后检查它的状态。开发者仍然可以使用分开的上下文来实现每一个用户(或者每一个线程)的状态管理。cookie 规范的注册,在本地上下文中定义存储的 cookie 优先于那些在 HTTP 客户端设置的默认上下文。

CloseableHttpClient httpclient =

Lookup cookieSpecReg =
CookieStore cookieStore =

HttpClientContext context = HttpClientContext.create();
context.setCookieSpecRegistry(cookieSpecReg);
context.setCookieStore(cookieStore);
HttpGet httpget = new HttpGet("http://somehost/");
CloseableHttpResponse response1 = httpclient.execute(httpget, context);

// Cookie origin details
CookieOrigin cookieOrigin = context.getCookieOrigin();
// Cookie spec used
CookieSpec cookieSpec = context.getCookieSpec();

转载自 并发编程网 - ifeve.com

时间: 2024-09-05 04:49:17

《HttpClient 官方文档》第三章 HTTP 状态管理的相关文章

《HttpClient官方文档》2.3 HTTP连接管理

2.3. HTTP 连接管理 2.3.1. 管理连接和连接管理器 HTTP 连接是复杂的. 有状态的. 非线程安全的对象,因此需要恰当的管理才能正常工作.HTTP连接一次只能由一个线程使用.HttpClient使用实现了HttpClientConnectionManager接口,被称为HTTP连接管理器的特殊实体去访问HTTP连接. HTTP连接管理器的作用是作为一个工厂类来为新的HTTP连接使用,管理持久连接的生命周期和同步访问,确保一次只能由一个线程使用连接. HTTP连接管理器内部与Man

《HttpClient官方文档》1.2 HttpClient 接口

1.2. HttpClient 接口 HttpClient 接口表示最基本的HTTP请求执行要约.它不会对请求执行过程加上约束或一些特定的信息,并且保留连接管理,状态管理,认证和处理重定向的细节到各自的实现中.这会使它更方便的使用额外功能来装饰接口,如响应内容缓存. 通常来说, HttpClient接口的实现负责处理特定方面的HTTP协议,比如重定向.身份认证处理.对连接的持久性和维持连接存活长短的决策之类的多个处理程序和策略接口实现的门面. 这使得用户能够有选择性的将一些自定义的,基于特定应用

《HttpClient官方文档》第六章 HTTP 缓存

第六章. HTTP缓存 6.1. 通用概念 HttpClient Cache 提供了用HttpClient(等效浏览器缓存的Java实现)来兼容HTTP / 1.1的缓存层.实现遵循责任链模式,HttpClient缓存的实现类可以替代默认无缓存的HttpClient;完全可以通过缓存实现的请求将不会触发实际的原始请求.在可以的情况下,使用GETs条件If-Modified-Since和/or If-None-Match请求头,会自动验证旧的缓存项.HTTP / 1.1缓存一般被设计成语义透明的,

《HttpClient 官方文档》第五章 Fluent API

第五章:流式 API 5.1 易用 API 接口 4.2版本的 HttpClient 带来了一组非常容易使用的流式 API(Fluent API) 接口.暴露的流式API(Fluent API) 接口中仅仅是 HttpClient 最基本的一些功能,这些接口是在不需要使用 HttpClient 丰富的灵活性时,为了一些简单的功能而准备的. 例如:流式接口(Fluent API) 增加了使用者对连接的管理和资源的分配上的便利性.这里有一系列通过 HttpClient 流式接口(Fluent API

《HttpClient官方文档》1.1 执行请求(二)

1.1.4. HTTP 实体 HTTP 消息可以携带与其相关联的请求或响应的内容实体.实体可以在一些请求和响应中找到,因为它们也是可选的.使用了实体的请求被称为封闭实体请求.HTTP规范定义了两种封闭实体的方法: POST 和PUT.响应通常期望包含一个内容实体. 这个规则也有特例,就像HEAD 方法和 204 No Content,304 Not Modified, 205 Reset Content 响应. HttpClient根据其内容来源以此区分三种类型的实体: streamed(流式)

《HttpClient官方文档》2.7 连接套接字工厂

2.7. Socket连接工厂 HTTP连接在内部使用java.net.Socket类的对象来处理数据在线路上的传输. 然而,他们依靠 ConnectionSocketFactory接口来创建,初始化和连接Socket.HttpClient的使用者能够在运行时,提供应用程序特定的Socket初始化代码.PlainConnectionSocketFactory类是创建和初始化普通(未加密)套接字的默认工厂类. 创建一个套接字和连接到主机的过程是解耦的,以便连接操作被阻塞的时候套接字能够被关闭 Ht

《HttpClient官方文档》4.8 SPNEGO/Kerberos验证

SPNEGO(简单并且受保护的GSSAPI协商机制)被设计为当两端都不知道他人可以提供,或使用什么时所提供的验证服务.它可以包装其他的机制,但是目前HttpClient4.2是按照Kerbros单独设计的. 4.8.1SPNEGO在HttpClient中的支持 SPNEGO验证方案被Sun Java 1.5以上版本兼容.1.6以上的Java版本被强烈推荐,因为它已经完全支持了SPNEGO验证. Sun JRE 提供了相关支持类来处理几乎所有的Kerb er和SPNEGO的令牌.这意味着很多步骤是

《HttpClient官方文档》1.3 HTTP执行上下文

1.3 HTTP执行上下文 HTTP起初是被设计成一种无状态的.面向请求和响应的协议.然而实际的应用经常需要在请求-响应切换过程中保存状态信息.为了使应用能够维持处理状态,HttpClient允许HTTP请求可以在一个特殊的上下文环境(HttpContext)中执行.如果一个context在连续的HTTP请求中被复用,那么这些逻辑相关的请求可以参与到同一个逻辑会话中.HttpContext功能与java.util.Map<String, Object>类似,它是一组任意值的集合.一个应用程序可

《HttpClient官方文档》HTTP验证4.4-4.7

4.4 HTTP验证和执行上下文 HttpClient依赖于AuthState类来追踪验证进程的状态的详细信息.HttpClient在执行HTTP请求执行时,创建AuthState的两个实例:一个对目标主机认证,另外一个用于代理认证.一旦目标主机或者代理要求用户验证,对应的AuthState实例将会在验证过程中被AuthScope,AuthScheme和Crednetials填充.这个AuthState可以被检查用于找出哪种类型要求验证,是否对应的AuthScheme被找到,以及凭证提供者可以找