当您用喜好的浏览器在网上冲浪时,您会遇到要求代理服务器认证或 http 服务器认证的 url,并会出现您再熟悉不过的窗口要求您输入用户名及口令:
从浏览器访问一个诸如 http://www.lombard.com/cgi-bin/quotes/quote 这样的 url 不成问题,因为您自己可以提供用户名和口令。但是当您试图通过 java 程序从与此 url 相关的 inputstream 中读取数据时,该 java 程序就会发出 filenotfoundexception 异常。
在 java 1.0 或 1.1 中,您可以通过在连接时记入 (post) 适当的认证字符串来避免这种情况,但这种方法仅在您事先知道该 url 是受保护的时才奏效。(authorization: basic username:password,其中基本认证域是以 base 64 编码的。)如果您事先没有预见到文档是受保护的,则您甚至无法读取文件内容。(有关用 java 1.1 applet 或应用程序访问口令保护的 url 的解决方案,请参阅“java 技巧 47:再谈 url 认证”。值得庆幸的是,java 1.2 在 java.net 包中添加了一个 authenticator 类,这使得访问口令保护的 url 变得极为容易。
现在,对于 java 1.2,您只需用 authenticator.setdefault() 安装一个 authenticator。这样,当需要认证时,已安装的 authenticator 的 getpasswordauthentication() 方法就会被调用,然后您就可以用适当的用户名和口令来设置 passwordauthentication 实例。就这么简单。
所需步骤如下所示。
第一步:安装 authenticator
authenticator.setdefault (new myauthenticator ());
第二步:创建 authenticator 的子类
class myauthenticator extends authenticator {
protected passwordauthentication getpasswordauthentication() {
return new passwordauthentication ("username", "password");
}
}
以下程序完整地显示了这种行为,它提供了自己的认证提示对话框。
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
public class urlpassword extends frame {
private textfield tf = new textfield();
private textarea ta = new textarea();
public urlpassword() {
super ("url password");
// 安装 authenticator
authenticator.setdefault (new myauthenticator ());
// 设置屏幕
add (tf, borderlayout.north);
ta.seteditable(false);
add (ta, borderlayout.center);
tf.addactionlistener (new actionlistener() {
public void actionperformed (actionevent e) {
string s = tf.gettext();
if (s.length() != 0)
ta.settext (fetchurl (s));
}
});
addwindowlistener (new windowadapter() {
public void windowclosing (windowevent e) {
dispose();
system.exit(0);
}
});
}
private string fetchurl (string urlstring) {
stringwriter sw = new stringwriter();
printwriter pw = new printwriter(sw);
try {
url url = new url (urlstring);
inputstream content = (inputstream)url.getcontent();
bufferedreader in =
new bufferedreader (new inputstreamreader (content));
string line;
while ((line = in.readline()) != null) {
pw.println (line);
}
} catch (malformedurlexception e) {
pw.println ("invalid url");
} catch (ioexception e) {
pw.println ("error reading url");
}
return sw.tostring();
}
public static void main (string args[]) {
frame f = new urlpassword();
f.setsize(300, 300);
f.setvisible (true);
}
class myauthenticator extends authenticator {
protected passwordauthentication getpasswordauthentication() {
final dialog jd = new dialog (urlpassword.this, "enter password", true);
jd.setlayout (new gridlayout (0, 1));
label jl = new label (getrequestingprompt());
jd.add (jl);
textfield username = new textfield();
username.setbackground (color.lightgray);
jd.add (username);
textfield password = new textfield();
password.setechochar (´*´);
password.setbackground (color.lightgray);
jd.add (password);
button jb = new button ("ok");
jd.add (jb);
jb.addactionlistener (new actionlistener() {
public void actionperformed (actionevent e) {
jd.dispose();
}
});
jd.pack();
jd.setvisible(true);
return new passwordauthentication (username.gettext(), password.gettext());
}
}
}
后续技巧!
来自 luis blanco gomez
代码的第 85 行(myauthenticator 类的返回参数)显示一个错误:
return new passwordauthentication (username.gettext(), password.gettext());
编译器将报错:
urlpass.java:88: incompatible type for constructor. can´t convert
java.lang.string to char[].
return new passwordauthentication ( username.gettext(), password.gettext());
为修正此错误,您必须声明一个 string 变量来存储 password.gettext();例如,"string pass= password.gettext();",并将返回行改为:
return new passwordauthentication ( username.gettext(), pass.tochararray());
为了测试这个程序,必须找出一个您知道其用户名和口令的 url。就 discover brokerage direct 而言,任何人都可以在 registration desk 获得一个免费口令。接下来,用 url http://www.lombard.com/cgi-bin/quotes/quote 来测试该程序。
有几点值得一提:不可信的 applet 可在 appletviewer 中安装一个缺省的 authenticator。hotjava、navigator 和 internet explorer 会怎么做尚不清楚。如果您没有必要的权限便试图更改 authenticator,该程序就会发出一个 accesscontrolexception 异常。
提交您喜好的 java 技巧
每篇技巧都将提供有关有用的技巧和窍门的几则简短信息,以帮助您改进 java 代码。我们将探究这一出色技术的诸多方面,每次讨论一个 java bean。
我们也希望将您的 java 技巧刊登在以后的 java world 上。赶快将您最棒的技巧和窍门写出来并发送到 javatips@javaworld.com。您可能会发现自己成了 javaworld 的一名作者,因为您的有益提示可能成为下一篇 java 技巧!
作者简介
john.zukowski john zukowski 是 magelang institute 的一位软件专家,他是 java awtreference(o´reilly& associates 出版)、borland´s jbuilder: no experience required(sybex 出版)两本书的作者,同时也是 mining company 的 focus on java 指南的作者。
闽公网安备 35060202000074号