Настройка прокси-сервера в Java включает конфигурацию системных свойств или специфических для библиотеки параметров для перенаправления HTTP/HTTPS-трафика через прокси, что применимо к таким инструментам, как java.net.http.HttpClient, Apache HttpClient, Jsoup и Selenium WebDriver.
Общие принципы настройки прокси в Java
Java Virtual Machine (JVM) поддерживает системные свойства для глобальной настройки прокси-серверов. Эти свойства влияют на стандартные сетевые операции, выполняемые классами из пакета java.net, и могут использоваться многими библиотеками, если они не переопределяют этот механизм.
Системные свойства Java
Основные системные свойства для настройки прокси:
- HTTP-прокси:
http.proxyHost: IP-адрес или доменное имя HTTP-прокси-сервера.http.proxyPort: Порт HTTP-прокси-сервера (по умолчанию 80).
- HTTPS-прокси:
https.proxyHost: IP-адрес или доменное имя HTTPS-прокси-сервера.https.proxyPort: Порт HTTPS-прокси-сервера (по умолчанию 443).
- SOCKS-прокси:
socksProxyHost: IP-адрес или доменное имя SOCKS-прокси-сервера.socksProxyPort: Порт SOCKS-прокси-сервера (по умолчанию 1080).socksProxyVersion: Версия SOCKS-протокола (по умолчанию 5).
- Исключения (Non-Proxy Hosts):
http.nonProxyHosts: Список хостов, для которых прокси не используется. Хосты разделяются символом|. Поддерживаются символы-заменители (*). Пример:localhost|127.*|[::1]|*.example.com.
Эти свойства можно установить при запуске JVM:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy.example.com -Dhttps.proxyPort=8080 -jar YourApp.jar
Или программно:
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");
System.setProperty("http.nonProxyHosts", "localhost|127.*");
Настройка аутентификации прокси
Для прокси, требующих аутентификации, можно использовать системный Authenticator:
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class ProxyAuthenticator extends Authenticator {
private final String username;
private final String password;
public ProxyAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// Проверяем, что запрос на аутентификацию исходит от прокси
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication(username, password.toCharArray());
}
return null;
}
public static void setup(String username, String password) {
Authenticator.setDefault(new ProxyAuthenticator(username, password));
}
}
Пример использования:
// В начале программы
ProxyAuthenticator.setup("proxyuser", "proxypass");
// Затем устанавливаем системные свойства прокси
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
// ... и так далее
Настройка прокси для Java HttpClient (java.net.http)
java.net.http.HttpClient (доступен с Java 11) предоставляет современный API для работы с HTTP. Он поддерживает настройку прокси через HttpClient.Builder.
Использование HttpClient.Builder
Для установки HTTP/HTTPS прокси:
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.io.IOException;
import java.net.URI;
public class JavaHttpClientProxy {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 8080)))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code: " + response.statusCode());
System.out.println("Body: " + response.body().substring(0, 100) + "...");
}
}
Для SOCKS-прокси:
import java.net.Proxy; // Важно использовать java.net.Proxy для SOCKS
// ... другие импорты
public class JavaHttpClientSocksProxy {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("socks.example.com", 1080)))
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code: " + response.statusCode());
System.out.println("Body: " + response.body().substring(0, 100) + "...");
}
}
Настройка аутентификации прокси
Для прокси, требующих аутентификации, используйте метод authenticator() в HttpClient.Builder:
import java.net.Authenticator;
import java.net.PasswordAuthentication;
// ... другие импорты
public class JavaHttpClientProxyAuth {
public static void main(String[] args) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 8080)))
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("proxyuser", "proxypass".toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://example.com"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code: " + response.statusCode());
System.out.println("Body: " + response.body().substring(0, 100) + "...");
}
}
Настройка прокси для Apache HttpClient (org.apache.http.client)
Apache HttpClient является широко используемой библиотекой для выполнения HTTP-запросов.
Базовая настройка
Настройка HTTP/HTTPS прокси осуществляется через RequestConfig:
import org.apache.http.HttpHost;
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.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class ApacheHttpClientProxy {
public static void main(String[] args) throws IOException {
HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http"); // Для HTTPS используйте "https"
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
try (CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(config).build()) {
HttpGet request = new HttpGet("http://example.com"); // Запрос через прокси
try (CloseableHttpResponse response = httpClient.execute(request)) {
System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
System.out.println("Body: " + EntityUtils.toString(response.getEntity()).substring(0, 100) + "...");
}
}
}
}
Настройка аутентификации и исключений
Для прокси, требующих аутентификации, используется CredentialsProvider и AuthScope:
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
// ... другие импорты
public class ApacheHttpClientProxyAuth {
public static void main(String[] args) throws IOException {
HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass"));
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
try (CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultRequestConfig(config)
.build()) {
HttpGet request = new HttpGet("http://example.com");
try (CloseableHttpResponse response = httpClient.execute(request)) {
System.out.println("Status Code: " + response.getStatusLine().getStatusCode());
System.out.println("Body: " + EntityUtils.toString(response.getEntity()).substring(0, 100) + "...");
}
}
}
}
Apache HttpClient также учитывает системные свойства http.nonProxyHosts при их установке.
Настройка прокси для Jsoup
Jsoup — библиотека для парсинга HTML. Она позволяет настраивать прокси как через свои методы, так и через системные свойства.
Через Connection.proxy()
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy; // Важно использовать java.net.Proxy
public class JsoupProxy {
public static void main(String[] args) throws IOException {
String url = "http://example.com";
String proxyHost = "proxy.example.com";
int proxyPort = 8080;
Document doc = Jsoup.connect(url)
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)))
.get();
System.out.println("Title: " + doc.title());
System.out.println("Body: " + doc.body().text().substring(0, 100) + "...");
}
}
Для SOCKS-прокси измените Proxy.Type.HTTP на Proxy.Type.SOCKS.
Через системные свойства
Если системные свойства прокси установлены (как описано в разделе "Общие принципы"), Jsoup будет использовать их автоматически без дополнительной настройки в коде:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
public class JsoupSystemProxy {
public static void main(String[] args) throws IOException {
// Установка системных свойств (или запуск с -D)
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");
String url = "http://example.com";
Document doc = Jsoup.connect(url).get(); // Jsoup автоматически использует системные прокси
System.out.println("Title: " + doc.title());
System.out.println("Body: " + doc.body().text().substring(0, 100) + "...");
}
}
Настройка прокси для Selenium WebDriver
Selenium WebDriver позволяет автоматизировать взаимодействие с браузерами. Прокси настраиваются через Capabilities браузера.
Для Chrome
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.Proxy; // Важно использовать org.openqa.selenium.Proxy
public class SeleniumChromeProxy {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver"); // Укажите путь к chromedriver
Proxy proxy = new Proxy();
proxy.setHttpProxy("proxy.example.com:8080");
proxy.setSslProxy("proxy.example.com:8080"); // Для HTTPS
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", proxy);
// options.addArguments("--headless"); // Опционально: запуск в безголовом режиме
WebDriver driver = new ChromeDriver(options);
try {
driver.get("http://example.com");
System.out.println("Page Title: " + driver.getTitle());
} finally {
driver.quit();
}
}
}
Для Firefox
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.Proxy; // Важно использовать org.openqa.selenium.Proxy
public class SeleniumFirefoxProxy {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver"); // Укажите путь к geckodriver
Proxy proxy = new Proxy();
proxy.setHttpProxy("proxy.example.com:8080");
proxy.setSslProxy("proxy.example.com:8080"); // Для HTTPS
FirefoxOptions options = new FirefoxOptions();
options.setProxy(proxy);
// options.addArguments("-headless"); // Опционально: запуск в безголовом режиме
WebDriver driver = new FirefoxDriver(options);
try {
driver.get("http://example.com");
System.out.println("Page Title: " + driver.getTitle());
} finally {
driver.quit();
}
}
}
Настройка аутентификации прокси для Selenium
Selenium WebDriver напрямую не поддерживает передачу учетных данных для HTTP/HTTPS прокси через Proxy объект. Для прокси, требующих аутентификации, используйте следующие подходы:
- SOCKS-прокси с аутентификацией:
org.openqa.selenium.Proxyподдерживает SOCKS v5 с аутентификацией.
java proxy.setSocksProxy("socks.example.com:1080"); proxy.setSocksUsername("socksuser"); proxy.setSocksPassword("sockspass"); proxy.setSocksVersion(5); // По умолчанию 5 - Использование прокси-сервера без аутентификации на стороне клиента: Настройте прокси-сервер так, чтобы он не требовал аутентификации от клиента, или управляйте аутентификацией на самом прокси-сервере.
- Использование сторонних инструментов: Например,
BrowserMob Proxy(или аналогичные) могут перехватывать трафик и добавлять заголовки аутентификации прокси.
Работа с SOCKS-прокси
SOCKS-прокси отличаются от HTTP/HTTPS прокси тем, что они работают на более низком уровне и могут перенаправлять любой TCP-трафик, а не только HTTP/HTTPS.
Системные свойства
Как упоминалось ранее, SOCKS-прокси можно настроить глобально через системные свойства:
System.setProperty("socksProxyHost", "socks.example.com");
System.setProperty("socksProxyPort", "1080");
System.setProperty("socksProxyVersion", "5"); // Для SOCKS v5
Эти свойства будут использоваться java.net.Socket и другими классами, которые используют системные настройки прокси.
Специфические для библиотек настройки
java.net.http.HttpClient: ИспользуетProxySelector.of(new InetSocketAddress("socks.example.com", 1080)). Java автоматически определит тип SOCKS.Jsoup: Используетnew Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.example.com", 1080)).Apache HttpClient: Напрямую не поддерживает SOCKS-прокси черезRequestConfig. Для SOCKS можно использовать системные свойства или настроитьSocketFactoryдляHttpClientBuilder.Selenium WebDriver: Поддерживает SOCKS-прокси через методыsetSocksProxy(),setSocksUsername(),setSocksPassword()в классеorg.openqa.selenium.Proxy.
Таблица сравнения методов настройки прокси
| Метод/Библиотека | Способ настройки | Поддержка аутентификации (HTTP/HTTPS) | Поддержка SOCKS | Примечания |
|---|---|---|---|---|
| Java System Properties | -Dhttp.proxyHost=... / System.setProperty(...) |
Да (через java.net.Authenticator) |
Да | Глобальное влияние на всю JVM, используется многими библиотеками по умолчанию. |
java.net.http.HttpClient |
HttpClient.newBuilder().proxy(...) |
Да (через HttpClient.Builder.authenticator(...)) |
Да | Современный API (Java 11+), гибкая настройка прокси и аутентификации для каждого клиента. |
Apache HttpClient |
RequestConfig.custom().setProxy(...) |
Да (через CredentialsProvider) |
Нет (напрямую) | Требует отдельной настройки для SOCKS (например, через системные свойства или кастомный SocketFactory). Гибкая настройка для каждого запроса или клиента. |
Jsoup |
Jsoup.connect(...).proxy(...) |
Нет (напрямую) | Да | Поддерживает системные свойства прокси. Для аутентификации прокси через Jsoup необходимо использовать системный Authenticator или прокси без аутентификации. |
Selenium WebDriver |
Proxy объект в ChromeOptions/FirefoxOptions |
Да (только для SOCKS) | Да | Для HTTP/HTTPS прокси с аутентификацией обычно требуются обходные пути (например, сторонние прокси-серверы или расширения браузера), или использование SOCKS v5 с аутентификацией. Поддерживает http.nonProxyHosts через системные свойства. |