摘要

客户端HTTP状态管理对于创建需要与象基于网络浏览器的email或在线银行服务网络程序交互作用的Java应用程序是十分重要的。本文介绍了在Java中一个强大易用的客户端HTTP状态管理cookie库,这个库在固有的java.net工具箱中很少见。其中存在几种客户端HTTP状态管理APIs,它们提供了难于学习并没必要重新开发设计的函数方法。这篇文章中Cookie管理库尽量使用核心Java API类。

当在开发一个针对所有主要的internet邮件服务器(基于Web或其他类型)提供单点访问的通用邮件客户端时,我发现我的应用程序经常不得不作为一个小的网络浏览器与提供邮件服务的网站交互。 当开发XML网络服务以便于机器更容易访问网站时我总在需要网站交互时遇到困难。这些网站经常使用cookies进行状态管理及维护用户会话数据,在这两种情况,我意识到多数网站交互都涉及cookie操作。我也注意到虽然两种情况下的应用程序都执行cookie操作,但其逻辑处理较困难及不具有互换性。针对此限制,我从开发一个小型普通用途库出发致力于cookie操作。在这篇文章中我将与你分享这个库。

为了在运行中图解说明库,我建议使用基于Hotmail邮件检测器的控制台。此外,我从在J2ME平台上使用MIDP的移动设备观点探究了客户端状态管理。

Cookie基础

让我们从回答一些问题开始:

什么是状态管理,为什么我们需要它?

什么是cookies,它们怎样适应图片?

要回答第一个问题,我们必须更精密地检测一下HTTP。HTTP是无国界协议,因为从网络服务器观点看所有HTTP请求都独立于先前请求。就是说每一个HTTP响应完全依赖于相应请求中包含的信息。当这种行为使网络服务执行更简单有效时,用它作为复杂网络应用的基础将更为合适。

状态管理机制克服了HTTP的一些限制并允许网络客户端及服务器端维护请求间的关系。在这种关系维持的期间叫做会话(session)。多数要求你登录的网络应用程序使用了会话及状态管理。购物推车应用程序使用状态管理控制所有标记为已购买项目的列表。状态管理能够使个别用户参数的入口及搜索引擎个性化定制。网络应用程序甚至能使用状态管理根据用户爱好兴趣定制网站内容。

Cookies影响着状态管理。Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。 是通用cookie规范。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将到同一服务器的任何请求缚上这些cookies。在这篇文章后面,我同义性地使用了cookie操作和状态管理术语。

如果你要找出你访问的哪个网站使用了cookies,可以试试这个简单的试验:

注意: 只有当你觉得改变你的浏览器设置没什么问题并知道方法时才执行这个练习。

● 打开你常用的浏览器,我假设你使用的是Internet Explorer (IE) 5+或Netscape Navigator 4+。

● 使自动cookie操作无效:

在IE浏览器的“工具”菜单中选择“Internet选项”,再选择“安全”标签,单击“自定义级别”然后向下拉动滚条直到你看见“允许使用存储在你计算机上的cookies”并选中“提示”选项,同时也选中“允许使用每个对话cookies(未存储)”的“提示”选项,单击“确定”按钮回到主窗口。

在Netscape Navigator的“编辑”菜单中选择“参数选择”中的“高级”,选中“接收cookie时警告”,单击“确定”按钮回到主窗口。

● 现在浏览你“收藏”中的站点,特别是当你检查你的网络邮件或进入在线电子商店时,要求你允许接收cookies的对话框会不断地向你轰来。

将上面的步骤恢复到你以前的初始设置,你也能看见哪些cookies被保存到了你的本地机器上(在警告应用之前):

● 对于IE:使用“Windows资源管理器”或“我的电脑”浏览C:\Windows\Cookies文件夹,在这个文件夹中的所有文本文件都包含cookies。

● 对于Netscape Navigator:

