九、HttpClient状态管理(cookie相关)

1.HTTP cookie

Cookie 是 HTTP 代理和目标服务器可以交流保持会话的状态信息的令牌或小的数据包。网景公司的工程师把它称为“魔法小甜饼”("magic cookie"),这个名字好像有粘性一样。

HttpClient 使用 Cookie 接口来代表抽象的 cookie 令牌。 HTTP中简单形式中的cookie是名/值对。 通常一个 HTTP 的 cookie 也包含一些属性,比如版本号,合法的域名,指定 cookie 应用所在的源服务器URL路径的子集, cookie 的最长有效时间。

SetCookie接口代表由源服务器发送给HTTP代理的响应中的首部Set-Cookie,它用来维持一个对话状态。

ClientCookie接口和它指定的方法扩展了Cookie。比如:能够取回被源服务器定义的原始cookie。这对生成 Cookie 首部很重要,因为一些 cookie规范需要Cookie 首部应该包含特定的属性,这些属性只能在 Set-Cookie 头部中指定。

 

下面是客户端创建cookie对象的例子:

BasicClientCookie cookie = new BasicClientCookie("name", "value");  
// Set effective domain and path attributes  
cookie.setDomain(".mycompany.com");  
cookie.setPath("/");  
// Set attributes exactly as sent by the server  
cookie.setAttribute(ClientCookie.PATH_ATTR, "/");  
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, ".mycompany.com");  

2.cookie详解

CookieSpec接口代表一个管理cookie的规范,cookie管理规范是强制的。

·解析Set-Cookie头部规则

·分析验证cookie规则

·用给定的主机名,端口号,和原路径格式化Cookie首部

 

HttpClient附带了几个CookieSpec的实现

Standard strict:State management policy compliant with the syntax and semantics of the wellbehaved profile defined by RFC 6265, section 4.  
  
Standard:State management policy compliant with a more relaxed profile defined by RFC  
6265, section 4 intended for interoperability with existing servers that do not conform to the well  
behaved profile.  
  
Netscape draft (obsolete):This policy conforms to the original draft specification published  
by Netscape Communications. It should be avoided unless absolutely necessary for compatibility  
with legacy code.  
  
RFC 2965 (obsolete):State management policy compliant with the obsolete state management  
specification defined by RFC 2965. Please do not use in new applications.--->已废弃  
  
RFC 2109 (obsolete):State management policy compliant with the obsolete state management  
specification defined by RFC 2109. Please do not use in new applications--->已废弃  
   
Browser compatibility (obsolete):This policy strives to closely mimic the (mis)behavior of  
older versions of browser applications such as Microsoft Internet Explorer and Mozilla FireFox.  
Please do not use in new applications.--->已废弃  
  
Default:Default cookie policy is a synthetic policy that picks up either RFC 2965, RFC 2109  
or Netscape draft compliant implementation based on properties of cookies sent with the HTTP  
 response (such as version attribute, now obsolete). This policy will be deprecated in favor of the  
 standard (RFC 6265 compliant) implementation in the next minor release of HttpClient.  
   
Ignore cookies:所有的cookie将会被忽略  

在新程序中,强烈建议使用Standard或Standard strict策略。废弃的规范仅应该使用在遗留项目中。下一个HttpClient版本将不会支持废弃的规范。

3.选择cookie策略

Cookie策略能够能够在HTTP客户端设置,如果需要的话,能够在HTTP请求中被重写(覆盖)。

RequestConfig globalConfig = RequestConfig.custom()  
    .setCookieSpec(CookieSpecs.DEFAULT)  
    .build();  
CloseableHttpClient httpclient = HttpClients.custom()  
    .setDefaultRequestConfig(globalConfig)  
    .build();  
RequestConfig localConfig = RequestConfig.copy(globalConfig)  
    .setCookieSpec(CookieSpecs.STANDARD_STRICT)  
.build();  
HttpGet httpGet = new HttpGet("/");  
httpGet.setConfig(localConfig); 

 

4.自定义cookie策略

为了实现自定义的cookie策略你必须创建一个CookieSpec的实现,创建一个CookieSpecProvider的实现,用它来创建和初始化自定义规范的实例、和HttpClient注册工厂。一旦自定义的规范被注册,它将会和标准cookie规范一样被使用。

PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.getDefault();  
Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider>create()  
   .register(CookieSpecs.DEFAULT,new DefaultCookieSpecProvider(publicSuffixMatcher))  
   .register(CookieSpecs.STANDARD,newRFC6265CookieSpecProvider(publicSuffixMatcher))  
   .register("easy", new EasySpecProvider())  
   .build();  
RequestConfig requestConfig = RequestConfig.custom()  
   .setCookieSpec("easy")  
   .build();  
   CloseableHttpClient httpclient = HttpClients.custom()  
   .setDefaultCookieSpecRegistry(r)  
   .setDefaultRequestConfig(requestConfig)  
   .build();  

5.Cookie 持久化

HttpClient能够使用任何实现了CookieStore接口的物理cookie。默认的CookieStore实现类被称为BasicCookieStore,它的内部是使用java.util.ArrayList的简单实现的。当容器进行垃圾回收时,储存在BasicClientCookie中的对象就会丢失。如果必要的话,使用者可以提供一个复杂的实现。

// Create a local instance of cookie store  
CookieStore cookieStore = new BasicCookieStore();  
// Populate cookies if needed  
BasicClientCookie cookie = new BasicClientCookie("name", "value");  
cookie.setDomain(".mycompany.com");  
cookie.setPath("/");  
cookieStore.addCookie(cookie);  
// Set the store  
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore)  
   .build();  

6.HTTP状态管理和执行上下文

在一个HTTP执行请求的过程中,HttpClient向执行上下文中添加了下面的状态管理对象

lLookup实例代表了真实的cookie详细记录,这个属性的值设置在本地上下文中,优先于默认的。

lCookieSpec实例代表了真实的cookie规范

lCookieOrigin实例代表了当前的原服务器的详情

lCookieStore实例代表了当前的cookie store,这个属性的值设置在本地上下文中而优先于默认的。

 

在请求执行之前,本地的HttpContext对象能够定制HTTP状态管理上下文,或者在请求执行后检查它的状态。你可以使用分离的上下文以便实现每个用户(或每个线程)的状态管理。cookie规范记录、cookie store定义在本地的上下文中优先于那些在HTTP客户端设置的默认的上下文。

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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值