当前页面位置: » 丰搜网 » 文档中心 » 详细内容
java中的cookie管理方案(3)-与j2me结合
· 和一个请求(假定一个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工具和一个通用的处理器。convertbad
htmltogood帮助类将成形不好的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 { ... } ... }
|
你可以从resources下载完全功能的hotmailchecker及相关类。