在java中的状态管理
Java应用程序在以下几种情况要求cookie操作:
● 网站交互:为了与网站交互,基于Internet的客户端应用程序经常扮演小型网络浏览器的角色。这些站点使用cookies进行状态管理以维护用户的会话数据。
● 网络服务实现:网络服务承诺使网络成为电脑机器的友好地方。一个都希望的允许机器-网站进行交互的方法就是在网站前面有一个网络服务。因此,网络服务将目标网站的视窗十分友好地呈现在机器面前。这种网络服务的实现将需要cookie操作以达到真正的网站交互。
● 网络浏览:基于网络浏览的Java将需要cookie操作模块以支持状态管理。
为了执行客户端cookie操作,先看下面几个步骤:
● 检索cookies:
1. 从收到的HTTP头提取cookies。
2. 分别解析cookies的组成部分(名称,值,路径等等)。
3. 判定主机是否允许设置这些cookies。
● 发送cookies:
1. 判定哪些cookies能被发送给主机。
2. 对于多个cookies,判定必须发送的cookies的顺序。
3. 与外发的HTTP头一起格式并发送cookies。
一个客户端Java应用程序须遵循上面的所有步骤,但是用RFC2965列出的规范执行上述步骤将消耗大量的时间并分散开发者在核心程序上的注意力。结果,开发者经常选择向规范妥协而用很容易就被破坏的随意编写的cookie操作代码结束。
例如,假设你想要写一个与网络商店应用程序的servlet交互的Java客户应用程序,在服务器端,当servlet第一次通过调用request.getsession()为一个会话询问servlet容器时,容器创建一个新的会话并且服务器用一个会话ID在并发请求时检索会话对象,服务器自动将这个会话ID作为一个HTTP cookie发送到客户端。在并发请求时,客户端与请求一起回送同一个会话ID。服务器用ID区别正确的会话对象以便servlet处理请求。典型的客户端代码如下:
/* 取得cookie.*/
...
HttpURLConnection hUC= (HttpURLConnection) url.openConnection();
...
InputStream is = huc.getInputStream();
// 从响应中检索会话ID.
String cookieVal = hc.getHeaderField("Set-Cookie");
String sessionId;
if(cookieVal != null)
{
sessionId = cookieVal.substring(0, cookieVal.indexOf(";"));
}
...
/* 发送cookie. */
HttpURLConnection huc= (HttpURLConnection) url.openConnection();
if(sessionId != null)
{
huc.setRequestPRoperty("Cookie", sessionId);
}
InputStream is = huc.getInputStream();
...
cookie规范RFC2965为cookies版本1定义了一个新报头,Set-Cookie2。假如我们用新报头升级服务器,上面的代码将不能履行。上述代码也不能处理多重cookies。另外,版本1的cookie值可以是一个加引号的字符串,假如会话cookie的值是一个包含分号的加引号字符串,这也将引起上述代码不能履行。简而言之,上面的代码片断不是与cookie的版本使用孤立开来的。
上述代码对于只和一个特别的主机及路径影射交互的简单程序是适合的,但对于一个更庞大的应用程序,当涉及多重主机及路径时cookie管理将变得更复杂。开发者实现cookie规范中的所有算法、安全检查及平衡将证明是痛苦和徒然的。
进入jCookie
为了减轻这种情形,我开发了一个普通用途cookie库,命名为jCookie,用来实现cookie规范。这个库使客户端cookie操作所必需的额外代码和努力最小化并让开发者的精力集中在核心应用程序上。其他APIs库也有(例如,Apache的HTTPClient),但是他们使用了从内建本地的java.net APIs移出的结构,因此需要一个新的学习过程。我的API是一个调用已存在的java.net对象的简单方法。
你也能使用现在发展的jCookie延伸版本,叫jCookieMicro,在J2ME移动设备上创建一套令人激动的能与网络服务应用程序交互的客户系统。
现在我介绍jCookie API的主要行为,先从两个主要数据结构开始:
1. Cookie类:此类的一个实例表明一个独立的cookie。它封装了RFC 2965定义的所有cookie属性并提供用getters和setters访问这些属性。
2. CookieJar类:此类的一个实例被作为一个Cookie对象集的容器。它符合集合结构并提供操作cookie集合的方法。
API提供两个视野以同时满足开发者对于cookie透明操作的要求及开发者对于高级特性的要求。下面的图形说明了这些视野或层。
jCookie库的分层视图
(出处:http://www.knowsky.com)