Das Einrichten von Proxys für Java-Anwendungen, die HttpClient, Jsoup und Selenium verwenden, beinhaltet die Konfiguration von Proxy-Host und -Port entweder global über Java-Systemeigenschaften oder spezifisch für die Verbindungsobjekte jeder Bibliothek, oft einschließlich Vorkehrungen für die Authentifizierung.
Proxy-Grundlagen in Java
Proxy-Server fungieren als Vermittler für Netzwerkanfragen und bieten Vorteile wie verbesserte Sicherheit, Anonymität und Zugriff auf geografisch eingeschränkte Inhalte. In Java können Proxy-Konfigurationen entweder breit über die Java Virtual Machine (JVM) angewendet oder spezifisch für einzelne HTTP-Clients vorgenommen werden.
Proxy-Typen
- HTTP-Proxy: Verarbeitet HTTP-Anfragen (
http://). - HTTPS-Proxy: Verarbeitet HTTPS-Anfragen (
https://). Oft kann ein HTTP-Proxy auch HTTPS-Anfragen über dieCONNECT-Methode verarbeiten. - SOCKS-Proxy: Unterstützt verschiedene Netzwerkprotokolle, nicht nur HTTP/HTTPS. Bietet mehr Flexibilität und kann TCP- und UDP-Verkehr verarbeiten.
Proxy-Authentifizierung
Viele Proxys erfordern eine Authentifizierung (Benutzername/Passwort). Dies kann je nachdem, ob der Proxy global oder pro Client konfiguriert ist, unterschiedlich gehandhabt werden.
Globale Proxy-Einrichtung (Java-Systemeigenschaften)
Java bietet Systemeigenschaften zur Konfiguration von Proxys, die für alle java.net-Verbindungen gelten, einschließlich derer, die von HttpURLConnection (das Jsoup intern verwendet) und anderen Bibliotheken, die standardmäßig diese Systemeinstellungen nutzen, hergestellt werden.
// 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");
Diese Eigenschaften können auch als JVM-Argumente übergeben werden:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 YourApplication
Globale Proxy-Authentifizierung
Für Proxys, die eine Authentifizierung erfordern, kann Javas Authenticator-Klasse verwendet werden. Dies richtet einen Standard-Authenticator für alle java.net-Verbindungen ein.
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 bietet robuste, flexible Methoden für HTTP-Anfragen und wird häufig für komplexe Integrationen verwendet. Es unterstützt die explizite Proxy-Konfiguration pro Client-Instanz.
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 ist eine Java-Bibliothek für die Arbeit mit realem HTML. Sie bietet eine einfache API zum Abrufen von URLs und zum Parsen von HTML. Jsoup's Connection-Schnittstelle ermöglicht die direkte Proxy-Konfiguration.
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.
}
}
Für authentifizierte Proxys mit Jsoup ist der empfohlene Ansatz, die globalen Java-Systemeigenschaften und java.net.Authenticator wie im Abschnitt "Globale Proxy-Einrichtung" gezeigt zu konfigurieren. Jsoup's interne HttpURLConnection wird diese Einstellungen dann übernehmen.
Selenium WebDriver
Selenium automatisiert Webbrowser. Die Proxy-Konfiguration für Selenium WebDriver erfolgt typischerweise über browserspezifische Optionen.
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 Proxy-Authentifizierung
Selenium WebDriver selbst handhabt die Proxy-Authentifizierung (Benutzername/Passwort für HTTP/HTTPS-Proxys) nicht direkt. Gängige Ansätze umfassen:
- Browser-Erweiterungen: Verwenden Sie eine Browser-Erweiterung, die die Proxy-Authentifizierung handhabt. Diese Erweiterungen können über
ChromeOptionsoderFirefoxOptionsgeladen werden. - Proxy in URL: Bei einigen HTTP-Proxys können Anmeldeinformationen in die Proxy-URL eingebettet werden (z.B.
user:pass@proxy.example.com:8080), dies wird jedoch nicht universell unterstützt oder ist sicher. - SOCKS5-Authentifizierung: Selenius
Proxy-Klasse unterstütztsetSocksUsername()undsetSocksPassword()für SOCKS5-Proxys. - Upstream-Proxy-Server: Leiten Sie den Verkehr über einen anderen lokalen Proxy-Server (z.B. BrowserMob Proxy), der die Authentifizierung mit dem Ziel-Proxy verwaltet.
Vergleich der Proxy-Einrichtungsmethoden
| Merkmal | Java-Systemeigenschaften (-D) |
Apache HttpClient (4.x/5.x) | Jsoup (.proxy()) |
Selenium WebDriver (Proxy-Klasse) |
|---|---|---|---|---|
| Geltungsbereich | Global (JVM-weit) | Pro HttpClient-Instanz |
Pro Connection-Instanz |
Pro WebDriver-Instanz |
| Authentifizierung | java.net.Authenticator (global) |
CredentialsProvider (pro Client) |
java.net.Authenticator (falls global) |
SOCKS5 (setSocksUsername/Password); HTTP/HTTPS typischerweise über Erweiterungen/externe Tools |
| Flexibilität | Gering (betrifft alle java.net-Verbindungen) |
Hoch (feingranulare Kontrolle, Pro-Anfrage-Konfiguration) | Moderat (pro Verbindung, aber auf globale Auth angewiesen) | Hoch (browserspezifische Optionen, SOCKS-Auth) |
| Benutzerfreundlichkeit | Hoch (einfache Eigenschaften) | Moderat bis Hoch (erfordert mehr Code) | Hoch (einfache Methodenaufrufe) | Moderat (erfordert Erstellung von Proxy-Objekt und Setzen von Optionen) |
| Unterstützte Protokolle | HTTP, HTTPS, SOCKS | HTTP, HTTPS, SOCKS | HTTP, HTTPS (über HttpURLConnection) |
HTTP, HTTPS, SOCKS (Browser-Fähigkeiten) |
| Anwendungsfälle | Einfache, konsistente Proxy-Anforderungen in der App | Komplexe HTTP-Interaktionen, API-Clients | Web-Scraping, einfaches Abrufen von Seiten | Browser-Automatisierung, Tests, Web-Scraping |