Налаштування проксі для Java-застосунків за допомогою HttpClient, Jsoup та Selenium передбачає конфігурацію хоста та порту проксі або глобально через системні властивості Java, або спеціально для об'єктів з'єднання кожної бібліотеки, часто включаючи положення для автентифікації.
Основи проксі в Java
Проксі-сервери діють як посередники для мережевих запитів, пропонуючи такі переваги, як підвищена безпека, анонімність та доступ до геообмеженого контенту. У Java конфігурації проксі можуть застосовуватися широко по всій Java Virtual Machine (JVM) або спеціально до окремих HTTP-клієнтів.
Типи проксі
- HTTP Proxy: Обробляє HTTP-запити (
http://). - HTTPS Proxy: Обробляє HTTPS-запити (
https://). Часто HTTP-проксі також може обробляти HTTPS-запити за допомогою методуCONNECT. - SOCKS Proxy: Підтримує різні мережеві протоколи, не лише HTTP/HTTPS. Пропонує більшу гнучкість і може обробляти TCP та UDP трафік.
Автентифікація проксі
Багато проксі вимагають автентифікації (ім'я користувача/пароль). Це може оброблятися по-різному залежно від того, чи проксі налаштований глобально, чи для кожного клієнта.
Глобальне налаштування проксі (системні властивості Java)
Java надає системні властивості для конфігурації проксі, які застосовуються до всіх з'єднань java.net, включаючи ті, що здійснюються HttpURLConnection (який Jsoup використовує внутрішньо) та іншими бібліотеками, що за замовчуванням використовують ці системні налаштування.
// Set HTTP proxy
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
// Set HTTPS proxy (can be the same as HTTP or different)
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");
// Set SOCKS proxy
System.setProperty("socksProxyHost", "socks.example.com");
System.setProperty("socksProxyPort", "1080");
// Exclude hosts from proxying (comma-separated list, wildcards allowed)
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|*.local");
Ці властивості також можуть бути передані як аргументи JVM:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 YourApplication
Глобальна автентифікація проксі
Для проксі, що вимагають автентифікації, можна використовувати клас Authenticator Java. Це налаштовує автентифікатор за замовчуванням для всіх з'єднань java.net.
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class GlobalProxyAuthenticator {
public static void setup(String username, String password) {
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// Check if the request is for a proxy
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication(username, password.toCharArray());
}
return null; // No authentication for other requests
}
});
}
public static void main(String[] args) {
// Set global proxy properties
System.setProperty("http.proxyHost", "authenticated-proxy.example.com");
System.setProperty("http.proxyPort", "8080");
System.setProperty("https.proxyHost", "authenticated-proxy.example.com");
System.setProperty("https.proxyPort", "8080");
// Set up authenticator
GlobalProxyAuthenticator.setup("proxyuser", "proxypass");
// Now, any HttpURLConnection-based request will attempt to use this proxy and credentials
// Example: Jsoup will implicitly use this.
try {
org.jsoup.Connection.Response response = org.jsoup.Jsoup.connect("http://httpbin.org/get")
.ignoreContentType(true)
.execute();
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
Apache HttpClient
Apache HttpClient надає надійні, гнучкі методи для виконання HTTP-запитів і широко використовується для складних інтеграцій. Він підтримує явну конфігурацію проксі для кожного екземпляра клієнта.
HttpClient 4.x
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class HttpClient4ProxySetup {
public static void main(String[] args) throws Exception {
// 1. Define Proxy Host
HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http"); // or "https" or "socks"
// 2. Configure Request with Proxy
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
// 3. (Optional) For Authenticated Proxy: Credentials Provider
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass"));
// 4. Build HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(config)
.setDefaultCredentialsProvider(credentialsProvider) // For authenticated proxies
.build();
// 5. Execute Request
HttpGet request = new HttpGet("http://httpbin.org/get");
request.setConfig(config); // Ensure request uses the config
try (CloseableHttpResponse response = httpClient.execute(request)) {
System.out.println("Status: " + response.getStatusLine());
System.out.println("Body: " + EntityUtils.toString(response.getEntity()));
} finally {
httpClient.close();
}
}
}
HttpClient 5.x
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.ClassicHttpResponse;
public class HttpClient5ProxySetup {
public static void main(String[] args) throws Exception {
// 1. Define Proxy Host
HttpHost proxy = new HttpHost("http", "proxy.example.com", 8080); // Scheme, Host, Port
// 2. (Optional) For Authenticated Proxy: Credentials Provider
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass".toCharArray()));
// 3. Build HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(proxy) // Set proxy directly on the client builder
.setDefaultCredentialsProvider(credentialsProvider) // For authenticated proxies
.build();
// 4. Execute Request
HttpGet request = new HttpGet("http://httpbin.org/get");
// RequestConfig can still be used for per-request overrides if needed
RequestConfig requestConfig = RequestConfig.custom()
// .setProxy(proxy) // Can also be set here for per-request proxy
.build();
request.setConfig(requestConfig);
try (CloseableHttpClient client = httpClient) {
client.execute(request, response -> {
System.out.println("Status: " + response.getCode());
System.out.println("Body: " + EntityUtils.toString(response.getEntity()));
return null;
});
}
}
}
Jsoup
Jsoup – це бібліотека Java для роботи з реальним HTML. Вона надає простий API для отримання URL-адрес та аналізу HTML. Інтерфейс Connection Jsoup дозволяє пряму конфігурацію проксі.
import org.jsoup.Jsoup;
import org.jsoup.Connection;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
public class JsoupProxySetup {
public static void main(String[] args) {
String url = "http://httpbin.org/get";
String proxyHost = "proxy.example.com";
int proxyPort = 8080;
try {
// Method 1: Using proxy(host, port)
Connection.Response response1 = Jsoup.connect(url)
.proxy(proxyHost, proxyPort)
.ignoreContentType(true)
.execute();
System.out.println("Jsoup (Method 1) Status: " + response1.statusCode());
System.out.println("Jsoup (Method 1) Body: " + response1.body().substring(0, 100) + "...\n");
// Method 2: Using java.net.Proxy object
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
Connection.Response response2 = Jsoup.connect(url)
.proxy(proxy)
.ignoreContentType(true)
.execute();
System.out.println("Jsoup (Method 2) Status: " + response2.statusCode());
System.out.println("Jsoup (Method 2) Body: " + response2.body().substring(0, 100) + "...\n");
} catch (IOException e) {
System.err.println("Error connecting via Jsoup proxy: " + e.getMessage());
e.printStackTrace();
}
// For authenticated proxies, Jsoup relies on global Java system properties and Authenticator.
// See "Global Proxy Setup" section for details.
}
}
Для автентифікованих проксі з Jsoup рекомендований підхід полягає в конфігурації глобальних системних властивостей Java та java.net.Authenticator, як показано в розділі "Глобальне налаштування проксі". Внутрішній HttpURLConnection Jsoup тоді підхопить ці налаштування.
Selenium WebDriver
Selenium автоматизує веб-браузери. Конфігурація проксі для Selenium WebDriver зазвичай виконується за допомогою опцій, специфічних для браузера.
Chrome WebDriver
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class SeleniumChromeProxySetup {
public static void main(String[] args) {
// Set path to ChromeDriver executable
// System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
String proxyHost = "proxy.example.com";
int proxyPort = 8080;
String proxyAddress = proxyHost + ":" + proxyPort;
Proxy proxy = new Proxy();
proxy.setHttpProxy(proxyAddress); // For HTTP traffic
proxy.setSslProxy(proxyAddress); // For HTTPS traffic (often same as HTTP)
proxy.setSocksProxy(proxyAddress); // For SOCKS traffic
// proxy.setSocksUsername("socksuser"); // For SOCKS5 authentication
// proxy.setSocksPassword("sockspass");
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", proxy);
// options.addArguments("--proxy-server=" + proxyAddress); // Alternative for simple HTTP/HTTPS proxy
WebDriver driver = new ChromeDriver(options);
try {
driver.get("http://httpbin.org/get");
System.out.println("Page title: " + driver.getTitle());
// Further interactions with the page...
} finally {
driver.quit();
}
}
}
Firefox WebDriver
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
public class SeleniumFirefoxProxySetup {
public static void main(String[] args) {
// Set path to GeckoDriver executable
// System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
String proxyHost = "proxy.example.com";
int proxyPort = 8080;
String proxyAddress = proxyHost + ":" + proxyPort;
Proxy proxy = new Proxy();
proxy.setHttpProxy(proxyAddress);
proxy.setSslProxy(proxyAddress);
proxy.setSocksProxy(proxyAddress);
// proxy.setSocksUsername("socksuser");
// proxy.setSocksPassword("sockspass");
FirefoxOptions options = new FirefoxOptions();
options.setCapability("proxy", proxy);
WebDriver driver = new FirefoxDriver(options);
try {
driver.get("http://httpbin.org/get");
System.out.println("Page title: " + driver.getTitle());
} finally {
driver.quit();
}
}
}
Автентифікація проксі Selenium
Selenium WebDriver сам по собі не обробляє безпосередньо автентифікацію проксі (ім'я користувача/пароль для HTTP/HTTPS проксі). Поширені підходи включають:
- Розширення браузера: Використовуйте розширення браузера, яке обробляє автентифікацію проксі. Ці розширення можуть бути завантажені через
ChromeOptionsабоFirefoxOptions. - Проксі в URL: Для деяких HTTP-проксі облікові дані можуть бути вбудовані в URL проксі (наприклад,
user:pass@proxy.example.com:8080), але це не є універсально підтримуваним або безпечним. - Автентифікація SOCKS5: Клас
ProxySelenium підтримуєsetSocksUsername()таsetSocksPassword()для SOCKS5 проксі. - Вихідний проксі-сервер: Маршрутизація трафіку через інший локальний проксі-сервер (наприклад, BrowserMob Proxy), який керує автентифікацією з цільовим проксі.
Порівняння методів налаштування проксі
| Функція | Системні властивості Java (-D) |
Apache HttpClient (4.x/5.x) | Jsoup (.proxy()) |
Selenium WebDriver (клас Proxy) |
|---|---|---|---|---|
| Область дії | Глобальна (в межах JVM) | На екземпляр HttpClient |
На екземпляр Connection |
На екземпляр WebDriver |
| Автентифікація | java.net.Authenticator (глобально) |
CredentialsProvider (на клієнта) |
java.net.Authenticator (якщо глобально) |
SOCKS5 (setSocksUsername/Password); HTTP/HTTPS зазвичай через розширення/зовнішні інструменти |
| Гнучкість | Низька (впливає на всі з'єднання java.net) |
Висока (детальний контроль, конфігурація на запит) | Помірна (на з'єднання, але залежить від глобальних налаштувань для автентифікації) | Висока (опції, специфічні для браузера, автентифікація SOCKS) |
| Простота використання | Висока (прості властивості) | Помірна до високої (потребує більше коду) | Висока (прості виклики методів) | Помірна (потребує створення об'єкта Proxy та встановлення опцій) |
| Підтримувані протоколи | HTTP, HTTPS, SOCKS | HTTP, HTTPS, SOCKS | HTTP, HTTPS (через HttpURLConnection) |
HTTP, HTTPS, SOCKS (можливості браузера) |
| Випадки використання | Прості, послідовні потреби проксі в застосунку | Складні HTTP-взаємодії, клієнти API | Веб-скрейпінг, просте отримання сторінок | Автоматизація браузера, тестування, веб-скрейпінг |