17

感谢这个线程How to download and save a file from Internet using Java? 我知道如何下载文件,现在我的问题是我需要在我正在下载的服务器上进行身份验证。它是一个 subversion 服务器的 http 接口。我需要查看哪个字段?

使用最后一条评论中发布的代码,我得到了这个异常:

java.io.IOException: Server returned HTTP response code: 401 for URL: http://myserver/systemc-2.0.1.tgz
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1305)
    at java.net.URL.openStream(URL.java:1009)
    at mypackage.Installer.installSystemc201(Installer.java:29)
    at mypackage.Installer.main(Installer.java:38)

谢谢,

4

6 回答 6

16

您扩展Authenticator类并注册它。链接上的 javadocs 解释了如何。

我不知道这是否适用于得到该问题的公认答案的 nio 方法,但它肯定适用于作为该答案的老式方法。

在验证器类实现中,您可能会使用PasswordAuthentication并覆盖验证器实现的 getPasswordAuthentication() 方法以返回它。那将是传递您需要的用户名和密码的类。

根据您的要求,这里是一些示例代码:

public static final String USERNAME_KEY = "username";
public static final String PASSWORD_KEY = "password";
private final PasswordAuthentication authentication;

public MyAuthenticator(Properties properties) {
    String userName = properties.getProperty(USERNAME_KEY);
    String password = properties.getProperty(PASSWORD_KEY);
    if (userName == null || password == null) {
        authentication = null;
    } else {
        authentication = new PasswordAuthentication(userName, password.toCharArray());
    }
}

protected PasswordAuthentication getPasswordAuthentication() {
    return authentication;
}

然后在 main 方法中注册它(或者在调用 URL 之前的某处):

Authenticator.setDefault(new MyAuthenticator(properties));

用法很简单,但我发现 API 令人费解,而且对于您通常如何看待这些事情有点倒退。非常典型的单例设计。

于 2009-06-05T12:54:41.230 回答
9

这是我编写的一些代码,用于获取网站并将内容显示到 System.out。它使用基本身份验证:

import java.net.*;
import java.io.*;

public class foo {
    public static void main(String[] args) throws Exception {

   URL yahoo = new URL("http://www.MY_URL.com");

   String passwdstring = "USERNAME:PASSWORD";
   String encoding = new 
          sun.misc.BASE64Encoder().encode(passwdstring.getBytes());

   URLConnection uc = yahoo.openConnection();
   uc.setRequestProperty("Authorization", "Basic " + encoding);

   InputStream content = (InputStream)uc.getInputStream();
   BufferedReader in   =   
            new BufferedReader (new InputStreamReader (content));

   String line;
   while ((line = in.readLine()) != null) {
      System.out.println (line);
   }   

   in.close();
}

上面代码的问题:

  1. 这段代码不是生产就绪的(但它明白了这一点。)

  2. 该代码产生此编译器警告:

foo.java:11:警告:sun.misc.BASE64Encoder 是 Sun 专有 API,可能会在将来的版本中删除
      sun.misc.BASE64Encoder().encode(passwdstring.getBytes());
              ^ 1 个警告

确实应该使用 Authenticator 类,但是对于我的生活,我无法弄清楚如何使用,也找不到任何示例,这只是表明 Java 人在使用他们的时候并不真正喜欢它语言做很酷的事情。:-P

所以上述不是一个好的解决方案,但它确实有效,并且可以在以后轻松修改。

于 2009-06-05T13:07:42.873 回答
8

为 Authenticator 编写重写类:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {  
    private static String username = "";
    private static String password = "";

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication (MyAuthenticator.username, 
                MyAuthenticator.password.toCharArray());
    }

    public static void setPasswordAuthentication(String username, String password) {
        MyAuthenticator.username = username;
        MyAuthenticator.password = password;
    }
}

写你的主要课程:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;

public class MyMain{


    public static void main(String[] args) {
        URL url;
        InputStream is = null;
        BufferedReader br;
        String line;

        // Install Authenticator
        MyAuthenticator.setPasswordAuthentication("Username", "Password");
        Authenticator.setDefault (new MyAuthenticator ());

        try {
            url = new URL("Your_URL_Here");
            is = url.openStream();  // throws an IOException
            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException ioe) {
                // nothing to see here
            }
        }

    }

}
于 2014-08-06T14:43:54.813 回答
1

您是否尝试过以http://user:password@domain/path的形式构建您的 URL ?

于 2009-06-05T12:47:15.067 回答
1

我建议从 apache http://hc.apache.org/httpclient-3.x/检查 HttpClient它使下载/身份验证变得非常容易

于 2009-06-05T12:50:26.667 回答
0

这个开源库http://spnego.sourceforge.net也有一些关于如何使用它的 SpnegoHttpURLConnection 类的示例。

类中的构造函数之一允许您传入用户名和密码。

查看该类的 Java 文档以获取示例。

于 2009-11-16T08:50:04.137 回答