Как настроить прокси для использования JVM

StackOverflow https://stackoverflow.com/questions/120797

  •  02-07-2019
  •  | 
  •  

Вопрос

Часто приложению Java требуется подключение к Интернету.Самый распространенный пример — когда он читает XML-файл и ему необходимо загрузить его схему.

Я нахожусь за прокси-сервером.Как я могу настроить JVM на использование прокси?

Это было полезно?

Решение

Из документации Java (нет API javadoc):

http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html

Установите флаги JVM http.proxyHost и http.proxyPort при запуске JVM в командной строке.Обычно это делается с помощью сценария оболочки (в Unix) или bat-файла (в Windows).Вот пример сценария оболочки Unix:

JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...

При использовании таких контейнеров, как JBoss или WebLogic, мое решение — отредактировать сценарии запуска, предоставленные поставщиком.

Многие разработчики знакомы с Java API (javadocs), но часто упускают из виду остальную документацию.Содержит много интересной информации: http://download.oracle.com/javase/6/docs/technotes/guides/


Обновлять : Если вы не хотите использовать прокси для разрешения некоторых хостов локальной/интранет-сети, прочтите комментарий @Tomalak:

Также не забудьте свойство http.nonProxyHosts!

-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com‌​|etc"

Другие советы

Чтобы использовать настройку системного прокси:

java -Djava.net.useSystemProxies=true ...

Или программно:

System.setProperty("java.net.useSystemProxies", "true");

Источник: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html

Чтобы программно установить прокси-сервер HTTP/HTTPS и/или SOCKS:

...

public void setProxy() {
    if (isUseHTTPProxy()) {
        // HTTP/HTTPS Proxy
        System.setProperty("http.proxyHost", getHTTPHost());
        System.setProperty("http.proxyPort", getHTTPPort());
        System.setProperty("https.proxyHost", getHTTPHost());
        System.setProperty("https.proxyPort", getHTTPPort());
        if (isUseHTTPAuth()) {
            String encoded = new String(Base64.encodeBase64((getHTTPUsername() + ":" + getHTTPPassword()).getBytes()));
            con.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
            Authenticator.setDefault(new ProxyAuth(getHTTPUsername(), getHTTPPassword()));
        }
    }
    if (isUseSOCKSProxy()) {
        // SOCKS Proxy
        System.setProperty("socksProxyHost", getSOCKSHost());
        System.setProperty("socksProxyPort", getSOCKSPort());
        if (isUseSOCKSAuth()) {
            System.setProperty("java.net.socks.username", getSOCKSUsername());
            System.setProperty("java.net.socks.password", getSOCKSPassword());
            Authenticator.setDefault(new ProxyAuth(getSOCKSUsername(), getSOCKSPassword()));
        }
    }
}

...

public class ProxyAuth extends Authenticator {
    private PasswordAuthentication auth;

    private ProxyAuth(String user, String password) {
        auth = new PasswordAuthentication(user, password == null ? new char[]{} : password.toCharArray());
    }

    protected PasswordAuthentication getPasswordAuthentication() {
        return auth;
    }
}

...

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

Вы можете установить эти флаги программно следующим образом:

if (needsProxy()) {
    System.setProperty("http.proxyHost",getProxyHost());
    System.setProperty("http.proxyPort",getProxyPort());
} else {
    System.setProperty("http.proxyHost","");
    System.setProperty("http.proxyPort","");
}

Просто верните правильные значения из методов needsProxy(), getProxyHost() и getProxyPort() и вы можете вызывать этот фрагмент кода, когда захотите.

JVM использует прокси для выполнения HTTP-вызовов

System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");

Это может использовать прокси-сервер настроек пользователя

System.setProperty("java.net.useSystemProxies", "true");

Вы можете установить некоторые свойства прокси-сервера в качестве параметров jvm.

-Dhttp.proxyPort=8080, proxyHost и т. д.

но если вам нужно пройти через прокси-сервер аутентификации, вам понадобится аутентификатор, подобный этому примеру:

ПроксиАутентификатор.java

import java.net.*;
import java.io.*;

public class ProxyAuthenticator extends Authenticator {

    private String userName, password;

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(userName, password.toCharArray());
    }

    public ProxyAuthenticator(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }
}

