原 始的HTTP是被设计为无状态的,面向请求/响应的协议,没有特殊规定有状态的,贯穿一些逻辑相关的请求/响应交换的会话。由于HTTP协议变得越来越普 及和受欢迎,越来越多的从前没有打算使用它的系统也开始为应用程序来使用它,比如作为电子商务应用程序的传输方式。因此,支持状态管理就变得非常必要了。
网 景公司,一度成为Web客户端和服务器软件开发者的领导方向,在它们基于专有规范的产品中实现了对HTTP状态管理的支持。之后,网景公司试图通过发布规 范草案来规范这种机制。它们的努力通过RFC标准跟踪促成了这些规范定义。然而,在很多应用程序中的状态管理仍然基于网景公司的草案而不兼容官方的规范。 很多主要的Web浏览器开发者觉得有必要保留那些极大促进标准片段应用程序的兼容性。
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头部中指定的特定属性。
这里有一个重新创建网景公司草案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");
HttpClient附带了一些CookieSpec的实现:
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);
CookieSpecFactory csf = new CookieSpecFactory() {public CookieSpec newInstance(HttpParams params) {return new BrowserCompatSpec() {@Overridepublic void validate(Cookie cookie, CookieOrigin origin)throws MalformedCookieException {// 这相当简单}};}};DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.getCookieSpecs().register("easy", csf);httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY, "easy");
DefaultHttpClient httpclient = new DefaultHttpClient();// 创建一个本地的cookie store实例CookieStore cookieStore = new MyCookieStore();// 如果需要填充cookieBasicClientCookie cookie = new BasicClientCookie("name", "value");cookie.setVersion(0);cookie.setDomain(".mycompany.com");cookie.setPath("/");cookieStore.addCookie(cookie);// 设置存储httpclient.setCookieStore(cookieStore);
本地的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 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)
原文:http://www.cnblogs.com/openlearn/p/5829612.html