Как установить прокси-сервер, который будет использоваться JVM

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

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

Ответ 1

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

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

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

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"

Ответ 3

Программно установить прокси-сервер 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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

Вы можете установить некоторые свойства прокси-сервера как параметры 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/%[email protected]%3E

Ответ 7

Комбинируя Сортировщик и Джавабретт /Leonel отвечает:

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

Ответ 8

чтение XML файла и загрузка его схемы

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

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

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

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

Ответ 9

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

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

Ответ 10

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

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();

Ответ 11

Ниже показано, как установить в 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.proxyHost к службе HTTP, вы должны использовать http.proxyHost, http.proxyPort и т.д.

Ответ 12

Добавьте это, прежде чем подключаться к 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");

Ответ 13

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

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

Здесь надуманный пример в 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

Ответ 14

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

например.

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

Ответ 15

Недавно я открыл способ разрешить 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 в bootclasspath, например. java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. Если кто-то знает, как преодолеть это ограничение, дайте мне знать.

Ответ 16

Это работает для меня:

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.

Ответ 17

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

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

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

Ответ 18

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

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

Изменить: см. @me.yahoo.com/a/0QMxE обсуждение CatalogResolver, в котором используется подход EntityResolver:

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

Ответ 19

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

Ответ 20

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

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