Пример.java

    import java.net.Authenticator;
    import ProxyAuthenticator;

public class Example {

    public static void main(String[] args) {
        String username = System.getProperty("proxy.authentication.username");
        String password = System.getProperty("proxy.authentication.password");

                if (username != null && !username.equals("")) {
            Authenticator.setDefault(new ProxyAuthenticator(username, password));
        }

                // here your JVM will be authenticated

    }
}

На основании этого ответа:http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

Объединение ответов Сортера и Джавабретта/Леонела:

java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar

читает XML-файл и ему необходимо загрузить его схему

Если вы рассчитываете получить схемы или DTD через Интернет, вы создаете медленное, болтливое и хрупкое приложение.Что произойдет, если удаленный сервер, на котором размещен файл, выйдет из строя в плановом или внеплановом режиме?Ваше приложение ломается.Это нормально?

Видеть http://xml.apache.org/commons/comComponents/resolver/resolver-article.html#s.catalog.files

URL-адреса схем и т.п. лучше всего рассматривать как уникальные идентификаторы.Не как запросы на удаленный доступ к этому файлу.Выполните поиск в Google по «Каталогу XML».Каталог XML позволяет размещать такие ресурсы локально, устраняя медлительность, болтливость и хрупкость.

По сути, это постоянно кэшированная копия удаленного контента.И это нормально, поскольку удаленный контент никогда не изменится.Если когда-либо появится обновление, оно будет по другому URL-адресу.Делать фактический поиск ресурса через Интернет особенно глупым.

Установить java.net.useSystemProxies собственность true.Вы можете установить его, например, через JAVA_TOOL_OPTIONS переменная окружающей среды.В Ubuntu вы можете, например, добавить следующую строку в .bashrc:

экспорт JAVA_TOOL_OPTIONS+=" -Djava.net.useSystemProxies=true"

Я тоже за брандмауэром, у меня это сработало!!

System.setProperty("http.proxyHost", "proxy host addr");
System.setProperty("http.proxyPort", "808");
Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {

        return new PasswordAuthentication("domain\\user","password".toCharArray());
    }
});

URL url = new URL("http://www.google.com/");
URLConnection con = url.openConnection();

BufferedReader in = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));

// Read it ...
String inputLine;
while ((inputLine = in.readLine()) != null)
    System.out.println(inputLine);

in.close();

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

Передача системных свойств в командной строке с помощью -D и установка их в коде с помощью System.setProperty("name", "value") эквивалентны.

Но обратите внимание на это

Пример, который работает:

C:\temp>java -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit com.andreas.JavaNetHttpConnection

Но следующее не работает

C:\temp>java com.andreas.JavaNetHttpConnection -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit

Единственная разница – это расположение системных свойств!(до и после занятий)

Если в вашем пароле есть специальные символы, вы можете заключить его в кавычки «@MyPass123%», как в приведенном выше примере.

Если вы получаете доступ к службе HTTPS, вам необходимо использовать https.proxyHost, https.proxyPort и т. д.

Если вы получаете доступ к службе HTTP, вам необходимо использовать http.proxyHost, http.proxyPort и т. д.

Добавьте это перед подключением к URL-адресу за прокси-сервером.

System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
System.getProperties().put("http.proxyUser", "someUserName");
System.getProperties().put("http.proxyPassword", "somePassword");

Это небольшое обновление, но начиная с Java 7 прокси-соединения теперь можно создавать программно, а не через свойства системы.Это может быть полезно, если:

  1. Прокси должен динамически меняться во время выполнения программы.
  2. Необходимо использовать несколько параллельных прокси
  3. Или просто сделайте свой код чище :)

Вот надуманный пример в groovy:

// proxy configuration read from file resource under "proxyFileName"
String proxyFileName = "proxy.txt"
String proxyPort = "1234"
String url = "http://www.promised.land"
File testProxyFile = new File(proxyFileName)
URLConnection connection

if (!testProxyFile.exists()) {

    logger.debug "proxyFileName doesn't exist.  Bypassing connection via proxy."
    connection = url.toURL().openConnection()

} else {
    String proxyAddress = testProxyFile.text
    connection = url.toURL().openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort)))
}

