龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

使用Java 1.2的Authenticator 类

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
当您用喜好的浏览器在网上冲浪时,您会碰到要求代理服务器认证或 HTTP 服务器认证的 URL,并会出现您再熟悉不过的窗口要求您输入用户名及口令: 从浏览器访问一个诸如 http://www.l

  当您用喜好的浏览器在网上冲浪时,您会碰到要求代理服务器认证或 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。
  
精彩图集

赞助商链接