Configurar proxies para aplicações Java usando HttpClient, Jsoup e Selenium envolve definir o host e a porta do proxy — seja globalmente, por meio das propriedades de sistema do Java, seja especificamente nos objetos de conexão de cada biblioteca —, muitas vezes incluindo mecanismos de autenticação.
Fundamentos de proxy em Java
Servidores proxy atuam como intermediários para requisições de rede, oferecendo benefícios como maior segurança, anonimato e acesso a conteúdo com restrição geográfica. Em Java, as configurações de proxy podem ser aplicadas de forma ampla em toda a Java Virtual Machine (JVM) ou especificamente em clientes HTTP individuais.
Tipos de proxy
- Proxy HTTP: trata requisições HTTP (
http://). - Proxy HTTPS: trata requisições HTTPS (
https://). Muitas vezes, um proxy HTTP também consegue tratar requisições HTTPS pelo métodoCONNECT. - Proxy SOCKS: suporta diversos protocolos de rede, não apenas HTTP/HTTPS. Oferece mais flexibilidade e consegue lidar com tráfego TCP e UDP.
Autenticação de proxy
Muitos proxies exigem autenticação (usuário/senha). Isso pode ser tratado de maneiras diferentes conforme o proxy esteja configurado globalmente ou por cliente.
Configuração global de proxy (propriedades de sistema do Java)
O Java oferece propriedades de sistema para configurar proxies que se aplicam a todas as conexões java.net, incluindo as feitas por HttpURLConnection (que o Jsoup usa internamente) e outras bibliotecas que assumem por padrão essas configurações de sistema.
// Define o proxy HTTP
System.setProperty("http.proxyHost", "proxy.example.com");
System.setProperty("http.proxyPort", "8080");
// Define o proxy HTTPS (pode ser o mesmo do HTTP ou diferente)
System.setProperty("https.proxyHost", "proxy.example.com");
System.setProperty("https.proxyPort", "8080");
// Define o proxy SOCKS
System.setProperty("socksProxyHost", "socks.example.com");
System.setProperty("socksProxyPort", "1080");
// Exclui hosts do proxy (lista separada por vírgulas, curingas permitidos)
System.setProperty("http.nonProxyHosts", "localhost|127.0.0.1|*.local");
Essas propriedades também podem ser passadas como argumentos da JVM:
java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 YourApplication
Autenticação em proxy global
Para proxies que exigem autenticação, é possível usar a classe Authenticator do Java. Isso define um autenticador padrão para todas as conexões 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() {
// Verifica se a requisição é para um proxy
if (getRequestorType() == RequestorType.PROXY) {
return new PasswordAuthentication(username, password.toCharArray());
}
return null; // Sem autenticação para as demais requisições
}
});
}
public static void main(String[] args) {
// Define as propriedades globais de proxy
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");
// Configura o autenticador
GlobalProxyAuthenticator.setup("proxyuser", "proxypass");
// A partir daqui, qualquer requisição baseada em HttpURLConnection tentará usar este proxy e estas credenciais
// Exemplo: o Jsoup usará isso implicitamente.
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
O Apache HttpClient oferece métodos robustos e flexíveis para fazer requisições HTTP e é amplamente usado em integrações complexas. Ele suporta configuração explícita de proxy por instância de cliente.
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 o host do proxy
HttpHost proxy = new HttpHost("proxy.example.com", 8080, "http"); // ou "https" ou "socks"
// 2. Configura a requisição com o proxy
RequestConfig config = RequestConfig.custom()
.setProxy(proxy)
.build();
// 3. (Opcional) Para proxy autenticado: provedor de credenciais
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass"));
// 4. Constrói o HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(config)
.setDefaultCredentialsProvider(credentialsProvider) // Para proxies autenticados
.build();
// 5. Executa a requisição
HttpGet request = new HttpGet("http://httpbin.org/get");
request.setConfig(config); // Garante que a requisição use a configuração
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 o host do proxy
HttpHost proxy = new HttpHost("http", "proxy.example.com", 8080); // Esquema, host, porta
// 2. (Opcional) Para proxy autenticado: provedor de credenciais
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(proxy.getHostName(), proxy.getPort()),
new UsernamePasswordCredentials("proxyuser", "proxypass".toCharArray()));
// 3. Constrói o HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(proxy) // Define o proxy diretamente no builder do cliente
.setDefaultCredentialsProvider(credentialsProvider) // Para proxies autenticados
.build();
// 4. Executa a requisição
HttpGet request = new HttpGet("http://httpbin.org/get");
// O RequestConfig ainda pode ser usado para sobrescritas por requisição, se necessário
RequestConfig requestConfig = RequestConfig.custom()
// .setProxy(proxy) // Também pode ser definido aqui para um proxy por requisição
.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
O Jsoup é uma biblioteca Java para trabalhar com HTML do mundo real. Ele oferece uma API simples para buscar URLs e fazer parsing de HTML. A interface Connection do Jsoup permite configurar o proxy diretamente.
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 {
// Método 1: usando 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");
// Método 2: usando o objeto java.net.Proxy
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();
}
// Para proxies autenticados, o Jsoup depende das propriedades de sistema globais do Java e do Authenticator.
// Veja a seção "Configuração global de proxy" para detalhes.
}
}
Para proxies autenticados com o Jsoup, a abordagem recomendada é configurar as propriedades de sistema globais do Java e o java.net.Authenticator, como demonstrado na seção "Configuração global de proxy". O HttpURLConnection interno do Jsoup então herdará essas configurações.
Selenium WebDriver
O Selenium automatiza navegadores web. A configuração de proxy no Selenium WebDriver normalmente é feita por meio de opções específicas de cada navegador.
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) {
// Define o caminho para o executável do ChromeDriver
// 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); // Para tráfego HTTP
proxy.setSslProxy(proxyAddress); // Para tráfego HTTPS (normalmente o mesmo do HTTP)
proxy.setSocksProxy(proxyAddress); // Para tráfego SOCKS
// proxy.setSocksUsername("socksuser"); // Para autenticação SOCKS5
// proxy.setSocksPassword("sockspass");
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", proxy);
// options.addArguments("--proxy-server=" + proxyAddress); // Alternativa para proxy HTTP/HTTPS simples
WebDriver driver = new ChromeDriver(options);
try {
driver.get("http://httpbin.org/get");
System.out.println("Page title: " + driver.getTitle());
// Demais interações com a página...
} 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) {
// Define o caminho para o executável do GeckoDriver
// 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();
}
}
}
Autenticação de proxy no Selenium
O Selenium WebDriver, por si só, não trata diretamente a autenticação de proxy (usuário/senha para proxies HTTP/HTTPS). As abordagens mais comuns incluem:
- Extensões de navegador: use uma extensão de navegador que trate a autenticação de proxy. Essas extensões podem ser carregadas via
ChromeOptionsouFirefoxOptions. - Proxy na URL: em alguns proxies HTTP, as credenciais podem ser embutidas na URL do proxy (por exemplo,
user:[email protected]:8080), mas isso não é universalmente suportado nem seguro. - Autenticação SOCKS5: a classe
Proxydo Selenium suportasetSocksUsername()esetSocksPassword()para proxies SOCKS5. - Servidor proxy upstream: roteie o tráfego por outro servidor proxy local (por exemplo, BrowserMob Proxy) que faça a autenticação com o proxy de destino.
Comparação dos métodos de configuração de proxy
| Recurso | Propriedades de sistema do Java (-D) |
Apache HttpClient (4.x/5.x) | Jsoup (.proxy()) |
Selenium WebDriver (classe Proxy) |
|---|---|---|---|---|
| Escopo | Global (toda a JVM) | Por instância de HttpClient |
Por instância de Connection |
Por instância de WebDriver |
| Autenticação | java.net.Authenticator (global) |
CredentialsProvider (por cliente) |
java.net.Authenticator (se global) |
SOCKS5 (setSocksUsername/Password); HTTP/HTTPS geralmente via extensões/ferramentas externas |
| Flexibilidade | Baixa (afeta todas as conexões java.net) |
Alta (controle granular, configuração por requisição) | Moderada (por conexão, mas depende do global para autenticação) | Alta (opções específicas do navegador, autenticação SOCKS) |
| Facilidade de uso | Alta (propriedades simples) | Moderada a alta (exige mais código) | Alta (chamadas de método simples) | Moderada (exige criar o objeto Proxy e definir as opções) |
| Protocolos suportados | HTTP, HTTPS, SOCKS | HTTP, HTTPS, SOCKS | HTTP, HTTPS (via HttpURLConnection) |
HTTP, HTTPS, SOCKS (recursos do navegador) |
| Casos de uso | Necessidades de proxy simples e uniformes no app | Interações HTTP complexas, clientes de API | Web scraping, busca simples de páginas | Automação de navegador, testes, web scraping |
