Conexão através de servidores proxy no Java principal
1. Introdução
Servidores proxy atuam como intermediários entre aplicativos clientes e outros servidores. Em um ambiente corporativo, costumamos usá-los para ajudar a fornecer controle sobre o conteúdo que os usuários consomem, geralmente através dos limites da rede.
Neste tutorial, veremoshow to connect through proxy servers in Java.
Primeiro, vamos explorar a abordagem mais antiga e mais global que abrange toda a JVM e é configurada com propriedades do sistema. Posteriormente, apresentaremos a classeProxy, que nos dá mais controle ao permitir a configuração por conexão.
2. Configuração
Para executar os exemplos neste artigo, precisaremos acessar um servidor proxy. Squid é uma implementação popular que está disponível para a maioria dos sistemas operacionais. A configuração padrão do Squid será boa o suficiente para a maioria dos nossos exemplos.
3. Usando uma configuração global
Java expõe um conjunto de propriedades do sistema que podem ser usadas para configurar o comportamento da JVM. Essa abordagem de "tamanho único" costuma ser a mais simples de implementar, se for apropriada para o caso de uso.
Podemosset the required properties from the command line when invoking the JVM. Como alternativa, também podemosset them by calling System.setProperty() at runtime.
3.1. Propriedades de sistema disponíveis
Java fornece manipuladores de proxy para os protocolos HTTP, HTTPS, FTP e SOCKS. Um proxy pode ser definido para cada manipulador como um nome de host e número de porta:
-
http.proxyHost - O nome do host do servidor proxy HTTP
-
http.proxyPort - o número da porta do servidor proxy HTTP - a propriedade é opcional e o padrão é 80 se não for fornecida
-
http.nonProxyHosts - uma lista delimitada por barras verticais (“|”) de padrões de host para os quais o proxy deve ser ignorado - aplica-se aos manipuladores HTTP e HTTPS, se definido
-
socksProxyHost - O nome do host do servidor proxy SOCKS
-
socksProxyPort - O número da porta do servidor proxy SOCKS
Se especificarnonProxyHosts, os padrões do host podem começar ou terminar com um caractere curinga (“*”). Pode ser necessário escapar do "|" delimitador nas plataformas Windows. Uma lista exaustiva de todas as propriedades de sistema relacionadas ao proxy disponíveis pode ser encontrada emOracle’s official Java documentation on networking properties.
3.2. Definido por meio de argumentos de linha de comando
Podemos definir proxies na linha de comando passando as configurações como propriedades do sistema:
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.example.networking.proxies.CommandLineProxyDemo
Ao iniciar um processo desta forma, podemos simplesmente usaropenConnection() emURL sem nenhum trabalho adicional:
URL url = new URL(RESOURCE_URL);
URLConnection con = url.openConnection();
3.3. Definir usandoSystem.setProperty(String, String)
Se não formos capazes de definir as propriedades do proxy na linha de comando, podemos defini-las com chamadas paraSystem.setProperty() em nosso programa:
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");
URL url = new URL(RESOURCE_URL);
URLConnection con = url.openConnection();
// ...
Se posteriormente desarmarmos manualmente as propriedades relevantes do sistema, o proxy não será mais usado:
System.setProperty("http.proxyHost", null);
3.4. Limitações da configuração global
Embora o uso de uma configuração global com propriedades do sistema seja fácil de implementar, essa abordagemlimits what we can do because the settings apply across the entire JVM. Por esse motivo, as configurações definidas para um protocolo específico permanecem ativas durante a vida útil da JVM ou até que sejam desativadas.
Para contornar essa limitação, pode ser tentador ativar e desativar as configurações conforme necessário. Para fazer isso com segurança em um programa multithread, seria necessário introduzir medidas para proteger contra problemas de simultaneidade.
Como alternativa,the Proxy API provides more granular control over proxy configuration.
4. Usando a APIProxy
A classeProxy nos oferece uma maneira flexível de configurar proxies por conexão. Se houver alguma configuração de proxy em toda a JVM, as configurações de proxy com base em conexão usando a classeProxy as substituirão.
Existem três tipos de proxies que podemos definir porProxy.Type:
-
HTTP - um proxy usando o protocolo HTTP
-
SOCKS - um proxy usando o protocolo SOCKS
-
DIRECT - uma conexão direta explicitamente configurada sem um proxy
4.1. Usando um proxy HTTP
Para usar um proxy HTTP, primeirowrap a SocketAddress instance with a Proxy and type of Proxy.Type.HTTP. Em seguida, simplesmente passamos a instânciaProxy paraURLConnection.openConnection():
URL weburl = new URL(URL_STRING);
Proxy webProxy
= new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3128));
HttpURLConnection webProxyConnection
= (HttpURLConnection) weburl.openConnection(webProxy);
Simplificando, isso significa que vamos nos conectar aURL_STRING, mas, em seguida, rotear essa conexão por meio de um servidor proxy hospedado em127.0.0.1:3128.
4.2. Usando um proxy DIRETO
Podemos ter um requisito para conectar-se diretamente a um host. Neste caso, podemos explicitamente a instânciabypass a proxy that may be configured globally by using the static Proxy.NO_PROXY. Nos bastidores, a API constrói uma nova instância deProxy para nós, usandoProxy.Type.DIRECT como o tipo:
HttpURLConnection directConnection
= (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);
Basicamente, se não houver um proxy configurado globalmente, é o mesmo que chamaropenConnection() em argumentos.
4.3. Usando um proxy SOCKS
Usar um proxy SOCKS é semelhante à variante HTTP ao trabalhar comURLConnection. Começamos porwrapping a SocketAddress instance with a Proxy using a type of Proxy.Type.SOCKS. Depois, passamos a instânciaProxy paraURLConnection.openConnection:
Proxy socksProxy
= new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080));
HttpURLConnection socksConnection
= (HttpURLConnection) weburl.openConnection(socksProxy);
Também é possíveluse a SOCKS proxy when connecting to a TCP socket. Primeiro, usamos a instânciaProxy para construir umSocket. Depois disso, nóspass the destination SocketAddress instance to Socket.connect():
Socket proxySocket = new Socket(socksProxy);
InetSocketAddress socketHost
= new InetSocketAddress(SOCKET_SERVER_HOST, SOCKET_SERVER_PORT);
proxySocket.connect(socketHost);
5. Conclusão
Neste artigo, vimos como trabalhar com servidores proxy no Java principal.
Primeiro, analisamos o estilo mais antigo e global de conectar-se através de servidores proxy usando as propriedades do sistema. Em seguida, vimos como usar a classeProxy, que fornece controle refinado ao se conectar por meio de servidores proxy.
Como sempre, todo o código-fonte usado neste artigo pode ser encontrado emon GitHub.