在Windows系统中,使用“Windows资源管理器”或“我的电脑”浏览C:\Program Files\Netscape\Users文件夹,找到一个名叫“cookies.txt”的文件或“cookies”子目录。

在Unix类似系统中,在“.netscape”目录中找到一个名叫“cookies”的文件。

注意: 根据你安装的系统不同,使自动cookie操作无效及查看保存的cookies的步骤也可能不同。

现在你已经知道了一些基本知识,接下来我将阐述怎样将这些与Java联系起来。

在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库的分层视图

jCookie结构

下面我将描述层及他们使用的不同的类。

层1

那些开发者多数都想进行透明cookie操作,这通常是使用层1的情形。在这个级别,你用Client类操作cookies。它有两个主要的方法:

· public CookieJar getCookies(URLConnection urlConn): 这个方法从给出的URLConnection中析取cookies,将它们解析到Cookie对象,并作为一个CookieJar返回。

· public CookieJar setCookies(URLConnection urlConn, CookieJar cj):这个方法从CookieJar中提取合适的Cookie对象并设置URLConnection的报头。

层0

这些开发者没有在使用层0的代码中深入就无法呼吸(包括我)。在这里,你可以通过使用cookie操作代码改变解析逻辑和安全规则。要这样做,首先实现CookieParser接口,它有以下四个方法:

· public Header getCookieHeaders(CookieJar cj):在CookieJar中转换Cookies为一报头以适合与一个HTTP请求一起发送。

· public boolean allowedCookie(Cookie c, URL url): 检查是否一个给出URL的请求能返回指定的Cookie。

· public CookieJar parseCookies(Header h, URL url):在一个HTTP响应中将报头转换到一个Cookie对象的CookieJar中。

· public boolean sendCookieWithURL(Cookie c, URL url, boolean bRespectExpires): 检查是否给出的Cookie能被与给出URL的一个请求一起发送。

你能使用Client类的setCookieParser(CookieParser cp)方法去设置CookieParser实现。被库缺省使用的CookieParser是一个RFC 2965 cookie规范中的实现。

在层1,jCookie作为一个库;在层0,它成为一个API的基础。

jCookie用法

Client类在两个层都调用cookie操作逻辑。它提供了应用程序开发者的库架构。要使用jCookie库,按照下面这些步骤:

· 从响应到请求检索cookies:

创建一个URLConnection对象并初始化。

连接URLConnection。

创建一个Client对象并设定一个定制的CookieParser。

通过调用Client实例的getCookies()方法得到一个Cookies的CookieJar,作为在URLConnection中的一个参数。

与HTTP响应一起作一些事情。

· 和一个请求(假定一个CookieJar已被检索)一起发送cookies:

创建一个URLConnection对象并初始化。

创建一个Client对象并设定一个定制的CookieParser。

通过调用Client实例的setCookies()方法设置cookie报头,作为URLConnection and CookieJar 中的参数。

连接URLConnection。

与HTTP响应一起作一些事情。

下面的摘录显示了普通jCookie的用法。这个jCookie代码十分突出:

import com.sonalb.net.http.cookie.*;

import java.net.*;

import java.io.*;

...

public class Example

{

...

public void someMethod()

{

...

URL url = new URL("");

HttpURLConnection huc = (HttpURLConnection) url.openConnection();

//在这里初始化HttpURLConnection.

...

huc.connect();

InputStream is = huc.getInputStream();

Client client = new Client();

CookieJar cj = client.getCookies(huc);

//进行一些处理

...

huc.disconnect();

// 执行另一请求

url = new URL("");

huc = (HttpURLConnection) url.openConnection();

client.setCookies(huc, cj);

huc.connect();

...

// 进行一些处理

}

}

上面的代码描述了jCookie API的两个方面:

· 本地java.net对象的使用(HttpURLConnection)。

· 轻易地回收和发送cookies(单个方法调用)。