try {
    connection.connect()
}
catch (Exception e) {
    logger.error e.printStackTrace()
}

Полная ссылка:http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html

Если вам нужен «Socks Proxy», укажите аргументы виртуальной машины «socksProxyHost» и «socksProxyPort».

например

java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main

Недавно я обнаружил способ разрешить JVM использовать настройки прокси-сервера браузера.Что вам нужно сделать, это добавить ${java.home}/lib/deploy.jar в ваш проект и инициализировать библиотеку следующим образом:

import com.sun.deploy.net.proxy.DeployProxySelector;
import com.sun.deploy.services.PlatformType;
import com.sun.deploy.services.ServiceManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class ExtendedProxyManager {

    private static final Log logger = LogFactory.getLog(ExtendedProxyManager.class);

    /**
     * After calling this method, proxy settings can be magically retrieved from default browser settings.
     */
    public static boolean init() {
        logger.debug("Init started");

        // Initialization code was taken from com.sun.deploy.ClientContainer:
        ServiceManager
                .setService(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1 ? PlatformType.STANDALONE_TIGER_WIN32
                        : PlatformType.STANDALONE_TIGER_UNIX);

        try {
            // This will call ProxySelector.setDefault():
            DeployProxySelector.reset();
        } catch (Throwable throwable) {
            logger.error("Unable to initialize extended dynamic browser proxy settings support.", throwable);

            return false;
        }

        return true;
    }
}

После этого настройки прокси-сервера доступны Java API через java.net.ProxySelector.

Единственная проблема с этим подходом заключается в том, что вам нужно запустить JVM с помощью deploy.jar в пути к загрузочному классу, например. java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar.Если кто-то знает, как обойти это ограничение, дайте мне знать.

Это подходит для меня:

public void setHttpProxy(boolean isNeedProxy) {
    if (isNeedProxy) {
        System.setProperty("http.proxyHost", getProxyHost());
        System.setProperty("http.proxyPort", getProxyPort());
    } else {
        System.clearProperty("http.proxyHost");
        System.clearProperty("http.proxyPort");
    }
}

P/S:Я основываюсь на ответе GHad.

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

Уилл Айверсон делает полезное предложение по адресу Использование HttpProxy для подключения к хосту с приоритетной аутентификацией использовать инструмент управления прокси-серверами, например Proxifier ( http://www.proxifier.com/ для Mac OS X и Windows), чтобы справиться с этим.

Например, с помощью Proxifier вы можете настроить его так, чтобы он перехватывал только Java-команды, которые будут управляться и перенаправляться через его (аутентифицированный) прокси-сервер.Однако в этом случае вам нужно будет установить значения proxyHost и proxyPort пустыми, например.пройти внутрь -Dhttp.proxyHost= -Dhttp.proxyPort= к вашим Java-командам.

Кроме того, если вы всегда хотите загружать одну и ту же схему, вы можете добавить ее в свой путь к классам (файловая система или JAR), а затем использовать собственный EntityResolver

Видеть здесь для более полного обсуждения этого подхода.

Редактировать:Видеть @me.yahoo.com/a/0QMxE's обсуждение CatalogResolver, использующего подход EntityResolver:

CatalogResolver cr = new CatalogResolver();
...
yourParser.setEntityResolver(cr) 

Вы можете использовать переменные JVM http.proxy*, если вы находитесь в автономной JVM, но вам НЕ СЛЕДУЕТ изменять их сценарии запуска и/или делать это на своем сервере приложений (за исключением, возможно, jboss или tomcat).Вместо этого вам следует использовать JAVA Proxy API (а не System.setProperty) или использовать собственные параметры конфигурации поставщика.И WebSphere, и WebLogic имеют четко определенные способы настройки прокси, которые гораздо более мощны, чем J2SE.Кроме того, для WebSphere и WebLogic вы, скорее всего, немного сломаете свой сервер приложений, переопределив сценарии запуска (особенно процессы взаимодействия сервера, поскольку вы также можете указать им использовать ваш прокси...).

Я думаю настроить ВИНHTTP тоже будет работать.

Многие программы, включая Центры обновления Windows, испытывают проблемы с прокси-сервером.Настроив WINHTTP, вы всегда сможете решить подобные проблемы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top