Четене от файл от адрес в интернет през базова автентификация (Basic Authentication)

В употребата на Java дори за най-прости цели, четенето от файл рядко отсъства като необходимост. Чести са случаите, когато файлът ще е разположен на друг компютър, до който може да се достигне чрез URL. Това е проста и донякъде безинтересна  задача, но понякога и при нея могат да възникнат определени препятствия.

Настоящият пример илюстрира ситуацията, при която, за да достигнем необходимия ни файл, е нужно да предоставим на сървъра валидни име и парола – т. нар. базова автентификация (basic authentication).

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

public class FileReader {

	public void readFile(){
		String path = "http://www.example.com/file.txt";

		// Така подаваме името и паролата, които ще ползваме.
		Authenticator.setDefault (new Authenticator() {
		    protected PasswordAuthentication getPasswordAuthentication() {
		        return new PasswordAuthentication ("потребител", "парола".toCharArray());
		    }
		});

	    try {
	        URL url = new URL(path);
	        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
	        String str = in.readLine();
	        while (str != null) {	         	
	        		str = in.readLine();
			// Действия, които програмата извършва, четейки ред по ред.
	        }
	        in.close();
	        } catch (MalformedURLException e) {	 
			// Възниква при невалиден адрес, например когато не е посочен протоколът.       	  
	        } catch (IOException e) {
			// Възниква, когато файлът не може да бъде прочетен – може да не съществува
			// или просто нямаме достъп до него.
	        }
	}
}

Какво ми направи толкова голямо впечатление, че да споделя това – противно на очакванията, не подаваме данните за автентификация направо в URL-а, например http://потребител:парола@www.example.com, както е логично да решим – това би довело до грешка. Правилният начин е именно да предефинираме java.net.Authenticator.getPasswordAuthentication().