10

Nhờ chủ đề này How to download and save a file from Internet using Java? Tôi biết cách tải xuống tệp, bây giờ vấn đề của tôi là tôi cần phải xác thực trên máy chủ mà tôi đang tải xuống. Đó là giao diện http cho máy chủ lật đổ. Tôi cần tra cứu trường nào?Tải xuống tệp từ internet bằng java: Cách xác thực?

Sử dụng mã đăng trong chú thích cuối cùng, tôi nhận được ngoại lệ này:

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) 

Cảm ơn,

+0

ngoại lệ gì bạn nhận được nếu bạn bỏ qua id người dùng và mật khẩu từ url? – cmsjr

+0

ngoại lệ tương tự nếu tôi bỏ qua thông tin đăng nhập/pass hoặc nếu tôi đặt nó (mã 401) – user105413

Trả lời

11

Bạn mở rộng các lớp Authenticator và đăng ký nó. Các javadocs tại liên kết giải thích như thế nào.

Tôi không biết liệu điều này có phù hợp với phương pháp nio có câu trả lời được chấp nhận cho câu hỏi hay không, nhưng nó chắc chắn hoạt động theo cách cũ kỹ, đó là câu trả lời theo câu hỏi đó.

Trong quá trình triển khai lớp xác thực, có thể bạn sẽ sử dụng PasswordAuthentication và ghi đè phương thức getPasswordAuthentication() để triển khai Authenticator của bạn để trả lại. Đó sẽ là lớp được truyền tên người dùng và mật khẩu bạn cần.

Theo yêu cầu của bạn, đây là một số mẫu mã:

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; 
} 

Và bạn đăng ký nó trong phương thức main (hoặc ở đâu đó dọc theo dòng trước khi bạn gọi URL):

Authenticator.setDefault(new MyAuthenticator(properties)); 

Các sử dụng rất đơn giản, nhưng tôi thấy API phức tạp và ngược lại về cách bạn thường nghĩ về những điều này. Khá điển hình của thiết kế singleton.

+0

Bạn có thể đăng một số mã mẫu không? Javadoc không đưa ra bất kỳ ví dụ nào và không thể biết cách sử dụng lớp này! – poundifdef

+3

Vâng, bạn chỉ cần gọi setDefault và thats nó '\t \t Authenticator.setDefault (Authenticator mới() { \t \t \t bảo vệ thực mật khẩu getPasswordAuthentication() { \t \t \t \t trở lại thực mật khẩu mới ("đăng nhập", " vượt qua" .toCharArray()); \t \t \t} \t \t});' tôi rất ấn tượng – user105413

+0

Tốt thứ! Một giải pháp java thường xoắn. Lưu ý rằng có thể chính xác hơn để nói rằng bạn cần phải EXTEND thay vì thực hiện lớp Authenticator; nó không phải là một giao diện ... – jsh

1

Bạn đã cố gắng xây dựng URL của bạn trong các hình thức http://user:[email protected]/path?

+0

nó hoạt động trong trình duyệt của tôi nhưng không có trong chương trình java của tôi – user105413

+0

Xin lỗi vì đã không giải quyết được. Có vẻ như Authenticator được đề cập bởi @Yishai kết thúc tốt đẹp kỹ thuật đó http://www.javaworld.com/javaworld/javatips/jw-javatip47.html – cmsjr

7

Đây là một số mã tôi đã viết tìm nạp trang web và hiển thị nội dung cho System.out. Nó sử dụng xác thực cơ bản:

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(); 
} 

Vấn đề với đoạn code trên:

  1. Mã này không phải là sản xuất-ready (. Nhưng nó được điểm trên)

  2. Các kết quả trả lại cảnh báo trình biên dịch này:

 
foo.java:11: warning: sun.misc.BASE64Encoder is Sun proprietary API and may be removed in a future release 
     sun.misc.BASE64Encoder().encode(passwdstring.getBytes()); 
      ^1 warning 

Người ta thực sự nên sử dụng lớp Authenticator, nhưng đối với cuộc sống của tôi, tôi không thể tìm ra cách và tôi cũng không thể tìm thấy bất kỳ ví dụ nào, chỉ cho thấy người Java không thực sự thích nó khi bạn sử dụng ngôn ngữ của họ để làm những điều tuyệt vời. :-P

Vì vậy, bên trên không phải là giải pháp tốt, nhưng nó hoạt động và có thể dễ dàng được sửa đổi sau này.

+1

Nếu bạn muốn có một bộ mã hóa base64, tôi khuyên bạn nên thực hiện iharder.net. Public Domain, không thể tự do hơn thế. http://iharder.sourceforge.net/current/java/base64/ – Yishai

+0

Đây chỉ là những gì tôi cần, cảm ơn. – Amalgovinus

+0

Groovy đã có hỗ trợ base64! Chỉ cần làm passwd.getBytes(). EncodeBase64(). ToString(). Xem http://mrhaki.blogspot.com/2009/11/groovy-goodness-base64-encoding.html –

0

Thư viện nguồn mở này, http://spnego.sourceforge.net, cũng có một số ví dụ về cách sử dụng lớp SpnegoHttpURLConnection của nó.

Một trong các hàm tạo trong lớp cho phép bạn chuyển vào tên người dùng và mật khẩu.

Hãy xem tài liệu java của lớp học để biết các ví dụ.

6

Viết lớp trọng của bạn đối với 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; 
    } 
} 

Viết lớp học chính của bạn:

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 
      } 
     } 

    } 

} 
Các vấn đề liên quan