HttpClient 4.5教程學(xué)習(xí)與翻譯——第3章:HTTP 狀態(tài)管理

原文鏈接

第3章:HTTP 狀態(tài)管理

最初融蹂,HTTP被設(shè)計(jì)為無(wú)狀態(tài)灶伊,面向請(qǐng)求/響應(yīng)的協(xié)議该编,對(duì)于跨越幾個(gè)邏輯相關(guān)的請(qǐng)求/響應(yīng)交換的有狀態(tài)會(huì)話沒有特殊規(guī)定向抢。隨著HTTP協(xié)議的普及和采用越來(lái)越多的系統(tǒng)開始將其用于應(yīng)用程序认境,它從未打算用于電子商務(wù)應(yīng)用程序的傳輸。因此挟鸠,對(duì)狀態(tài)管理的支持成為必要元暴。

Netscape Communications當(dāng)時(shí)是Web客戶端和服務(wù)器軟件的領(lǐng)先開發(fā)商,它基于專有規(guī)范在其產(chǎn)品中實(shí)現(xiàn)了對(duì)HTTP狀態(tài)管理的支持兄猩。后來(lái)茉盏,Netscape嘗試通過發(fā)布規(guī)范草案來(lái)標(biāo)準(zhǔn)化該機(jī)制。這些努力促成了通過RFC標(biāo)準(zhǔn)軌道定義的正式規(guī)范枢冤。但是鸠姨,大量應(yīng)用程序中的狀態(tài)管理仍然主要基于Netscape草案,并且與官方規(guī)范不兼容淹真。 Web瀏覽器的所有主要開發(fā)人員都不得不保持與這些應(yīng)用程序的兼容性讶迁,這極大地促成了標(biāo)準(zhǔn)合規(guī)性的碎片化。

3.1. HTTP cookies

HTTP cookie是HTTP代理和目標(biāo)服務(wù)器可以交換以維護(hù)會(huì)話的令牌或短狀態(tài)信息包核蘸。 Netscape的工程師曾經(jīng)把它稱為“神奇的餅干”巍糯,這個(gè)名字被沿用至今。
HttpClient使用Cookie接口表示抽象cookie令牌客扎。 在其最簡(jiǎn)單的形式中祟峦,HTTP cookie僅僅是名稱/值對(duì)。 通常徙鱼,HTTP cookie還包含許多屬性宅楞,例如有效的域针姿,指定此cookie適用的源服務(wù)器上的URL子集的路徑,以及cookie有效的最長(zhǎng)時(shí)間厌衙。
SetCookie接口表示由源服務(wù)器發(fā)送到HTTP代理的Set-Cookie響應(yīng)頭距淫,以便維持會(huì)話狀態(tài)。
ClientCookie接口擴(kuò)展了Cookie接口婶希,具有其他特定于客戶端的功能榕暇,例如能夠完全檢索原始服務(wù)器指定的原始cookie屬性。 這對(duì)于生成Cookie標(biāo)頭很重要喻杈,因?yàn)槟承〤ookie規(guī)范要求Cookie標(biāo)頭只有在Set-Cookie標(biāo)頭中指定時(shí)才應(yīng)包含某些屬性彤枢。
以下是創(chuàng)建客戶端cookie對(duì)象的示例:

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 規(guī)范

CookieSpec接口表示cookie管理規(guī)范。 cookie管理規(guī)范應(yīng)強(qiáng)制執(zhí)行:

  • 解析Set-Cookie標(biāo)頭的規(guī)則奕塑。
  • 解析cookie的驗(yàn)證規(guī)則堂污。
  • 格式化給定主機(jī)家肯,端口和原始路徑的Cookie標(biāo)頭龄砰。

HttpClient附帶了幾個(gè)CookieSpec實(shí)現(xiàn):

  • Standard strict: 狀態(tài)管理策略符合RFC 6265第4節(jié)定義的行為良好的配置文件的語(yǔ)法和語(yǔ)義。
  • Standard: 狀態(tài)管理策略符合RFC 6265定義的更寬松的配置文件讨衣,第4節(jié)旨在與不符合良好行為的配置文件的現(xiàn)有服務(wù)器進(jìn)行互操作换棚。
  • Netscape draft (已過時(shí)): 此政策符合Netscape Communications發(fā)布的原始規(guī)范草案。 除非絕對(duì)有必要與遺留代碼兼容反镇,否則應(yīng)該避免使用它固蚤。
  • RFC 2965 (已過時(shí)): 狀態(tài)管理策略符合RFC 2965定義的過時(shí)狀態(tài)管理規(guī)范。請(qǐng)不要在新應(yīng)用程序中使用歹茶。
  • RFC 2109 (已過時(shí)): 狀態(tài)管理策略符合RFC 2109定義的過時(shí)狀態(tài)管理規(guī)范夕玩。請(qǐng)不要在新應(yīng)用程序中使用。
  • Browser compatibility (已過時(shí)): 此策略致力于嚴(yán)密模仿舊版本的瀏覽器應(yīng)用程序(如Microsoft Internet Explorer和Mozilla FireFox)的(錯(cuò)誤)行為惊豺。 請(qǐng)不要在新的應(yīng)用程序中使用燎孟。
  • Default: 默認(rèn)cookie策略是一種綜合策略,它根據(jù)與HTTP響應(yīng)一起發(fā)送的cookie的屬性(例如版本屬性尸昧,現(xiàn)在已過時(shí))選擇RFC 2965揩页,RFC 2109或Netscape草案兼容實(shí)現(xiàn)。 在HttpClient的下一個(gè)次要版本中烹俗,將棄用此策略以支持標(biāo)準(zhǔn)(符合RFC 6265)實(shí)現(xiàn)爆侣。
  • Ignore cookies: 所有cookie都被忽略。

