Як встановити проксі-сервер, який використовуватиме JVM


307

Багато разів додатку 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

102

Щоб скористатися налаштуванням системного проксі:

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


Дивовижна настройка jvm аргументація працює для мене, як шарм. Дякую
nanosoft

Я використовував цей код для відключення проксі-сервера за значенням "false" на моєму SSLSocket. Дякую.
Фер

1
Можливо, це тому, що мій проксі вимагає автентифікації, але це не спрацювало для мене. Я б хотів, щоб це було.
Саймон Форсберг

3
Це не працює з файлами Proxy 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 / пароль", чому також встановити Аутентифікатор?
Маркіз Лорн

1
чому не "con.setRequest ..." con не розпізнається. Які бібліотеки для цього потрібні.
Ранднум

1
+1 для опції proxy 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()і ви можете викликати цей фрагмент коду , коли ви хочете.


34
"proxySet" нічого не робить. Доказ: встановіть його на "false". Незважаючи на те, що в JDK не існує і ніколи не було такої власності, різні книги та посилання в Інтернеті. Він походив від давно неіснуючого HotJavaBean, інкапсульованого браузера, загинув смерть приблизно в 1998 році.
Маркіз Лорн

2
Дійсно це назви властивостей без http / https?
Betlista

18
Це неправильно в трьох значеннях: 1: як було сказано, немає елемента "proxySet"; 2: "proxyHost" і "proxyPort" повинні бути "http.proxyHost" і "http.proxyPort" (або еквівалентом "https"); 3: System.getProperties (). Put (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: тут ви праві.
toolforger

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


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, а властивості клієнта Apache HTTP, тому це працює не у всіх випадках.
Телпер

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

5

Якщо ви хочете "Socks Proxy", повідомте про аргументи "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;
    }
}

Після цього налаштування проксі доступні для Java API через java.net.ProxySelector.

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


1
Я б хотів, щоб я міг підтвердити це кілька разів, це єдине рішення, яке працювало на мене; Дякую тобі! Мені довелося завантажити банку журналу apache commons звідси: commons.apache.org/proper/commons-logging/download_logging.cgi Мій код в Main (): System.setProperty ("java.net.useSystemProxies", "true") ; System.out.println ("виявлення проксі"); ExtendedProxyManager.init ();
Борис

Що xbootclasspathвказувало б на вказівку на layout.jar, чи не можу я перенести цю банку на звичайний класний шлях (коли працює без веб-запуску)?
Хаутман

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
Хаутман

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

Як вказується в інших відповідях, якщо вам потрібно використовувати автентифіковані проксі, немає надійного способу зробити це виключно за допомогою змінних командного рядка - що дратує, якщо ви використовуєте чужу програму і не хочете возитися з вихідний код.

Вілл Іверсон робить корисну пропозицію при використанні програми HttpProxy для підключення до хоста з попередньою автентифікацією, щоб використовувати інструмент управління проксі, наприклад Proxifier ( http://www.proxifier.com/ для Mac OS X та Windows) для вирішення цього питання.

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


-1

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


-5

Я думаю, що налаштування WINHTTP також буде працювати.

У багатьох програмах, включаючи оновлення Windows, виникають проблеми із проксі. Налаштування WINHTTP завжди виправить подібні проблеми

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.