Conexión a través de servidores proxy en Core Java

1. Introducción

Los servidores proxy actúan como intermediarios entre las aplicaciones cliente y otros servidores. En un entorno empresarial, a menudo los usamos para ayudar a proporcionar control sobre el contenido que consumen los usuarios, generalmente a través de los límites de la red.

En este tutorial, veremos cómo conectarse a través de servidores proxy en Java .

Primero, exploraremos el enfoque más antiguo y más global que abarca toda la JVM y está configurado con propiedades del sistema. Luego, presentaremos la clase Proxy , que nos da más control al permitir la configuración por conexión.

2. Configuración

Para ejecutar los ejemplos de este artículo, necesitaremos acceso a un servidor proxy. Squid es una implementación popular que está disponible para la mayoría de los sistemas operativos. La configuración predeterminada de Squid será lo suficientemente buena para la mayoría de nuestros ejemplos.

3. Uso de una configuración global

Java expone un conjunto de propiedades del sistema que se pueden utilizar para configurar el comportamiento de toda la JVM. Este enfoque de “talla única” es a menudo el más sencillo de implementar si es apropiado para el caso de uso.

Podemos establecer las propiedades requeridas desde la línea de comandos al invocar la JVM . Como alternativa, también podemos configurarlos llamando a System.setProperty () en tiempo de ejecución .

3.1. Propiedades del sistema disponibles

Java proporciona controladores de proxy para los protocolos HTTP, HTTPS, FTP y SOCKS. Se puede definir un proxy para cada controlador como un nombre de host y un número de puerto:

  • http.proxyHost : el nombre de host del servidor proxy HTTP
  • http.proxyPort : el número de puerto del servidor proxy HTTP; la propiedad es opcional y el valor predeterminado es 80 si no se proporciona
  • http.nonProxyHosts : una lista delimitada por tuberías ("|") de patrones de host para los que se debe omitir el proxy; se aplica tanto a los controladores HTTP como a HTTPS, si se configuran
  • socksProxyHost : el nombre de host del servidor proxy SOCKS
  • socksProxyPort : el número de puerto del servidor proxy SOCKS

Si especifica nonProxyHosts , los patrones de host pueden comenzar o terminar con un carácter comodín ("*"). Puede que sea necesario escapar del "|" delimitador en plataformas Windows. Se puede encontrar una lista exhaustiva de todas las propiedades del sistema relacionadas con el proxy disponibles en la documentación oficial de Java de Oracle sobre propiedades de red.

3.2. Establecer mediante argumentos de línea de comando

Podemos definir proxies en la línea de comando pasando la configuración como propiedades del sistema:

java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 com.baeldung.networking.proxies.CommandLineProxyDemo

Al iniciar un proceso de esta manera, podemos simplemente usar openConnection () en la URL sin ningún trabajo adicional:

URL url = new URL(RESOURCE_URL); URLConnection con = url.openConnection();

3.3. Establecer usando System.setProperty (String, String)

Si no podemos configurar las propiedades del proxy en la línea de comando, podemos configurarlas con llamadas a System.setProperty () dentro de nuestro programa:

System.setProperty("http.proxyHost", "127.0.0.1"); System.setProperty("http.proxyPort", "3128"); URL url = new URL(RESOURCE_URL); URLConnection con = url.openConnection(); // ...

Si posteriormente desarmamos las propiedades relevantes del sistema manualmente, el proxy ya no se utilizará:

System.setProperty("http.proxyHost", null);

3.4. Limitaciones de la configuración global

Aunque el uso de una configuración global con propiedades del sistema es fácil de implementar, este enfoque limita lo que podemos hacer porque la configuración se aplica en toda la JVM . Por esta razón, las configuraciones definidas para un protocolo en particular están activas durante la vida útil de la JVM o hasta que se anulan.

Para evitar esta limitación, puede ser tentador activar y desactivar la configuración según sea necesario. Para hacer esto de forma segura en un programa de subprocesos múltiples, sería necesario introducir medidas para proteger contra problemas de concurrencia.

Como alternativa, la API de proxy proporciona un control más granular sobre la configuración del proxy.

4. Usando la API de proxy

La clase Proxy nos brinda una forma flexible de configurar proxies por conexión. Si existe alguna configuración de proxy para toda la JVM, la configuración de proxy basada en la conexión que utiliza la clase Proxy la anulará.

Hay tres tipos de proxies que podemos definir por Proxy.Type :

  • HTTP : un proxy que utiliza el protocolo HTTP
  • SOCKS : un proxy que utiliza el protocolo SOCKS
  • DIRECTO : una conexión directa configurada explícitamente sin un proxy

4.1. Usando un proxy HTTP

Para usar un proxy HTTP, primero empaquetamos una instancia de SocketAddress con un Proxy y un tipo de Proxy.Type.HTTP . A continuación, simplemente pasamos la instancia de Proxy a URLConnection.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);

En pocas palabras, esto significa que nos conectaremos a URL_STRING , pero luego enrutaremos esa conexión a través de un servidor proxy alojado en 127.0.0.1:3128 .

4.2. Usando un proxy DIRECTO

Es posible que tengamos el requisito de conectarnos directamente a un host. En este caso, podemos omitir explícitamente un proxy que se puede configurar globalmente utilizando la instancia estática Proxy.NO_PROXY . Bajo las sábanas, la API construye una nueva instancia de Proxy para nosotros, usando Proxy.Type.DIRECT como el tipo :

HttpURLConnection directConnection = (HttpURLConnection) weburl.openConnection(Proxy.NO_PROXY);

Básicamente, si no hay un proxy configurado globalmente, esto es lo mismo que llamar a openConnection () sin argumentos.

4.3. Usar un proxy SOCKS

Using a SOCKS proxy is similar to the HTTP variant when working with URLConnection. We start by wrapping a SocketAddress instance with a Proxy using a type of Proxy.Type.SOCKS. Afterward, we pass the Proxy instance to URLConnection.openConnection:

Proxy socksProxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080)); HttpURLConnection socksConnection = (HttpURLConnection) weburl.openConnection(socksProxy); 

It's also possible to use a SOCKS proxy when connecting to a TCP socket. First, we use the Proxy instance to construct a Socket. Afterward, we pass 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. Conclusion

In this article, we looked at how to work with proxy servers in core Java.

En primer lugar, analizamos el estilo más antiguo y más global de conectarse a través de servidores proxy utilizando propiedades del sistema. Luego, vimos cómo usar la clase Proxy , que proporciona un control detallado cuando se conecta a través de servidores proxy.

Como siempre, todo el código fuente utilizado en este artículo se puede encontrar en GitHub.