閱讀120 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《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("https://somehost/");
CloseableHttpResponse response1 = httpclient.execute(httpget, context);

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

轉載自 並發編程網 - ifeve.com

最後更新:2017-05-19 11:31:46

  上一篇:go  《Http Client 官方文檔》7. 高級主題
  下一篇:go  Spring Data 官方文檔》4.7 Spring Data擴展