強(qiáng)烈建議在新應(yīng)用程序中使用標(biāo)準(zhǔn)(Standard)或嚴(yán)格標(biāo)準(zhǔn)(Standard strict)策略幢妄。 應(yīng)使用過時(shí)的規(guī)范與舊系統(tǒng)兼容兔仰。 在HttpClient的下一個(gè)主要版本中將刪除對(duì)過時(shí)規(guī)范的支持。

3.3. 選擇cookie策略

如果需要蕉鸳,可以在HTTP客戶端設(shè)置Cookie策略斋陪,并在HTTP請(qǐng)求級(jí)別覆蓋。

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策略

為了實(shí)現(xiàn)自定義cookie策略,應(yīng)該創(chuàng)建CookieSpec接口的自定義實(shí)現(xiàn)无虚,創(chuàng)建CookieSpecProvider實(shí)現(xiàn)以創(chuàng)建和初始化自定義規(guī)范的實(shí)例缔赠,并使用HttpClient注冊(cè)工廠。 一旦注冊(cè)了自定義規(guī)范友题,就可以像標(biāo)準(zhǔn)cookie規(guī)范一樣激活它嗤堰。

PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();

Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>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可以與實(shí)現(xiàn)CookieStore接口的持久性cookie存儲(chǔ)的任何物理表示一起使用。 名為BasicCookieStore的默認(rèn)CookieStore實(shí)現(xiàn)是一個(gè)由java.util.ArrayList支持的簡(jiǎn)單實(shí)現(xiàn)度宦。 當(dāng)容器對(duì)象被垃圾收集時(shí)踢匣,存儲(chǔ)在BasicClientCookie對(duì)象中的Cookie將丟失。 如有必要戈抄,用戶可以提供更復(fù)雜的實(shí)現(xiàn)离唬。

// 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狀態(tài)管理和執(zhí)行上下文

在HTTP請(qǐng)求執(zhí)行過程中,HttpClient將以下與狀態(tài)管理相關(guān)的對(duì)象添加到執(zhí)行上下文中:

  • Lookup 表示實(shí)際的cookie規(guī)范注冊(cè)表划鸽。 在本地上下文中設(shè)置的此屬性的值優(yōu)先于默認(rèn)值输莺。
  • CookieSpec 表示實(shí)際的cookie規(guī)范。
  • CookieOrigin 表示原始服務(wù)器的實(shí)際細(xì)節(jié)裸诽。
  • CookieStore 實(shí)際的cookie存儲(chǔ)庫(kù)(CookieStore)嫂用。 在本地上下文中設(shè)置的此屬性的值優(yōu)先于默認(rèn)值。
    本地HttpContext對(duì)象可用于在請(qǐng)求執(zhí)行之前自定義HTTP狀態(tài)管理上下文丈冬,或在請(qǐng)求執(zhí)行后檢查其狀態(tài)嘱函。 還可以使用單獨(dú)的執(zhí)行上下文來(lái)實(shí)現(xiàn)每個(gè)用戶(或每個(gè)線程)狀態(tài)管理。 在本地上下文中定義的cookie規(guī)范注冊(cè)表和cookie存儲(chǔ)將優(yōu)先于在HTTP客戶端級(jí)別設(shè)置的默認(rèn)值埂蕊。
CloseableHttpClient httpclient = <...>

Lookup<CookieSpecProvider> 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();

上一章: 鏈接管理
下一章: 認(rèn)證

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末往弓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蓄氧,更是在濱河造成了極大的恐慌函似,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匀们,死亡現(xiàn)場(chǎng)離奇詭異缴淋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)泄朴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門重抖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人祖灰,你說我怎么就攤上這事钟沛。” “怎么了局扶?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵恨统,是天一觀的道長(zhǎng)叁扫。 經(jīng)常有香客問我,道長(zhǎng)畜埋,這世上最難降的妖魔是什么莫绣? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮悠鞍,結(jié)果婚禮上对室,老公的妹妹穿的比我還像新娘。我一直安慰自己咖祭,他們只是感情好掩宜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著么翰,像睡著了一般牺汤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浩嫌,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天檐迟,我揣著相機(jī)與錄音,去河邊找鬼固该。 笑死锅减,一個(gè)胖子當(dāng)著我的面吹牛糖儡,可吹牛的內(nèi)容都是我干的伐坏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼握联,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼桦沉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起金闽,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纯露,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后代芜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埠褪,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年挤庇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钞速。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嫡秕,死狀恐怖渴语,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昆咽,我是刑警寧澤驾凶,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布牙甫,位于F島的核電站,受9級(jí)特大地震影響调违,放射性物質(zhì)發(fā)生泄漏窟哺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一技肩、第九天 我趴在偏房一處隱蔽的房頂上張望脏答。 院中可真熱鬧,春花似錦亩鬼、人聲如沸殖告。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)黄绩。三九已至,卻和暖如春玷过,著一層夾襖步出監(jiān)牢的瞬間爽丹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工辛蚊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粤蝎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓袋马,卻偏偏與公主長(zhǎng)得像初澎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子虑凛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355