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

308

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

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

Леонель
источник
Документация Oracle по этому поводу выглядит довольно устаревшей (хотя, вероятно, все еще действительной). Вот что - то более современное с весны: docs.spring.io/spring-integration/reference/html/...
nobar

Ответы:

350

Из документации 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"
Леонель
источник
109
+1. Также не забывайте http.nonProxyHostsсобственность! (использование так: -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Томалак
3
Привет, ребята, как вы можете включить в это имя пользователя и пароль? Спасибо
Joeblackdev
8
@Joeblackdev посмотрите на http.proxyUser и http.proxyPassword
aasukisuki
4
@aasukisuki http.proxyUserи http.proxyPasswordне являются системными свойствами Java. Они для HTTP-клиента Apache.
Маркиз Лорн
24
Также не забудьте настроить https.proxyHostи https.proxyPortдля HTTP.
C-Otto
103

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

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

GR5
источник
Потрясающая настройка JVM аргументация работает для меня как очарование .. Спасибо
nanosoft
Я использовал этот код для отключения прокси по значению «false» на моем SSLSocket. Спасибо.
Fer
1
Возможно, это потому, что мой прокси-сервер требует аутентификации, но у меня это не сработало. Я хотел бы это сделал.
Саймон Форсберг
3
Это не работает с прокси - Auto-Config (PAC) файлы, см stackoverflow.com/questions/10324996/...
Michael_S
80

Чтобы установить 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-прокси работают на разных уровнях сетевого стека, поэтому вы можете использовать один или другой или оба.

Крис Каррутерс
источник
4
Если установлены «java.net.socks.username / password», зачем также устанавливать Аутентификатор?
Маркиз Лорн
1
почему не "con.setRequest ...", мошенник не распознается. Какие библиотеки для этого нужны.
Ранднум
1
+1 для опции прокси socks, так как иногда http прокси не может решить мою проблему
manuzhang
1
В моем тестировании это работает, если вы устанавливаете только Аутентификатор по умолчанию - нет необходимости устанавливать свойства аутентификации
Дрю Стивенс,
1
Не работает, если вы только системные свойства. Метинкс свойства java.net.socks. (Имя пользователя | пароль) ничего не делают.
Дрю Стивенс
46

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

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

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

GHAD
источник
34
"proxySet" ничего не делает. Доказательство: установите «false». В JDK такой собственности нет и никогда не было, несмотря на различные книги и онлайн-ссылки. Это произошло от давно не существовавшего HotJavaBean, инкапсулированного браузера, умершего примерно в 1998 году.
Маркиз Лорн,
2
Действительно ли имена свойств без http / https?
Бетлиста
18
Это неправильно по трем причинам: 1: как уже упоминалось, нет элемента "proxySet"; 2: «proxyHost» и «proxyPort» должны быть «http.proxyHost» и «http.proxyPort» (или эквивалентными «https»); 3:. System.getProperties () положим (X, Y) является не такой же , как System.setProperty (X, Y). Но кроме этого - отличный ответ.
Роб Крэнфилл
Почти правильно. Смотрите: memorynotfound.com/configure-http-proxy-settings-java
csvan
1
@RobCranfill 1: «proxySet» раньше был нестандартным флагом, который был нужен старому JDK, но больше не нужен; 2: «proxyHost» и «proxyPort» работают, «http». префикс просто ограничивает их протоколом HTTP (аналогично «https.»), 3: здесь вы правы.
инструментальный инструмент
24

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

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

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

System.setProperty("java.net.useSystemProxies", "true");
Сарат
источник
Используйте System.setPropertyвместоSystem.getProperties().put(...)
Саймон Форсберг
12

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

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

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

ProxyAuthenticator.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;
    }
}

Example.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

Алекс. С.
источник
это не работает. если вы еще не аутентифицированы, первая строка в основной функции получает кучу нулевых значений, и код останавливается. Это не помогает кому-то аутентифицировать свой jvm, чтобы он мог совершать URL-вызовы через прокси.
Ранднум
12

Сочетание ответов Сортера и Джавабретта / Леонеля:

java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar
Bamboomy
источник
10

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

export JAVA_TOOL_OPTIONS + = "-Djava.net.useSystemProxies = true"

Михай Капотэ
источник
9

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

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

Но учтите это

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

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т. Д.

Андреас Панайотидис
источник
5
ProxyUser и proxyPassword - это не системные свойства Java, а свойства HTTP-клиента Apache, поэтому это работает не во всех случаях.
THelper
8

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

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

См. Http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files.

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

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

Джон М
источник
7

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

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();
Pallavi
источник
5

Если вы хотите «Socks Proxy», сообщите аргументы VM «socksProxyHost» и «socksProxyPort».

например

java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main
Марсело С.
источник
4

Добавьте это, прежде чем подключаться к 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");
сортировщик
источник
4
http.proxyUserи http.proxyPasswordне являются системными свойствами Java. Они для HTTP-клиента Apache.
маркиз Лорн
Используйте System.setPropertyвместоSystem.getProperties().put(...)
Саймон Форсберг
4

Это незначительное обновление, но, начиная с 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

Филипп М.
источник
2
Это начиная с Java 1.5, а не 1.7.
маркиз Лорн
3

Недавно я обнаружил способ разрешить 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;
    }
}

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

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

dma_k
источник
1
Хотелось бы, чтобы я высказал это несколько раз, это единственное решение, которое сработало для меня; Спасибо! Мне пришлось скачать jar-файл регистрации Apache Commons отсюда: commons.apache.org/proper/commons-logging/download_logging.cgi Мой код в Main (): System.setProperty ("java.net.useSystemProxies", "true") ; System.out.println («обнаружение прокси»); ExtendedProxyManager.init ();
Борис
Какое xbootclasspathвлияние окажет указание на deploy.jar, не могу ли я перенести этот jar на мой обычный classpath (при работе без веб-запуска)?
Хаутман
1
в JDK 9 это терпит неудачу :( Exception in thread "main" java.lang.IllegalAccessError: class ...) cannot access class com.sun.deploy.net.proxy.DeployProxySelector (in module jdk.deploy) because module jdk.deploy does not export com.sun.deploy.net.proxy
Houtman
2

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

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.

Вьет Тран
источник
Этот ответ не дает ничего такого, что еще не было сказано в других ответах.
Саймон Форсберг
1

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

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

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

patdevelop
источник
-1

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


источник
-5

Я думаю, что настройка WINHTTP также будет работать.

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

нилас
источник