最初,Http被设计成一个无状态的,面向请求/响应的协议,所以它不能在逻辑相关的http请求/响应中保持状态会话。由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统,比如电子商务系统。因此,http支持状态管理就很必要了。

当时的web客户端和服务器软件领先者,网景(netscape)公司,最先在他们的产品中支持http状态管理,并且制定了一些专有规范。后来,网景通过发规范草案,规范了这一机制。这些努力促成 RFC standard track制定了标准的规范。但是,现在多数的应用的状态管理机制都在使用网景公司的规范,而网景的规范和官方规定是不兼容的。因此所有的浏览器开发这都被迫兼容这两种协议,从而导致协议的不统一。

3.1.Http cookies

所谓的Http cookie就是一个token或者很短的报文信息,http代理和服务器可以通过cookie来维持会话状态。网景的工程师把它们称作“magic cookie”。

HttpClient使用Cookie接口来代表cookie。简单说来,cookie就是一个键值对。一般,cookie也会包含版本号、域名、路径和cookie有效期。

SetCookie接口可以代表服务器发给http代理的一个set-cookie响应头,在浏览器中,这个set-cookie响应头可以写入cookie,以便保持会话状态。SetCookie2接口对SetCookie接口进行了拓展,添加了Set-Cookie2方法。

ClientCookie接口继承了Cookie接口,并进行了功能拓展,比如它可以取出服务器发送过来的原始cookie的值。生成头消息是很重要的,因为只有当cookie被指定为Set-Cookie或者Set-Cookie2时,它才需要包括一些特定的属性。

3.1.1COOKIES版本

兼容网景的规范,但是不兼容官方规范的cookie,是版本0. 兼容官方规范的版本,将会是版本1。版本1中的Cookie可能和版本0工作机制有差异。

下面的代码,创建了网景版本的Cookie:

BasicClientCookie netscapeCookie = new BasicClientCookie("name", "value");
netscapeCookie.setVersion(0);
netscapeCookie.setDomain(".yeetrack.com");
netscapeCookie.setPath("/");

下面的代码,创建标准版本的Cookie。注意,标准版本的Cookie必须保留服务器发送过来的Cookie所有属性。

BasicClientCookie2 stdCookie = new BasicClientCookie2("name", "value");
stdCookie.setVersion(1);
stdCookie.setDomain(".yeetrack.com");
stdCookie.setPorts(new int[] {80,8080});
stdCookie.setPath("/");
stdCookie.setSecure(true);
// Set attributes EXACTLY as sent by the server
stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");
stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".yeetrack.com");
stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");

3.2. Cookie规范

CookieSpec接口代表了Cookie管理规范。Cookie管理规范规定了:

  • 解析Set-CookieSet-Cookie2(可选)头消息的规则
  • 验证Cookie的规则
  • 将指定的主机名、端口和路径格式化成Cookie头消息

HttpClient有下面几种CookieSpec规范:

  • Netscape draft: 这种符合网景公司指定的规范。但是尽量不要使用,除非一定要保证兼容很旧的代码。
  • Standard: RFC 2965 HTTP状态管理规范
  • Browser compatibility: 这种方式,尽量模仿常用的浏览器,如IE和firefox
  • Best match: ‘Meta’ cookie specification that picks up a cookie policy based on the format of cookies sent with the HTTP response.它基本上将上面的几种规范积聚到一个类中。
    ++ Ignore cookies: 忽略所有Cookie
    强烈推荐使用Best Match匹配规则,让HttpClient根据运行时环境自己选择合适的规范。

3.3.选择Cookie策略

我们可以在创建Http client的时候指定Cookie测试,如果需要,也可以在执行http请求的时候,进行覆盖指定。

RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(globalConfig)
.build();
RequestConfig localConfig = RequestConfig.copy(globalConfig)
.setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
.build();
HttpGet httpGet = new HttpGet("http://www.yeetrack.com");
httpGet.setConfig(localConfig);

3.4.自定义Cookie策略

如果我们要自定义Cookie测试,就要自己实现CookieSpec接口,然后创建一个CookieSpecProvider接口来新建、初始化自定义CookieSpec接口,最后把CookieSpecProvider注册到HttpClient中。一旦我们注册了自定义策略,就可以像其他标准策略一样使用了。

 CookieSpecProvider easySpecProvider = new CookieSpecProvider() {

        public CookieSpec create(HttpContext context) {

            return new BrowserCompatSpec() {
@Override
public void validate(Cookie cookie, CookieOrigin origin)
throws MalformedCookieException {
// Oh, I am easy
}
};
} };
Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()
.register(CookieSpecs.BEST_MATCH,
new BestMatchSpecFactory())
.register(CookieSpecs.BROWSER_COMPATIBILITY,
new BrowserCompatSpecFactory())
.register("easy", easySpecProvider)
.build(); RequestConfig requestConfig = RequestConfig.custom()
.setCookieSpec("easy")
.build(); CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCookieSpecRegistry(r)
.setDefaultRequestConfig(requestConfig)
.build();

3.5.Cookie持久化

HttpClient可以使用任何存储方式的cookie store,只要这个cookie store实现了CookieStore接口。默认的CookieStore通过java.util.ArrayList简单实现了BasicCookieStore。存在在BasicCookieStore中的Cookie,当载体对象被当做垃圾回收掉后,就会丢失。如果必要,用户可以自己实现更为复杂的方式。

 // 创建CookieStore实例
CookieStore cookieStore = new BasicCookieStore();
// 新建一个Cookie
BasicClientCookie cookie = new BasicClientCookie("name", "value");
cookie.setVersion(0);
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
cookieStore.addCoo
//将CookieStore设置到httpClient中
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.build();

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