在实践中,上述代码已经能成功地维护两个请求间的会话。现在我们转换层的基本结构,让我们将jCookie与一些真实代码连接。

Hotmail新邮件检测器

为了阐明jCookie库的使用方便,我将在一个显示一个Hotmail账号新消息的发件人、主题及日期字段的应用程序中使用它。为了简单起见,应用程序在控制台显示这些信息。为了在Hotmail收件箱接收新消息,应用程序需要完成以下步骤:

· 在登录表单中执行一个HTTP POST操作登录Hotmail。

· 为了到达主页,操作重定向及cookies。

· 检索收件箱的HTML页。

· 提取新消息的相关字段。

多数站点要求用户第一次通过一个表单执行一个HTTP POST 操作以完成登录过程。为了成功鉴定身份,POST的响应通常是一个带一些cookie报头的HTTP重定向。当重定向页被请求时cookies返回给服务器。

jCookie库包括一个很有用的类叫HTTPRedirectHandler,它管理当完成客户端cookie操作时操作重定向的普通任务。要使用这个类,首先要在一个未连接的HttpURLConnection中创建一个HTTPRedirectHandler实例,然后调用HTTPRedirectHandler实例的connect()方法去操作重定向及cookie。句柄从HTTP响应代码中确定是否运行成功。一旦进程完成,调用的类就检索表明最后一次请求的HttpURLConnection对象。CookieJar包含所有在能被检索的重定向过程中接收的cookies。Cookie操作逻辑存在于HTTPRedirectHandler的connect()方法中。让我们来看一看这个方法的代码。Cookie操作部份进行了注释:

package com.sonalb.net.http;

import com.sonalb.net.http.cookie.*;

import java.net.*;

import java.io.*;

public class HTTPRedirectHandler

{

...

public HTTPRedirectHandler(HttpURLConnection huc)

{

...

}

public void connect() throws IOException

{

if(bConnected)

{

throw new IllegalStateException("No can do. Already connected.");

}

int code;

URL url;

huc.setFollowRedirects(false);

// 设置在Cookies中的检验

if(!cj.isEmpty())

{

client.setCookies(huc,cj);

}

is = huc.getInputStream();

// 从HttpURLConnection中提取Cookies并加到CookieJar中去

cj.addAll(Client.getCookies(huc));

while((code = huc.getResponseCode()) != successCode && maxRedirects > 0)

{

if(code != 302)

{

throw new IOException("Can't deal with this code (" + code + ").");

}

is.close();

is = null;

url = new URL(huc.getHeaderField("location"));

huc.disconnect();

huc = null;

huc = (HttpURLConnection) url.openConnection();

//和HTTP请求一起发送Cookies

Client.setCookies(huc, cj);

huc.setFollowRedirects(false);

huc.connect();

is = huc.getInputStream();

//从响应中提取Cookies并加进jar中去

cj.addAll(Client.getCookies(huc));

maxRedirects--;

}

if(maxRedirects <= 0 && code != successCode)

{

throw new IOException("Max redirects exhausted.");

}

bConnected = true;

}

//其他方法在这里出现

public void handleCookies(boolean b)

{

...

}

public void setSuccessCode(int i)

{

...

}

public void setCookieJar(CookieJar cj)

{

...

}

public void addCookies(CookieJar cj)

{

...

}

public CookieJar getCookieJar()

{

...

}

public HttpURLConnection getConnection()

{

...

}

public void setMaxRedirects(int i)

{

...

}

}

HotmailChecker应用程序使用HTTPRedirectHandler进行登录操作。应用程序从使用带有并发请求的HTTPRedirectHandler中检索CookieJar。HotmailChecker的相关部份显示如下。Hotmail细节和jCookie关联注释被突出显示:

public boolean doLogin() throws Exception

