王朝网络
分享
 
 
 

Java中的cookie管理方案(3)-与J2ME结合

王朝java/jsp·作者佚名  2008-05-31
宽屏版  字体: |||超大  

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("http://www.site.com/");

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("http://www.site.com/");

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.www.protocol");

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

//创建HttpURLConnection并初始化

URL url = new URL("https://lc2.law13.hotmail.passport.com/cgi-bin/dologin");

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("

");

}

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("

Usage: java HotmailChecker ");

}

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

...

public HotmailChecker(String username, String password)

{

...

}

public boolean doLogin() throws Exception

{

...

}

public Vector getNewMessages() throws Exception

{

...

}

...

}

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

(出处:http://www.knowsky.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有