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

来源:互联网 发布:centos 磁盘空间 编辑:程序博客网 时间:2024/05/16 15:30
<script type="text/javascript">google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";google_ad_width = 336;google_ad_height = 280;//</script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>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("/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及相关类。Java中的cookie管理方案(1)-与J2ME结合Java中的cookie管理方案(2)-与J2ME结合Java中的cookie管理方案(3)-与J2ME结合Java中的cookie管理方案(4)-与J2ME结合
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 豫坡老基酒图片及价格 酒基酒价格 基酒价格 什么叫基酒 调酒基酒 基金 天天基金 基金赎回 维修基金 易方达基金 买货币基金 指数基金 汇添富基金 基金从业 基金定投 etf基金 兴全基金 酷基金网 001071基金 基金投资 基金经理 天天基金网自选基金 基金090003 基金481001 自选基金天天基金网 基金购买 查基金净值 购买基金 广发基金 混合基金 爱基金 基金手续费 黄金基金 基金类型 好买基金网 证券基金 指数型基金 基金入门 什么基金好 封闭基金 基金交易