{

//对于HTTPS初始化JSSE

System.getProperties().put("java.protocol.handler.pkgs","com.sun.net.ssl.internal.");

java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

//创建HttpURLConnection并初始化

URL url = new URL("");

HttpURLConnection huc = (HttpURLConnection) url.openConnection();

huc.setDoOutput(true);

huc.setRequestMethod("POST");

huc.setRequestProperty("User-Agent","Mozilla/4.7 [en] (Win98; I)");

//发送登录表单字段

StringBuffer sb = new StringBuffer();

sb.append("login="); sb.append(URLEncoder.encode(user));

...

OutputStream os = huc.getOutputStream();

os.write(sb.toString().getBytes("US-ASCII"));

os.close();

//创建句柄并进行处理

HTTPRedirectHandler hrh = new HTTPRedirectHandler(huc);

hrh.connect();

huc = hrh.getConnection();

//Microsoft有一个中间过渡页使用了一个刷新元标签以便于在HTTPS和HTTP间转换,这将防止安全

//警告弹出

//我们需要通过读取响应和解析URL手动取出URL

BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream()));

...

//一旦我们有了主页的URL,我们就又使用HTTPRedirectHandler重定向并处理响应以校验正确的注

//册

url = new URL(homeUrl);

huc = (HttpURLConnection) url.openConnection();

huc.setRequestProperty("User-Agent","Mozilla/4.7 [en] (Win98; I)");

hrh = new HTTPRedirectHandler(huc);

hrh.setCookieJar(cj);

hrh.connect();

...

//保存Cookies用于以后的请求

cj.addAll(hrh.getCookieJar());

...

return(bLoggedIn);

}

现在我们已经登录到Hotmail,我们请求收件箱页,在登录过程中已检索的Cookies中通过。一旦我们拥有了收件箱页,我们必须因为与新消息有关的信息而解析这个HTML。代替使用暴力的StringTokenizer检索这个信息,我们将用一个稍微文雅(既复杂的)方法调控XML。这种方法包括:

· 将成形不好的HTML转换为well-formed HTML。

· 用DOM(文档对象模型)通过well-formed HTML去得到新消息的信息。

假如DOM、XML和well-formed 对你来说一窍不通,只要说我们把收件箱HTML转换成一个树状结构的对象并得到想要的信息就足够了。

要将成形不好的HTML转换成well-formed HTML,我们用一个可自由下载的组件JTidy工具和一个通用的处理器。ConvertBadHTMLToGood帮助类将成形不好的Hotmail HTML转换成well-formed HTML。相关代码显示如下:

import java.io.*;

import org.w3c.tidy.*;

public class ConvertBadHTMLToGood

