zoukankan      html  css  js  c++  java
  • HTTP 状态管理

    一、HTTP 状态管理和执行上下文

    最初,HTTP是被设计成无状态的,面向请求-响应的协议。然而,现实世界中的应用程序经常需要通过一些逻辑相关的请求-响应交换来保持状态信息。 为了使应用程序能够维持一个过程状态, HttpClient允许HTTP请求在一个特定的执行上下文中来执行,称为HTTP上下文。其设计理念为:HttpContext->HttpCoreContext->HttpClientContext

    如果相同的上下文在连续请求之间重用,那么多种逻辑相关的请求可以参与到一个逻辑会话中。HTTP上下文功能和java.util.Map<String,Object>很相似。 它仅仅是任意命名参数值的集合。应用程序可以在请求之前填充上下文属性,也可以在执行完成之后来检查上下文属性。

    HttpContext能够包含任意的对象,因此在两个不同的线程中共享上下文是不安全的,建议每个线程都一个它自己执行的上下文。

    //创建HttpContext上下文
    HttpClientContext context = HttpClientContext.create();
    //在HttpContext上下文中执行请求
    CloseableHttpResponse response = httpClient.execute(httpPost, context);

    在HTTP请求执行的这一过程中, HttpClient添加了下列属性到执行上下文中:

    • HttpConnection实例代表连接到目标服务器的当前连接。
    • HttpHost实例代表连接到目标服务器的当前连接。
    • HttpRoute实例代表了完整的连接路由。
    • HttpRequest实例代表了当前的HTTP请求。最终的HttpRequest对象在执行上下文中总是准确代表了状态信息,因为它已经发送给了服务器。每个默认的HTTP/1.0 和 HTTP/1.1使用相对的请求URI,可是,请求以non-tunneling模式通过代理发送时,URI会是绝对的。
    • HttpResponse实例代表当前的HTTP响应。
    • java.lang.Boolean对象是一个标识,它标志着当前请求是否完整地传输给连接目标。
    • RequestConfig代表当前请求配置。
    • java.util.List<URI>对象代表一个含有执行请求过程中所有的重定向地址。

    你可以使用HttpClientContext适配器类来简化上下文状态的活动。代表一个逻辑相关的会话中的多个请求序列应该被同一个HttpContext实例执行,以确保请求之间会话上下文和状态信息的自动传输。即使使用同一个HttpContext上下文,HttpContext中的数据是共用的,当前正在执行的请求是可以获取上一个请求的数据中。

    /**
     * HttpClientContext 有以下的常用方法:
     *      setAttribute() 设置属性及值
     *      getAttribute() 获取指定的属性值
     *      setAuthCache() 
     *      getAuthCache()
     *      setUserToken()
     *      getUserToken()
     *      setAuthSchemeRegistry()
     *      getAuthSchemeRegistry()
     *      setCookieSpecRegistry()
     *      getCookieSpecRegistry()
     *      setCookieStore()
     *      getCookieStore()
     *      setTargetHost()
     *      getTargetHost()
     *      setCredentialsProvider()
     *      getCredentialsProvider
     *      setRequestConfig()
     *      getRequestConfig()
     *      getTargetAuthState()
     *      getCookieOrigin()
     *      getRedirectLocations()
     *      getProxyAuthState()
     *      getConnection()
     *      getHttpRoute()
     *      getCookieSpec()
     *      getRequest()
     *      getResponse()
     */

    二、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 头部中指定的特定属性。
    /**
     * 以下是与 HTTP cookies相关的一些接口或类
     * CookieSpec 接口, 代表cookie 管理的规范。RFC 2965 是官方 HTTP 状态管理规范。
     *      ClientPNames 已过时
     *      CookiePolicy 规范版本, API已过时
     *     CookieSpecs 枚举一些策略,可以调用 setCookieSpec()设置
     * CookieSpecFactory cookie 规范注册表, API已过时
     * CookieStore cookie持久化接口
     *      BasicCookieStore 实现类
     * BasicClientCookie
     * BasicClientCookie2
     */
    /**
     * 为客户端级别添加 Cookie
     */
    HttpClientBuilder httpClientBuilder = HttpClients.custom();
    CookieStore cookieStore = new BasicCookieStore();
    //name为cookie名称, value为cookie值
    BasicClientCookie stdCookie = new BasicClientCookie("name", "value");
    //cookie版本, 固定
    stdCookie.setVersion(1);
    //可以访问此cookie的域名
    stdCookie.setDomain("https://www.cnblogs.com");
    //访问此cookie的页面路径。 比如domain是abc.com, path是/test,那么只有/test路径下的页面可以读取此cookie。
    stdCookie.setPath("/");
    //是否只能通过https来传递此条cookie
    stdCookie.setSecure(true);
    // 精确设置由服务器发送的属性
    stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");
    stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, "https://www.cnblogs.com");
    //cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,
    //意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失
    stdCookie.setExpiryDate(new SimpleDateFormat("yyyy-MM-dd").parse("2020-10-01"));
    stdCookie.setCreationDate(new Date());
    cookieStore.addCookie(stdCookie);
    
    httpClientBuilder.setDefaultCookieStore(cookieStore);
    
    CloseableHttpClient httpClient = httpClientBuilder.build();
    /**
     * 也可以通过请求头添加 cookie
     */
    String cookieContent = new StringBuffer()
            .append("name=WeiDa;")
            .append("expires = Thu,01-Jan-2021 00:00:01 GMT;") //格林威治时间
            .append("domain = https://blog.csdn.net;")
            .append("secure;")
            .append("version = 1;").toString();
    Header cookieHeader = new BasicHeader("Cookie", cookieContent);
    httpPost.setHeader(cookieHeader);

    三、每个用户/线程的状态管理

    我们可以使用独立的本地执行上下文来实现对每个用户(或每个线程)状态的管理。定义在本地内容中的 cookie 规范注册表和 cookie 存储将会优先于设置在 HTTP 客户端级别中默认的那些。
     
    /**
     * 创建cookie store实例
     */
    CookieStore cookieStore = new BasicCookieStore();
    
    /**
     * 创建cookie实例
     */
    //name为cookie名称, value为cookie值
    BasicClientCookie stdCookie = new BasicClientCookie("name", "value");
    //cookie版本, 固定
    stdCookie.setVersion(1);
    //可以访问此cookie的域名
    stdCookie.setDomain("https://www.cnblogs.com");
    //访问此cookie的页面路径。 比如domain是abc.com, path是/test,那么只有/test路径下的页面可以读取此cookie。
    stdCookie.setPath("/");
    //是否只能通过https来传递此条cookie
    stdCookie.setSecure(true);
    // 精确设置由服务器发送的属性
    stdCookie.setAttribute(ClientCookie.VERSION_ATTR, "1");
    stdCookie.setAttribute(ClientCookie.DOMAIN_ATTR, "https://www.cnblogs.com");
    //cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,
    //意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失
    stdCookie.setExpiryDate(new SimpleDateFormat("yyyy-MM-dd").parse("2020-10-01"));
    stdCookie.setCreationDate(new Date());
    cookieStore.addCookie(stdCookie);
    
    /**
     * 创建执行上下文
     */
    HttpClientContext context = HttpClientContext.create();
    
    /**
     * 绑定定制的cookie store
     */
    context.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
    
    /**
     * 在执行上下文中执行请求
     */
    CloseableHttpResponse response = httpClient.execute(httpPost, context);
  • 相关阅读:
    php_sphinx安装使用
    获取数据库中所有表名
    总结thinkphp快捷查询getBy、getField、getFieldBy用法及场景
    打印机复印身份证方法
    svn 删除、移动和改名
    MySQL中REGEXP正则表达式使用大全
    高铁在高速运行时的电力是如何提供的?
    2016亚洲大学排名
    Mac下安装HBase及详解
    HBase Mac OSX 安装笔记
  • 原文地址:https://www.cnblogs.com/myitnews/p/12200379.html
Copyright © 2011-2022 走看看