`

HttpClient 教程 (三)

阅读更多
第三章 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兼容网景公司的草案标准,但是版本0被认为是不符合官方规范的。符合标准的cookie的期望版本是1。HttpClient可以处理基于不同版本的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规范

CookieSpec接口代表了cookie管理的规范。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策略。它基本上聚合了以上所有的实现到以一个类中。
强烈建议使用Best Match策略,让HttpClient在运行时基于执行上下文采用一些合适的兼容等级。
3.3 HTTP cookie和状态管理参数

这些是用于定制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规范注册表

HttpClient使用CookieSpecRegistry类维护一个可用的cookie规范注册表。下面的规范对于每个默认都是注册过的:
兼容性:浏览器兼容性(宽松策略)。
网景:网景公司草案。
rfc2109:RFC 2109(过时的严格策略)。
rfc2965:RFC 2965(严格策略的标准符合)。
best-match:最佳匹配meta(元)策略。
3.5 选择cookie策略

Cookie策略可以在HTTP客户端被设置,如果需要,在HTTP请求级重写。
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策略

为了实现定制cookie策略,我们应该创建CookieSpec接口的定制实现类,创建一个CookieSpecFactory实现来创建和初始化定制实现的实例并和HttpClient注册这个工厂。一旦定制实现被注册了,它可以和标准的cookie实现有相同的活性。
CookieSpecFactory csf = new CookieSpecFactory() {
public CookieSpec newInstance(HttpParams params) {
return new BrowserCompatSpec() {
@Override
public 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持久化

HttpClient可以和任意物理表示的实现了CookieStore接口的持久化cookie存储一起使用。默认的CookieStore实现称为BasicClientCookie,这是凭借java.util.ArrayList的一个简单实现。在BasicClientCookie对象中存储的cookie当容器对象被垃圾回收机制回收时会丢失。如果需要,用户可以提供更复杂的实现。
DefaultHttpClient httpclient = new DefaultHttpClient();
// 创建一个本地的cookie store实例
CookieStore cookieStore = new MyCookieStore();
// 如果需要填充cookie
BasicClientCookie cookie = new BasicClientCookie("name", "value");
cookie.setVersion(0);
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
// 设置存储
httpclient.setCookieStore(cookieStore);
3.8 HTTP状态管理和执行上下文

在HTTP请求执行的过程中,HttpClient添加了下列和状态管理相关的对象到执行上下文中:
'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 每个用户/线程的状态管理

我们可以使用独立的本地执行上下文来实现对每个用户(或每个线程)状态的管理。定义在本地内容中的cookie规范注册表和cookie存储将会优先于设置在HTTP客户端级别中默认的那些。
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)
1
8
分享到:
评论
1 楼 stone2oo6 2011-08-02  
这个系列介绍得比较到位,每篇都给你顶

相关推荐

    httpclient官网教程中文版

    ### Httpclient官网教程中文版知识点总结 #### 一、引言 HTTP协议作为互联网的核心通信标准之一,在现代网络服务及物联网设备中扮演着至关重要的角色。随着技术的发展,越来越多的应用和服务依赖于HTTP协议来实现...

    Httpclient教程

    ### Httpclient教程 #### 一、简介 在深入讲解如何使用`Httpclient`之前,我们首先需要了解`Httpclient`是什么以及它为何如此重要。`Httpclient`是Apache的一个开源项目,它提供了一套用于HTTP协议操作的客户端API...

    HttpClient 4.0中文教程

    ### HttpClient 4.0中文教程知识点总结 #### 一、HttpClient概述 **1.1 执行请求** - **HTTP请求**: HTTP请求包含了方法名称(GET、POST等)、URL以及必要的请求头信息。HttpClient允许开发者创建并发送这些请求...

    httpclient4中文教程.doc

    本教程将介绍HttpClient的基本概念和使用方法。 首先,HttpClient的核心功能是执行HTTP请求。通过创建HttpClient实例和指定的HTTP方法对象(如HttpGet、HttpPost等),可以向目标服务器发起请求并获取响应。以下是...

    HttpClient-4.0.1中文版官方教程

    ### HttpClient-4.0.1中文版官方教程 #### 第一章 基础 **1.1 执行请求** HttpClient 是 Apache 提供的一个用于发送 HTTP 请求和接收 HTTP 响应的强大工具包。它并不像浏览器那样具备完整网页渲染的能力,而是...

    HttpClient 4 官方教程中文翻译版

    ### HttpClient 4 官方教程中文翻译版知识点详解 #### 一、概述 Apache HttpClient 是一个用于Java应用程序的客户端HTTP组件。它旨在提供一个高效、最新且功能丰富的HTTP客户端编程框架,同时也支持HTTPS协议。...

    HttpClient4.3教程 PDF格式

    于是,便诞生了Apache HttpClient这样的第三方库,其主要目的是为了提供更为丰富和高效的HTTP客户端功能。 Apache HttpClient是一个开源的Java HTTP客户端库,主要用于执行HTTP方法,如GET、POST、PUT、DELETE等。...

    HttpClient4.3教程.PDF

    #### 三、HttpClient核心概念 ##### 3.1 请求执行 - **基本流程**:客户端创建HTTP请求对象,通过HttpClient发送给服务器;服务器处理请求后返回HTTP响应;客户端接收并处理响应。 - **示例代码**: ```java ...

    HttpClient 4.3教程.rar

    三、HttpClient基本使用 1. **创建HttpClient实例**:首先,需要创建一个HttpClient实例,可以通过HttpClients.custom().build()进行构建。 2. **设置请求**:使用HttpGet、HttpPost等类创建请求对象,设置URL、...

    Httpclient使用jar包三合一,基本使用方法

    HttpClient httpClient = new HttpClient(); PostMethod method = new PostMethod(str1); try { // 需要添加的header数据 List<Header> headers = new ArrayList<Header>(); headers.add(new ...

    HttpClient4.0.3教程文档

    ### HttpClient 4.0.3 教程知识点详解 #### 一、概述 **HttpClient** 是一个基于 Java 的浏览器模拟库,它为开发者提供了一种简单有效的方式来与 HTTP 服务器进行交互。本教程旨在帮助用户深入理解 HttpClient ...

    HttpClient-中文教程

    ### HttpClient-中文教程 #### 一、概述 **HttpClient** 是一个用于客户端的 HTTP 传输类库,并非浏览器。它的核心功能在于传输和接收 HTTP 消息,而不涉及缓存内容、执行 JavaScript 脚本、猜测内容类型或重新...

    HttpClient 教程

    ### HttpClient 教程知识点解析 #### 一、HttpClient与HttpCore概述 **HttpClient**是Apache组织下的一款开源库,主要用于Java应用中发送HTTP请求和处理响应。它提供了一种高效、灵活的方式,来构建和执行HTTP请求...

    HttpClient入门

    三、HttpClient基本使用步骤 1. **创建HttpClient实例**:首先,你需要创建一个HttpClient实例,可以使用`HttpClientBuilder`构建器来定制配置。 2. **构建HttpRequest对象**:根据需求创建HttpRequestBase的子类...

    HttpClient使用示例教程

    6. **可扩展的套接字工厂**:允许集成第三方解决方案。 7. **连接管理器**:用于多线程应用,可设置最大连接数和每个主机的最大连接数,以及自动关闭过期连接。 8. **Cookie处理**:自动处理Set-Cookie头,并支持...

    使用HttpClient异步请求数据

    但如果你仍然需要使用`HttpClient`,可以通过添加第三方依赖库来实现。 接下来,我们将探讨如何结合`AsyncTask`进行异步操作。`AsyncTask`是Android提供的一个轻量级的后台执行框架,它允许我们在后台线程执行耗时...

    HttpClient-4.0.1中文文档下载+官方教程

    ### HttpClient-4.0.1中文文档下载+官方教程知识点详解 #### 一、概述 **HttpClient** 是 Apache 提供的一个高效、功能丰富的 HTTP 客户端开发工具包,广泛应用于 Java 应用程序中进行 HTTP 请求处理。不同于普通...

    java HttpClient 发送GET请求和带有表单参数的POST请求教程例子

    #### 三、发送带表单参数的POST请求 发送带有表单参数的POST请求比GET请求稍微复杂一点。除了创建`HttpClient`和`HttpPost`对象外,还需要创建一个`List<NameValuePair>`来存储表单参数,然后将其封装到`...

Global site tag (gtag.js) - Google Analytics