{

...

public ConvertBadHTMLToGood(Reader r)

{

if(r == null)

{

throw new IllegalArgumentException();

}

inReader = r;

}

public Reader doConvert() throws IOException

{

//初始化JTidy对象

Tidy tidy = new Tidy();

tidy.setXmlOut(true);

tidy.setErrout(new PrintWriter(new StringWriter()));

//JTidy解析器要求一个InputStream,对于我的知识来说这里没有直接的办法将一个Reader转换

//成一个InputStream。这个工作区代码没有字符编码安全,但还可以混过。

BufferedReader br = new BufferedReader(inReader);

StringBuffer sb = new StringBuffer();

String line;

while((line = br.readLine()) != null)

{

sb.append(line);

sb.append("\n");

}

ByteArrayInputStream bais = new ByteArrayInputStream(sb.toString().getBytes("US-ASCII"));

ByteArrayOutputStream baos = new ByteArrayOutputStream();

//作一个将HTML转换well-formed HTML 的预备。

tidy.parse(bais, baos);

//整理一些遗漏的JTidy得到能被“true-blue”XML解析器解析的输出。

FixEntities fe = new FixEntities(baos.toString());

return(fe.getFixedReader());

}

一旦我们拥有了well-formed HTML,我们就用XML解析的Java API(JAXP)去转换well-formed HTML 成一个DOM树并通过树得到新消息的表单、主题及日期字段。我将忽略一些代码而向你展示如何使用HotmailChecker:

import com.sonalb.net.http.cookie.*;

...

public class HotmailChecker

{

public static void main(String args[]) throws Exception

{

if(args.length != 2)

{

usage();

System.exit(0);

}

String uname = args[0];

String pass = args[1];

HotmailChecker hmc = new HotmailChecker(uname,pass);

if(!hmc.doLogin())

{

System.out.println("Could not login to Hotmail.");

System.exit(0);

}

Vector newMessages = hmc.getNewMessages();

if(newMessages == null)

{

System.out.println("No NEW Messages.");

return;

}

System.out.println("You have " + newMessages.size() + " NEW Messages");

System.out.println("---------------------------------------------");

Iterator iter = newMessages.iterator();

//HMMessage封装了一个Hotmail消息

HMMessage hm;

while(iter.hasNext())

{

hm = (HMMessage) iter.next();

System.out.println(" From: " + hm.getFrom());

System.out.println(" Subject: " + hm.getSubject());

System.out.println("Sent Date: " + hm.getSentDate());

System.out.println("---------------------------------------------");

}

}

static void usage()

{

System.out.println("\nUsage: java HotmailChecker ");

}

//实例变量和方法从这里开始

...

public HotmailChecker(String username, String password)

{

...

}

public boolean doLogin() throws Exception

{

...

}

public Vector getNewMessages() throws Exception

{

...

}

...

}

你可以从下载完全功能的HotmailChecker及相关类。

jCookieMicro与J2ME结合

注意: 这部分假设已经对J2ME至少有一点熟悉。

前面,我曾提起用jCookieMicro库在J2ME平台的移动设备上建立与网络应用程序交互的客户系统的可能性。我仍然在开发jCookieMicro库。它的结构及用法将与jCookie库类似,除了URLConnection,jCookieMicro库将用MIDP HttpConnection对象。这部分描述了在移动应用程序(在我们的案例MIDlets中)使用成熟的cookie操作的好处。

让我们先练习在J2ME应用程序中状态管理常用的方法。诺基亚论坛一篇命名为“”(2002年三月)的论文描述了一个方法。论文提出作为一个URL重写机制的变异工作的机制:一个在网络服务器上的servlet站点操作所有的商务逻辑和使用通常的HTTP报头传送状态信息要胜于cookies。MIDlet简单地作为一个用户界面,传递用户输入到servlet并显示结果。(更多的关于在J2ME应用程序上的状态管理的URL重写及其他方法,请读“”,Michael Juntao Yuan和Ju Long著(JavaWorld,2002年四月).)

使用上述方法,这有与此讨论相关的应用程序的解决方法,一是象一个小型网络浏览器一样与网络服务器或应用程序交互:

· MIDlet从用户那里收集相关输入(比如,一个Hotmail用户名和密码)

· MIDlet传送输入到servlet

· Servlet用输入与网络服务器或应用程序交互(比如,Hotmail网站)

· Servlet传送结果到 MIDlet(比如,一个新消息列表)

· MIDlet向用户显示结果

在上述解决方法中,通用HTTP报头维护一个MIDlet和servlet间的会话。因此,servlet和MIDlet 都包含执行会话管理的逻辑。这证明前面讲过的不受欢迎的同一原因:通用代码很容易被破坏,甚至成为常规管理变化所带来的必然结果,比如服务器升级。这种方法的另一个缺点:它要求有一个在目标网络应用程序(如Hotmail)和移动应用程序之间的中间件。

对于上述方法你可以用两种办法替代jCookieMicro:

1. 将商务逻辑转移到移动应用程序上并完全消除中间servlet。在移动客户系统上用jCookieMicro进行会话管理。

2. 将商务逻辑保持在中间servlet上,但除去通用报头,并用jCookieMicro进行透明坚固的会话管理。

修改已存在的应用程序第二种方法证明更适合。第一种方法导致成本的降低和移动应用程序开发更轻松,因为它除去了服务器端资源的开销。下面的应用程序使用了第一种方法:

· MIDlet从用户处收集相关输入

· MIDlet直接连接到目标网络服务器并与之交互

· MIDlet向用户显示结果

第一种方法同时也消除了将商务逻辑保持在servlet的如下一些缺点:

· 一个servlet容器故障会导致整个应用程序离线,即使目标网络服务仍在运行。

· 应用程序被限制仅作为servlets展开。

在移动应用程序中进行状态管理的另一个方法在Sun无线Java开发者的一篇不依赖风俗权威的文章“”(2002年一月)中有描述,但包括在移动应用程序中写操作cookies的通用代码。前面关于写通用代码的缺点的讨论及使用jCookie(Micro)的优势请看上述命为“在Java中的状态管理”部分)。