在Http请求执行过程中,HttpClient会自动向执行上下文中添加下面的状态管理对象:

  • Lookup对象 代表实际的cookie规范registry。在当前上下文中的这个值优先于默认值。
  • CookieSpec对象 代表实际的Cookie规范。
  • CookieOrigin对象 代表实际的origin server的详细信息。
  • CookieStore对象 表示Cookie store。这个属性集中的值会取代默认值。

本地的HttpContext对象可以用来在Http请求执行前,自定义Http状态管理上下文;或者测试http请求执行完毕后上下文的状态。我们也可以在不同的线程中使用不同的执行上下文。我们在http请求层指定的cookie规范集和cookie store会覆盖在http Client层级的默认值。

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

HttpClient-03Http状态管理的更多相关文章

  1. httpclient http状态管理

    HTTP状态管理 最初,Htt被设计成一个无状态的面向请求响应的协议,所以它不能再逻辑相关的http请求/响应中保持状态会话. 由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统 ...

  2. HttpClient_HttpClient 4.3.6 HTTP状态管理

    HTTP状态管理 最初的HTTP被设计成以状态.请求/应答为导向的协议,它被制作成是没有特殊条款的,以便在状态会话中能交换逻辑关系请求/应答.HTTP协议越来越受欢迎和被采用,越来越多的系统会在应用程 ...

  3. Part2-HttpClient官方教程-Chapter3-HTTP状态管理

    ps:近日忙于课设与一个赛事的准备....时间真紧啊~~ 最初,HTTP被设计为一种无状态的,面向请求/响应的协议,它并没有为跨越多个逻辑相关的请求/响应交换的有状态会话做出特殊规定.随着HTTP协议 ...

  4. Blazor+Dapr+K8s微服务之状态管理

    1         状态管理服务器端接口 1.1         添加Dapr.AspNetCore包 在DaprTest1.Server项目中添加Dapr.AspNetCore包,该包实现了ASP. ...

  5. HttpClient4.3教程 第三章 Http状态管理

    最初,Http被设计成一个无状态的,面向请求/响应的协议,所以它不能在逻辑相关的http请求/响应中保持状态会话.由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统,比如电子商务 ...

  6. Redux状态管理方法与实例

    状态管理是目前构建单页应用中不可或缺的一环,也是值得花时间学习的知识点.React官方推荐我们使用Redux来管理我们的React应用,同时也提供了Redux的文档来供我们学习,中文版地址为http: ...

  7. 表格搞定 Asp.net Web 状态管理

    最近在网上搜罗了 ASP.NET WEB 状态管理方面的一些内容,终于把这些内容整合总结了一下. 1. 希望自己通过整理,能够掌握一些,为自己投资. 2. 以便自己忘记,又要浪费时间搜罗. 3. 希望 ...

  8. [译]面向初学者的Asp.Net状态管理技术

    介绍 本文主要讲解Asp.Net应用程序中的状态管理技术(Asp.Net中有多种状态管理技术),并批判性地分析所有状态管理技术的优缺点. 背景 HTTP是无状态的协议.客户端发起一个请求,服务器响应完 ...

  9. [Asp.Net]状态管理(Session、Application、Cache)

    上篇博文介绍了在客户端状态管理的两种方式:http://www.cnblogs.com/wolf-sun/p/3329773.html.除了在客户端上保存状态外,还可以在服务器上保存状态.使用客户端的 ...

随机推荐

  1. js 技巧 (六)JavaScript[对象.属性]集锦

    JavaScript[对象.属性]集锦 SCRIPT 标记 用于包含javascript代码. 语法 属性 LANGUAGE 定义脚本语言 SRC 定义一个URL用以指定以.JS结尾的文件 windo ...

  2. lucene-5.3.1配置(win7x64)

    lucene下载地址:http://www.us.apache.org/dist/lucene/java/5.3.1/lucene-5.3.1.zip 下载之后解压 控制台应用程序下配置: 找到luc ...

  3. Python之使用eval()函数将字符串的数据结构提取出来

    data = input('请输入你要修改的对象:').strip() ''' 输入下面的字典列表 [{'backend':'www.oldboy1.org','record':{'server':' ...

  4. C语言学习8

    计算某日是该年的第几天 编写一个计算天数的程序,用户从键盘输入年.月.日,在屏幕中输出此日期是该年的第几天. /******************************************** ...

  5. 【分治】输出前k大的数

    描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入第一行包含一个整数n,表示数组的大小.n < 100000.第二行包含n个整数,表示数组的元素,整数之间以一个空格分开.每个整 ...

  6. Fiddler简介与Web抓包,远程抓包(IE、360、谷歌、火狐)

    Fiddler简介以及web抓包 一.Fiddler简介 简单来说,Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯.网上简介很多,我们不多说. 二 ...

  7. Java面向对象学习-----类的成员变量

    类的成员变量: 猜数字游戏:一个类A有一个成员变量v,通过随机产生一个100内的整数给v赋值.定义一个方法,对A类的成员变量v进行猜.   没有猜对的情况下提示如果大了则提示大了,小了则提示小了,并且 ...

  8. ORACLE数据库查看执行计划的方法

    一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等 ...

  9. noip模拟赛 分组

    分析:暴力分挺多,也挺好想的,个人感觉两个特殊性质没什么卵用. 对于K=1,n ≤ 1024的情况,从后往前贪心地分,如果能和上一组分在一起就分在一起,否则就再开一组,这样可以保证字典序最小.ai ≤ ...

  10. Django:(7)auth用户认证组件 & 中间件

    用户认证组件 用户认证组件: 功能:用session记录登陆验证状态 前提:用户表:django自带的auth_user 创建超级用户的命令: python manage.py createsuper ...