`

HttpClient4.5.2 Http状态管理

阅读更多

原文链接:http://www.yeetrack.com/?p=822

 

最初,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所有属性。

    BasicClientCookie stdCookie = new BasicClientCookie("name", "value");
    stdCookie.setVersion(1);
    stdCookie.setDomain(".yeetrack.com");
    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");

下面的代码,创建了Set-Cookie2兼容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-4.5.2.jar.zip

    《HttpClient 4.5.2:HTTP 客户端库的深度解析》 在Java开发中,HttpClient是一个不可或缺的工具,它提供了强大的功能,用于执行HTTP请求并处理响应。HttpClient 4.5.2是这个库的一个稳定版本,带来了诸多改进和...

    HttpClient4.5.2

    6. **Cookie管理**:HttpClient提供了`CookieStore`和`CookiePolicy`,用于处理服务器返回的cookies,支持保持会话状态。 7. **实体处理**:HttpClient可以处理不同类型的请求和响应实体,包括文本、XML、JSON等。`...

    httpclient-4.5.2.jar安卓网络请求

    可以将`httpclient4.5.2.jar`文件导入到项目的libs目录下,然后在`build.gradle`文件中添加如下代码: ```groovy dependencies { implementation files('libs/httpclient4.5.2.jar') } ``` 2. 创建HttpClient实例:...

    HTTPClient4.5.2

    `HTTPClient 4.5.2` 是一个广泛使用的Java库,它提供了用于执行HTTP和HTTPS请求的强大功能。这个版本是Apache HttpClient项目的一部分,致力于提供高效、灵活且可扩展的HTTP客户端实现。在本文中,我们将深入探讨这...

    httpcomponents-client-4.5.2-src

    总的来说,HttpClient 4.5.2 是一个强大且灵活的 HTTP 客户端库,它的源码分析可以帮助我们理解 HTTP 请求的处理流程,学习网络编程的最佳实践,同时也可以根据实际需求对其进行定制和优化。深入研究 HttpClient 的...

    httpclient和httpmime的jar包

    HttpClient 4.5.2是该库的一个稳定版本,修复了之前版本的一些问题,并增加了新的特性。 2. **HttpMime模块**: 这个模块专门设计用于处理MIME类型的数据,如在HTTP请求中常见的multipart/form-data格式。在Web表单...

    HttpClient 4.52

    - HttpClient 4.5.2引入了连接池管理器,如`PoolingHttpClientConnectionManager`,用于复用HTTP连接,提高性能。 - 可以设置连接池的大小、超时时间等参数。 5. **认证与安全** - 支持多种认证机制,如Basic、...

    httpcomponents-client-4.5.2-bin.tar.gz

    以上代码创建了一个默认的HttpClient实例,发起一个GET请求到指定URL,并打印出响应状态行,最后关闭连接。 总之,Apache HttpClient是Java开发者进行HTTP通信的首选工具,尽管其非标准库的身份可能导致导入问题,...

    httpclient-log4g相关jar包

    在Java项目中,同时使用HTTPClient和Log4j时,开发者可以通过Log4j记录HTTP请求的详细信息,如请求URL、方法、参数、响应状态码等,这对于调试和监控系统的行为非常有帮助。例如,当发生网络问题或API调用失败时,...

    httpclient.jar

    1. **连接管理**:HttpClient 4.5.2引入了更先进的连接管理策略,如连接池,可以有效地复用TCP连接,减少建立新连接的开销,提高性能。 2. **异步处理**:支持非阻塞I/O和异步操作,适合于高并发场景,通过回调机制...

    httpcomponents-client-4.5.2

    在Android开发中,HTTPComponents Client 4.5.2可以作为替代原生HttpURLConnection的选择,特别是在处理复杂网络请求、保持连接状态或者需要高并发性能时。它提供了更强大、更灵活的API,使得开发者能够更好地控制...

    org.apache.http相关jar包下载(httpcomponents-client-4.2.5-bin.tar)

    1. **httpclient.jar**: 这是核心的HttpClient实现,提供了HTTP协议的客户端实现,包括GET、POST等请求方法,以及处理重定向、cookies和HTTP连接管理等功能。 2. **httpcore.jar**: 这是HttpClient的基础,包含了...

    java爬虫http包.zip

    6. **HttpClient Context**:存储请求上下文信息,如认证、重定向策略、连接管理器等,方便在不同请求之间共享状态。 使用这两个库,开发者可以轻松地构建一个功能完备的Java网络爬虫。例如,可以使用HttpClient...

    java连接clickhouse相关驱动包

    3. httpclient-4.5.2.jar:Apache HttpClient库,提供了HTTP客户端实现,Java驱动可能通过HTTP协议与ClickHouse服务器通信。 4. joda-time-2.9.9.jar:Joda-Time是一个替代Java默认日期时间库的优秀选择,可能在...

    .net Core 使用IHttpClientFactory请求实现

    导读:本文已添加在 晨曦微服务之旅 ,现在自己在尝试微服务架构,一边学边做项目快速的进入状态。当然在学习的过程中会将自己学到的知识进行分享。 一、为什么不用HttpClient  1.HttPClient使用完之后不会立即...

    开涛高可用高并发-亿级流量核心技术

    12.2.1 HttpClient 4.5.2配置 236 12.2.2 HttpClient连接池源码分析 240 12.2.3 HttpClient 4.2.3配置 241 12.2.4 问题示例 243 12.3 线程池 244 12.3.1 Java线程池 245 12.3.2 Tomcat线程池配置 248 13 异步并发...

    elasticsearch8.2.2+ik8.2.2+kibnana8.2.2 检索必须组件下载

    - `httpclient-4.5.2.jar` 和 `httpcore-4.4.4.jar` 是Apache HTTP客户端库,用于网络通信,支持HTTP/1.1协议。 - `commons-codec-1.9.jar` 提供了各种编码算法,如Base64和Hex编码,是网络通信和数据处理的基础...

    OPhone应用开发权威指南(黄晓庆)

    9.3.1 HttpClient API介绍 373 9.3.2 GET方法的使用和限制 378 9.3.3 使用POST方法上传附件 382 9.3.4 从服务器端下载图片 390 9.4 设计C/S通信数据格式 392 9.4.1 对象序列化 396 9.4.2 使用XML传输对象 401 9.5 小...

    Android开发案例驱动教程 配套代码

    4.5.2 图片文本菜单 59 本章小结 60 第5章 UI基础控件 61 5.1 按钮 61 5.1.1 Button 62 5.1.2 ImageButton 63 5.1.3 ToggleButton 64 5.2 TextView 64 5.3 EditText 65 5.4 RadioButton和RadioGroup 66 ...

    Android 开发技巧

    4.5.2、menu实现的两种方法 58 4.5.3、自定义MENU背景 62 4.5.4、触发menu 64 4.5.5、Context Menu和Options Menu菜单的区别 64 4.5.6、Context menus for expandable lists 64 4.6、LISTVIEW 66 4.6.1、ListView...

Global site tag (gtag.js) - Google Analytics