自从PJAE提供连同一些Java2类的完整JDK 1.1.8平台,即使在工作中的jCookieMicro,今天你也能在PersonalJava Application Environment (PJAE)下的应用程序中使用jCookie库。。

jCookie局限性

jCookie库还有一些局限性:

· 当cookie解析逻辑及安全标准插入到已存在的API(用CookieParser)时,没有一个对于核心数据结构和Cookie类有用的机制。

· 没有作性能测试。

你可以从得到jCookie最近的版本以及项目源代码。有一些项目是为未来版本计划的包括:

· 雅加达项目log4J logging API的使用提供了用户可配置的记录和调试。

· 用一个用户定义的控制器可简单修改jCookie行为,这可以决定解析一单个cookie是否失败将导致致命错误。

这些及其他部分的执行大量依赖于你的反馈。请在的jCookie项目站点上使用邮件列表、bug追踪、特征请求等等。

取得cooking

这里提到的jCookie库能帮助减轻客户端应用程序状态开发的难度。作为前面曾提到的,其他库的执行类似于函数,但这些结构已和存在的本地java.net API远无关系。另外,没有API/库单独从事cookie操作。其他的库将cookie操作合并作为一个完整的Java 网络客户结构的一部份,结果,使用这些库涉及了整个新的学习体系。

jCookie库接近于存在的java.net对象。在普遍的URLConnection或HttpConnection两个方法调用中状态管理十分简单。你可以通过一个有用的HTTPRedirectHandler类使得状态管理更简单。在处理客户端应用程序开发者时jCookie努力把浏览器作为cookie管理器。这能成功走多远只能由你的反响决定。我将感激任何你所分享的提示或建议。

