Подключение через прокси-серверы в Core Java

Подключение через прокси-серверы в Core Java

1. Вступление

Прокси-серверы выступают в качестве посредников между клиентскими приложениями и другими серверами. В корпоративных условиях мы часто используем их, чтобы обеспечить контроль над контентом, который потребляют пользователи, обычно за пределами сети.

В этом руководстве мы рассмотримhow to connect through proxy servers in Java.

Во-первых, мы рассмотрим более старый, более глобальный подход, охватывающий всю JVM и настраиваемый с помощью системных свойств. После этого мы представим классProxy, который дает нам больше контроля, позволяя настраивать параметры для каждого соединения.

2. Настроить

Для запуска примеров из этой статьи нам понадобится доступ к прокси-серверу. Squid - популярная реализация, доступная для большинства операционных систем. Конфигурация Squid по умолчанию будет достаточно хороша для большинства наших примеров.

3. Использование глобальной настройки

Java предоставляет набор системных свойств, которые можно использовать для настройки поведения JVM. Этот «универсальный подход» зачастую проще всего реализовать, если он подходит для конкретного случая использования.

Мы можемset the required properties from the command line when invoking the JVM. В качестве альтернативы мы также можемset them by calling System.setProperty() at runtime.

3.1. Доступные системные свойства

Java предоставляет обработчики прокси для протоколов HTTP, HTTPS, FTP и SOCKS. Прокси может быть определен для каждого обработчика как имя хоста и номер порта:

  • http.proxyHost - имя хоста прокси-сервера HTTP

  • http.proxyPort - Номер порта прокси-сервера HTTP - свойство не является обязательным и по умолчанию равно 80, если не указано.

  • http.nonProxyHosts - разделенный вертикальной чертой («|») список шаблонов узлов, для которых прокси-сервер должен быть пропущен - применяется как для обработчиков HTTP, так и для HTTPS, если установлено

  • socksProxyHost - имя хоста прокси-сервера SOCKS

  • socksProxyPort - Номер порта прокси-сервера SOCKS

Если указанnonProxyHosts, шаблоны хоста могут начинаться или заканчиваться символом подстановки («*»). Может потребоваться отключить разделитель «|» на платформах Windows. Исчерпывающий список всех доступных свойств системы, связанных с прокси, можно найти вOracle’s official Java documentation on networking properties.

3.2. Установить с помощью аргументов командной строки

Мы можем определить прокси в командной строке, передав настройки в качестве системных свойств:

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

При запуске процесса таким образом мы можем просто использоватьopenConnection() наURL без дополнительной работы:

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

3.3. Установить с использованиемSystem.setProperty(String, String)

Если мы не можем установить свойства прокси в командной строке, мы можем установить их с помощью вызововSystem.setProperty() в нашей программе:

System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "3128");

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

Если позже мы вручную сбросим соответствующие системные свойства, прокси больше не будет использоваться:

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

3.4. Ограничения глобальной конфигурации

Хотя использование глобальной конфигурации со свойствами системы легко реализовать, этот подходlimits what we can do because the settings apply across the entire JVM. По этой причине настройки, определенные для определенного протокола, активны в течение всего срока службы JVM или до тех пор, пока они не будут отменены.

Чтобы обойти это ограничение, может быть заманчиво включать и выключать настройки по мере необходимости. Чтобы сделать это безопасно в многопоточной программе, необходимо будет принять меры для защиты от проблем параллелизма.

В качестве альтернативыthe Proxy API provides more granular control over proxy configuration.

4. Использование APIProxy

КлассProxy дает нам гибкий способ настройки прокси для каждого соединения. Если есть какие-либо существующие настройки прокси для всей JVM, настройки прокси на основе подключения с использованием классаProxy переопределят их.

Есть три типа прокси, которые мы можем определить с помощьюProxy.Type:

  • HTTP - прокси, использующий протокол HTTP

  • SOCKS - прокси, использующий протокол SOCKS

  • DIRECT - явно настроенное прямое соединение без прокси

4.1. Использование прокси-сервера HTTP

Чтобы использовать прокси-сервер HTTP, мы сначалаwrap a SocketAddress instance with a Proxy and type of Proxy.Type.HTTP. Затем мы просто передаем экземплярProxy в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);

Проще говоря, это означает, что мы подключимся кURL_STRING, но затем направим это соединение через прокси-сервер, расположенный на127.0.0.1:3128.

4.2. Использование ПРЯМОГО прокси

У нас может быть требование подключиться напрямую к хосту. В этом случае мы можем явно использоватьbypass a proxy that may be configured globally by using the static Proxy.NO_PROXY instance. Под покровом API создает для нас новый экземплярProxy, используяProxy.Type.DIRECT в качестве типа:.

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

В принципе, если нет глобально настроенного прокси, это то же самое, что и вызовopenConnection() w без аргументов.

4.3. Использование прокси-сервера SOCKS

Использование прокси-сервера SOCKS аналогично варианту HTTP при работе сURLConnection.. Начнем сwrapping a SocketAddress instance with a Proxy using a type of Proxy.Type.SOCKS. После этого мы передаем экземплярProxy вURLConnection.openConnection:

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

Также возможноuse a SOCKS proxy when connecting to a TCP socket. Сначала мы используем экземплярProxy, чтобы построитьSocket. После этого мы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. Заключение

В этой статье мы рассмотрели, как работать с прокси-серверами в ядре Java.

Сначала мы рассмотрели более старый, более глобальный стиль подключения через прокси-серверы с использованием системных свойств. Затем мы увидели, как использовать классProxy, который обеспечивает детальный контроль при подключении через прокси-серверы.

Как всегда, весь исходный код, используемый в этой статье, можно найти вon GitHub.