HttpClient 教程 (三)
转自:http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2113246.html
第三章 HTTP状态管理
原始的HTTP是被设计为无状态的,面向请求/响应的协议,没有特殊规定有状态的,贯穿一些逻辑相关的请求/响应交换的会话。由于HTTP协议变得越来越普及和受欢迎,越来越多的从前没有打算使用它的系统也开始为应用程序来使用它,比如作为电子商务应用程序的传输方式。因此,支持状态管理就变得非常必要了。
网景公司,一度成为Web客户端和服务器软件开发者的领导方向,在它们基于专有规范的产品中实现了对HTTP状态管理的支持。之后,网景公司试图通过发布规范草案来规范这种机制。它们的努力通过RFC标准跟踪促成了这些规范定义。然而,在很多应用程序中的状态管理仍然基于网景公司的草案而不兼容官方的规范。很多主要的Web浏览器开发者觉得有必要保留那些极大促进标准片段应用程序的兼容性。
3.1 HTTP cookies
Cookie是HTTP代理和目标服务器可以交流保持会话的状态信息的令牌或短包。网景公司的工程师用它来指“魔法小甜饼”和粘住的名字。
HttpClient使用Cookie接口来代表抽象的cookie令牌。在它的简单形式中HTTP的cookie几乎是名/值对。通常一个HTTP的cookie也包含一些属性,比如版本号,合法的域名,指定cookie应用所在的源服务器URL子集的路径,cookie的最长有效时间。
SetCookie接口代表由源服务器发送给HTTP代理的响应中的头部信息Set-Cookie来维持一个对话状态。SetCookie2接口和指定的Set-Cookie2方法扩展了SetCookie。
SetCookie接口和额外的如获取原始cookie属性的能力,就像它们由源服务器指定的客户端特定功能扩展了Cookie接口。这对生成Cookie头部很重要,因为一些cookie规范需要。Cookie头部应该包含在Set-Cookie或Set-Cookie2头部中指定的特定属性。
3.1.1 Cookie版本
这里有一个重新创建网景公司草案cookie示例:
BasicClientCookie netscapeCookie = new BasicClientCookie("name", "value");netscapeCookie.setVersion(0);netscapeCookie.setDomain(".mycompany.com");netscapeCookie.setPath("/");
这是一个重新创建标准cookie的示例。要注意符合标准的cookie必须保留由源服务器发送的所有属性:
BasicClientCookie stdCookie = new BasicClientCookie("name", "value");stdCookie.setVersion(1);stdCookie.setDomain(".mycompany.com");stdCookie.setPath("/");stdCookie.setSecure(true);// 精确设置由服务器发送的属性stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");
这是一个重新创建Set-Cookie2兼容cookie的实例。要注意符合标准的cookie必须保留由源服务器发送的所有属性:
BasicClientCookie2 stdCookie = new BasicClientCookie2("name", "value");stdCookie.setVersion(1);stdCookie.setDomain(".mycompany.com");stdCookie.setPorts(new int[] {80,8080});stdCookie.setPath("/");stdCookie.setSecure(true);// 精确设置由服务器发送的属性stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");stdCookie.setAttribute(ClientCookie.PORT_ATTR, "80,8080");
3.2 Cookie规范
- 解析的Set-Cookie规则还有可选的Set-Cookie2头部信息。
- 验证解析cookie的规则。
- 格式化给定主机的Cookie头部信息,原始端口和路径。
HttpClient附带了一些CookieSpec的实现:
- 网景公司草案:这个规范符合由网景通讯发布的原始草案规范。应当避免,除非有绝对的必要去兼容遗留代码。
- RFC 2109:官方HTTP状态管理规范并取代的老版本,被RFC 2965取代。
- RFC 2965:官方HTTP状态管理规范。
- 浏览器兼容性:这个实现努力去密切模仿(mis)通用Web浏览器应用程序的实现。比如微软的Internet Explorer和Mozilla的FireFox浏览器。
- 最佳匹配:’Meta’(元)cookie规范采用了一些基于又HTTP响应发送的cookie格式的cookie策略。它基本上聚合了以上所有的实现到以一个类中。
3.3 HTTP cookie和状态管理参数
- 'http.protocol.cookie-datepatterns':定义了用于解析非标准的expires属性的合法日期格式。只是对兼容不符合规定的,仍然使用网景公司草案定义的expires而不使用标准的max-age属性服务器需要。这个参数期望得到一个java.util.Collection类型的值。集合元素必须是java.lang.String类型,来兼容java.text.SimpleDateFormat的语法。如果这个参数没有被设置,那么默认的选择就是CookieSpec实现规范的值。要注意这个参数的应用。
- 'http.protocol.single-cookie-header':定义了是否cookie应该强制到一个独立的Cookie请求头部信息中。否则,每个cookie就被当作分离的Cookie头部信息来格式化。这个参数期望得到一个java.lang.Boolean类型的值。如果这个参数没有被设置,那么默认的选择就是CookieSpec实现规范的值。要注意这个参数仅仅严格应用于cookie规范(RFC 2109和RFC 2965)。浏览器兼容性和网景公司草案策略将会放置所有的cookie到一个请求头部信息中。
- 'http.protocol.cookie-policy':定义了用于HTTP状态管理的cookie规范的名字。这个参数期望得到一个java.lang.String类型的值。如果这个参数没有被设置,那么合法的日期格式就是CookieSpec实现规范的值。
3.4 Cookie规范注册表
- 兼容性:浏览器兼容性(宽松策略)。
- 网景:网景公司草案。
- rfc2109:RFC 2109(过时的严格策略)。
- rfc2965:RFC 2965(严格策略的标准符合)。
- best-match:最佳匹配meta(元)策略。
3.5 选择cookie策略
HttpClient httpclient = new DefaultHttpClient();// 对每个默认的强制严格cookie策略httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965);HttpGet httpget = new HttpGet("http://www.broken-server.com/");// 对这个请求覆盖默认策略httpget.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
3.6 定制cookie策略
CookieSpecFactory csf = new CookieSpecFactory() {public CookieSpec newInstance(HttpParams params) {return new BrowserCompatSpec() {@Overridepublic void validate(Cookie cookie, CookieOrigin origin)throws MalformedCookieException {// 这相当简单}};}};DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.getCookieSpecs().register("easy", csf);httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, "easy");
3.7 Cookie持久化
DefaultHttpClient httpclient = new DefaultHttpClient();// 创建一个本地的cookie store实例CookieStore cookieStore = new MyCookieStore();// 如果需要填充cookieBasicClientCookie cookie = new BasicClientCookie("name", "value");cookie.setVersion(0);cookie.setDomain(".mycompany.com");cookie.setPath("/");cookieStore.addCookie(cookie);// 设置存储httpclient.setCookieStore(cookieStore);
3.8 HTTP状态管理和执行上下文
- 'http.cookiespec-registry':CookieSpecRegistry实例代表了实际的cookie规范注册表。这个属性的值设置在本地内容中,优先于默认的。
- 'http.cookie-spec':CookieSpec实例代表真实的cookie规范。
- 'http.cookie-origin':CookieOrigin实例代表了真实的源服务器的详细信息。
- 'http.cookie-store':CookieStore实例代表了真实的cookie存储。设置在本地内容中的这个属性的值优先于默认的。
本地的HttpContext对象可以被用来定制HTTP状态管理内容,先于请求执行或在请求执行之后检查它的状态:
HttpClient httpclient = new DefaultHttpClient();HttpContext localContext = new BasicHttpContext();HttpGet httpget = new HttpGet("http://localhost:8080/");HttpResponse response = httpclient.execute(httpget, localContext);CookieOrigin cookieOrigin = (CookieOrigin) localContext.getAttribute(ClientContext.COOKIE_ORIGIN);System.out.println("Cookie origin: " + cookieOrigin);CookieSpec cookieSpec = (CookieSpec) localContext.getAttribute(ClientContext.COOKIE_SPEC);System.out.println("Cookie spec used: " + cookieSpec);
3.9 每个用户/线程的状态管理
HttpClient httpclient = new DefaultHttpClient();// 创建cookie store的本地实例CookieStore cookieStore = new BasicCookieStore();// 创建本地的HTTP内容HttpContext localContext = new BasicHttpContext();// 绑定定制的cookie store到本地内容中localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);HttpGet httpget = new HttpGet("http://www.google.com/");// 作为参数传递本地内容HttpResponse response = httpclient.execute(httpget, localContext)
HttpClient 教程 (三)的更多相关文章
- HttpClient 教程 (一)
转自:http://www.cnblogs.com/loveyakamoz/archive/2011/07/21/2112804.html HttpClient 教程 (一) 前言 超文本传输协议 ...
- CRL快速开发框架系列教程三(更新数据)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)
前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...
- 无废话ExtJs 入门教程三[窗体:Window组件]
无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...
- CocoStudio教程三:认识并利用CocoStudio的果实 运行2.2.1版本
原文:CocoStudio教程三:认识并利用CocoStudio的果实 原文用的老版,用2.21搞起来好像有些问题,然后自己摸索了下,有的都是乱找的方法,只求能运行... 1,原文的CCJsonRea ...
- Android Studio系列教程三--快捷键
Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...
- Laravel教程 三:视图变量传递和Blade
Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...
- NGUI系列教程三
接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...
- 中文翻译:pjsip教程(三)之ICE stream transport的使用
1:pjsip教程(一)之PJNATH简介 2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介 3:pjsip教程(三)之ICE ...
随机推荐
- Knockout.js 数据验证之插件版和无插件版
本文我们将介绍使用 Knockout.js 实现一些基本的数据验证.就如我们在标题里提到的,我们会使用两种方法来创建数据验证方法. 使用自定义方法,不需要任何插件 最简单的方法是使用已有的插件 如果你 ...
- 理解SVG的图形填充规则
SVG的图形填充规则通过fill-rule属性来指定. 有效值: nonzero | evenodd | inherit 默认值: nonzero fill-rule属性用于指定使用哪一种算法 ...
- 学习KNN
转:© 著作权归作者所有 by ido 什么是KNN算法呢?顾名思义,就是K-Nearest neighbors Algorithms的简称.我们可能都知道最近邻算法,它就是KNN算法在k=1时的特例 ...
- 数据挖掘之权重计算(PageRank)
刘 勇 Email:lyssym@sina.com 简介 鉴于在Web抓取服务和文本挖掘之句子向量中对权重值的计算需要,本文基于MapReduce计算模型实现了PageRank算法.为验证本文算法 ...
- Mysql 5.7 从节点配置多线程主从复制
Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有一个线 ...
- tomcat使用方法大全
一.安装tomcat之后 tomcat压缩包解压之后,进入webapps目录,可以看到如下webapp: docs文档:这是一个静态页面集,不用启动tomcat也可以阅读 examples样例 hos ...
- Hibernate 、 Axis2发布
1. you just compile your web-service into aar file (not include bean files), copy the aar into axis2 ...
- 苹果越狱后必备软件,总有你需要的!11月23日追加14个,支持【iOS4】
http://bbs.dospy.com/thread-7398730-1-301-2.html越狱后必备软件,总有你需要的!11月23日追加14个,支持[iOS4] 背景自定义插件
- WSDL格式
http://www.blogjava.net/charles/archive/2008/12/15/246368.html最近写Web service, 很多代码是用工具生成的,可以说只知其然,不知 ...
- 奇葩属性:layout_weight 的解释及使用
在Android的控件布局中,有一个奇葩的 layout_weight 属性,定义如下: layout_weight : 用于指定剩余空闲空间的分割比例.用法: 01 <LinearLayout ...