java 手机网站 cookie操作_Java中的cookie管理方案——完整易用的客户端cookie操作库...相关推荐

  1. java 手机网站 cookie操作_java操作cookie问题

    做的一个ssh项目,其中需要使用cookie来辅助记录用户页面访问量.可是我在使用的时候出现问题,就是我设置了有效期,但是关闭浏览器后或者重新打开另一个浏览器均不能获取到设置的coo... 做的一个s ...

  2. java boolean几个字节_Java中boolean类型到底占用多少个字节?

    1.时间:2017-07-03 07:37:06YuanMxy 2.问题描述:今天在复习java基础的时候发现一小问题,Java中boolean类型到底占用多少个字节? 3.问题解答: (1)什么是b ...

  3. java常见的报错_Java中常见的错误有哪些?

    原标题:Java中常见的错误有哪些? 1.java.lang.Error 错误.是所有错误的基类,用于标识严重的程序运行问题.这些问题通常描述一些不应被应用程序捕获的反常情况. 原因: 1.对系统所访 ...

  4. java i 线程不安全_java中的++i是线程安全的吗?

    java中的++i是线程安全的吗?为什么?怎么使它线程安全呢? 先说答案: 非线程安全 先说下为什么是非线程安全的? 从Java内存模型说起 Java内存模型规定了所有的便利都存储在主内存中,每个线程 ...

  5. java bean的反射类_JAVA中反射机制五(JavaBean的内省与BeanUtils库)

    内省(Introspector) 是Java 语言对JavaBean类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法 ...

  6. java foreach跳出本次循环_Java中提供三种常用的循环语句

    开发工具与关键技术:MyEclipse 10,java 作者:刘东标 循环语句:满足一定条件的情况下反复执行一个操作. Java中提供三种常用的循环语句: 1.while循环语句 while先判断为真 ...

  7. java怎么无参构造方法_Java中如何在无参构造方法中调用有参构造?

    展开全部 一般正常的都是参数多的调用参数少的.有参数的调用无参数的居e68a843231313335323631343130323136353331333365643537多. 当然你要无参调用的参的 ...

  8. 随机数在java 自旋锁的运用_Java 中自旋锁的实现

    Java中初始是使用mutex互斥锁,因为互斥锁是会线程等待挂起,而对获取锁后的操作时间比较短暂的应用场景来说,这样的锁会让竞争锁的线程不停的park,unpark 的操作,这样的系统的调用性能是非常 ...

  9. java显示汉字乱码怎么办_java中的汉字显示问号乱码怎么解决

    java中的汉字显示问号乱码怎么解决 发布时间:2020-06-23 22:16:38 来源:亿速云 阅读:97 作者:元一 java中的汉字显示问号乱码怎么解决?针对这个问题,今天小编总结了这篇文章 ...

  10. java int转无符号_Java 中使用无符号整型(unsigned int)的使用方法

    背景 计算机科班出身大多学过离散数学,或者理工类专业也大多学习过 C 或 C++ 语言,从中我们了解到基本类型的整形有 short.int.long 等,还分别有无符号(unsigned)和带符号(s ...

最新文章

  1. Cent0S 7上的图形安装
  2. 我发现我的Java重拍了!
  3. Kaggle Bike Sharing Demand Prediction – How I got in top 5 percentile of participants?
  4. master节点部署pod_小伙!Kubernetes 部署如此简单,你看完全明白了
  5. dataframe iloc_如何使用iloc和loc 对Pandas Dataframe进行索引和切片
  6. 详解在ASP.NET中用LINQ实现数据处理
  7. 数据缺失,如何智能修复?第一名方案源码分享
  8. 软件安装——在Vmware中安装CentOS7(转载)
  9. ADO.NET访问数据集的表、行和列
  10. ubuntu14在kDE界面下的关于eclipse提示框黑色背景的修改!
  11. 必看干货!五个步骤帮您成功实施IT SLA
  12. CentOS 6.4 电信ADSL拨号上网网络配置
  13. html css网页代码,源码附上
  14. docker image 重命名
  15. 【Cadence使用】PCB元器件匹配3D模型
  16. 直播入门(二)从视频采集到客户端播放
  17. 金融核心业务流程整理
  18. android apk 反编译,修改version后重新打包
  19. IRSHELL 3.8/3.81安装使用教程
  20. 铝电解电容器的主要参数----唯样商城

热门文章

  1. 操作系统国产化,你支持吗?鸿蒙OS万物互联!
  2. 自动切换输入法 for Mac(输入法辅助工具)
  3. 手机传感器你知道多少个?
  4. 怎么注册tk域名_全面剖析tk免费域名注册
  5. 如何批量将 PPT 转换为 jpeg、png、bmp 图片
  6. 知识图谱属性融合_知识图谱融合_本体概念层的融合方法与技术
  7. pmp 估算技术_现在是时候进行大型技术估算了
  8. 编制职工档案管理程序C语言,职工档案管理系统
  9. JAVA GUI同一个窗体切换面板JPanel以及获取JFrame方法的注意事项
  10. 山西台达plc可编程控制器_可编程控制器(PLC)故障的常见原因及处理方法