回到顶部


http状态管理

cookie是HTTP代理和目标服务器可以交流保持回话的状态信息的令牌或短包。
httpclient使用Cookie接口来代表抽象的cookie令牌,在它的简单形式中http的cookie是键/值对.
通常一个http的cookie也包含一些属性,比如版本号,合法的域名,指定cookie应用所在的源服务器url子集的路径,cookie的最长有效期
SetCookie接口代表源服务器发送给http代理的响应中的头部信息Set-Cookie来维持一个对话状态
SetCookie2接口和指定Set-Cookie2方法扩展了Set-Cookie
SetCookie接口和额外的如获取原始cookie属性的能力,就像他们由源服务器指定的客户端特定功能扩展了Cookie接口。
这对生成Cookie头部很重要,因为一些cookie规范需要
Cookie头部应该包含在Set-Cookie或Set-Cookie2头部指定的特定属性

cookie版本

Cookie兼容网景公司的草案标准,但是版本0被认为是不符合官方规范的。
符合标准的cookie的期望版本是1.
httpclient可以处理基于不同版本的cookie
​
BasicClientCookie netscapeCookie = new BasicClientCookie("name","value");
netscapeCookie.setVersion(0);
netscapeCookie.setDomain("127.0.0.1");
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");

cookie规范

CookieSpec接口代表了cookie管理的规范。
*) 解析Set-Cookie规则还有可选的Set-Cookie2头部信息
*) 验证解析cookie的规则
*) 格式化给定主机的Cookie头部信息,原始端口和路径
httpclient附带一些cookieSpec的实现
网景公司草案:这个规范符合由网景通讯发布的原始草案规范。应当避免,除非有绝对的必要去兼容遗留代码。
RFC2109:官方HTTP状态管理规范并取代的老版本,被RFC 2965取代。
RFC2965:官方HTTP状态管理规范。
浏览器兼容性:这个实现努力去密切模仿(mis)通用Web浏览器应用程序的实现。比如微软的Internet Explorer和Mozilla的FireFox浏览器。
最佳匹配:'Meta'(元)cookie规范采用了一些基于又HTTP响应发送的cookie格式的cookie策略。它基本上聚合了以上所有的实现到以一个类中。
 
建议使用best match策略,让httpclient在运行时基于执行上下文采用一些合适的兼容等级

cookie规范注册表

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

选择cookie策略

cookie策略可以在http客户端被设置,如果需要,在http请求级重写.
HttpClient httpclient = new DefaultHttpClient();
//对每个默认的强制严格cookie策略
httpclient.getParams().setPatameter(ClientPNames.COOKIE_POLICY,CookiePolicy,RFC_2965);
HttpGet httpget=new HttpGet("http://www.broken-server.com/");
//对这个请求覆盖默认策略
httpget.getParams().setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.BROWSER_COMPABILITY);

定制cookie策略

实现定制(自定义)cookie策略,我们应该创建CookieSpec接口的定制实现类
创建一个CookieSpecFactory实现来创建和初始化定制实现的实例并使用HttpClient注册这个工厂
​
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().reginster("easy",csf);
httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY,"easy");

cookie持久化

DefaultHttpClient httpClient = new DefaultHttpClient();
//创建一个本地cookie store实例
CookieStore cookieStore = new BasicCookieStore();
//如果需要填充cookie
BasicClientCookie cookie = new BasicClientCookie("name","value");
cookie.setVersion(0);
cookie.setDomain("127.0.0.1");
cookie.setPath("/");
cookieStore.addCookie(cookie);
//设置存储
httpclient.setCookieStore(cookieStore);
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);

每个用户/线程的状态管理
HttpClient httpclient = new DefaultHttpClient();
//创建cookie store的本地实例
CookieStore cookieStore = new BasicCookieStore();
//创建本地的http内容
HttpContext content = new BasicHttpContext();
//绑定定制cookie store到本地内容中
content.setAttribute(ClientContext.COOKIE_STORE,cookieStore);
HttpGet httpget = new HttpGet("http://www.baidu.com");
//作为参数传递本地内容
HttpResponse response = httpclient.execute(httpget,content);
posted on 2018-04-14 06:02  ssgao  阅读(327)  评论(0编辑  收藏  举报