Jak ustawić serwer proxy do używania przez JVM


307

Wiele razy aplikacja Java musi łączyć się z Internetem. Najczęstszy przykład ma miejsce, gdy czyta plik XML i musi pobrać jego schemat.

Jestem za serwerem proxy. Jak mogę ustawić moją JVM do używania proxy?


Dokumentacja Oracle wokół tego wydaje się dość przestarzała (choć nadal prawdopodobnie ważna). Oto coś bardziej nowoczesnego od wiosny: docs.spring.io/spring-integration/reference/html/…
nobar

Odpowiedzi:


350

Z dokumentacji Java ( nie API javadoc):

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

Ustaw flagi JVM http.proxyHosti http.proxyPortpodczas uruchamiania JVM w wierszu polecenia. Zwykle odbywa się to w skrypcie powłoki (w systemie Unix) lub w pliku bat (w systemie Windows). Oto przykład ze skryptem powłoki Uniksa:

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

Podczas korzystania z kontenerów takich jak JBoss lub WebLogic, moim rozwiązaniem jest edycja skryptów startowych dostarczonych przez dostawcę.

Wielu programistów zna Java API (javadocs), ale wiele razy reszta dokumentacji jest pomijana. Zawiera wiele interesujących informacji: http://download.oracle.com/javase/6/docs/technotes/guides/


Aktualizacja: jeśli nie chcesz używać proxy do rozwiązania niektórych hostów lokalnych / intranetowych, sprawdź komentarz z @Tomalak:

Nie zapomnij również o właściwości http.nonProxyHosts!

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

109
+1. Nie zapomnij także o http.nonProxyHostsnieruchomości! (zastosowanie tak: -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Tomalak

3
Cześć chłopaki, jak możecie dołączyć do tego nazwę użytkownika i hasło? Dzięki
Joeblackdev

8
@Jeblebldev spójrz na http.proxyUser i http.proxyPassword
aasukisuki

4
@aasukisuki http.proxyUseri http.proxyPasswordnie są właściwościami systemu Java. Są dla klienta HTTP Apache.
Markiz Lorne

24
Nie zapomnij również skonfigurować https.proxyHosti https.proxyPortdla HTTPs.
C-Otto

102

Aby użyć systemowego ustawienia proxy:

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

Lub programowo:

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

Źródło: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html


Niesamowite ustawienie argumentów Jvm działa dla mnie jak urok .. Dzięki
nanosoft

Użyłem tego kodu, aby wyłączyć proxy przez wartość „false” na moim SSLSocket. Dzięki.
Fer

1
Być może dzieje się tak, ponieważ mój serwer proxy wymaga uwierzytelnienia, ale to nie działało dla mnie. Chciałbym, żeby tak było.
Simon Forsberg

3
Nie działa to z plikami automatycznej
konfiguracji

80

Aby programowo ustawić serwer proxy HTTP / HTTPS i / lub 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;
    }
}

...

Pamiętaj, że proxy HTTP i proxy SOCKS działają na różnych poziomach w stosie sieciowym, więc możesz użyć jednego lub drugiego lub obu.


4
Jeśli ustawione są „java.net.socks.username / password”, to po co ustawiać także Authenticator?
Markiz Lorne

1
dlaczego nie jest „con.setRequest ...” oszustwo nie jest rozpoznawane. Jakie biblioteki są do tego potrzebne.
Randnum

1
+1 za opcję proxy skarpet, ponieważ czasami serwer proxy HTTP nie może rozwiązać mojego problemu
manuzhang

1
W moich testach działa, jeśli ustawisz tylko domyślny Authenticator - nie musisz ustawiać właściwości uwierzytelniania
Drew Stephens,

1
Nie działa, jeśli masz tylko właściwości systemowe. Methinks java.net.socks. (Nazwa użytkownika | hasło) nic nie robi.
Drew Stephens

46

Możesz ustawić te flagi programowo w ten sposób:

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

Wystarczy zwrócić odpowiednie wartości z metod needsProxy(), getProxyHost()a getProxyPort()można nazwać ten fragment kodu, kiedy tylko chcesz.


34
„proxySet” nic nie robi. Dowód: ustaw na „fałsz”. Nie ma i nigdy nie było takiej właściwości w JDK, pomimo różnych książek i referencji online. Pochodzi z od dawna nieistniejącego HotJavaBean, zamkniętej przeglądarki, zmarł śmiercią około 1998 roku.
Markiz Lorne

2
Naprawdę są nazwy właściwości bez http / https?
Betlista

18
Jest to błędne z trzech powodów: 1: jak wspomniano, nie ma elementu „proxySet”; 2: „proxyHost” i „proxyPort” muszą być „http.proxyHost” i „http.proxyPort” (lub odpowiednikiem „https”); 3: System.getProperty (). Put (X, Y) to nie to samo co System.setProperty (X, Y). Ale poza tym - świetna odpowiedź.
Rob Cranfill,


1
@RobCranfill 1: „proxySet” był niestandardową flagą, która była potrzebna przez stary JDK, ale nie jest już konieczna; 2: działają „proxyHost” i „proxyPort”, „http”. prefiks ogranicza je tylko do protokołu HTTP (podobnie jak w przypadku „https.”), 3: masz rację.
toolforger

24

JVM używa proxy do wykonywania połączeń HTTP

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

Może to korzystać z serwera proxy ustawień użytkownika

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

Użyj System.setPropertyzamiastSystem.getProperties().put(...)
Simon Forsberg

12

Możesz ustawić niektóre właściwości dotyczące serwera proxy jako parametry jvm

-Dhttp.proxyPort = 8080, proxyHost itp.

ale jeśli potrzebujesz przekazać przez proxy uwierzytelniające, potrzebujesz uwierzytelnienia takiego jak ten przykład:

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

    }
}

Na podstawie tej odpowiedzi: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E


to nie działa. jeśli nie jesteś jeszcze uwierzytelniony, pierwszy wiersz funkcji głównej otrzymuje wiązkę wartości zerowych i kod zatrzymuje się. To nie pomaga komuś uwierzytelnić swojego pliku Jvm, aby mógł wykonywać połączenia URL przez serwer proxy.
Randnum,

12

Łączenie odpowiedzi Sortera i javabretta / Leonela:

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


9

Poniżej pokazano, jak ustawić w Javie proxy z użytkownikiem proxy i hasłem proxy z wiersza poleceń, co jest bardzo częstym przypadkiem. Zasadniczo nie należy zapisywać haseł i hostów w kodzie.

Przekazywanie właściwości systemu w wierszu poleceń za pomocą -D i ustawianie ich w kodzie za pomocą System.setProperty („nazwa”, „wartość”) jest równoważne.

Ale zauważ to

Przykład, który działa:

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

Ale następujące działania nie działają :

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

Jedyną różnicą jest położenie właściwości systemu! (przed i po zajęciach)

Jeśli masz hasło specjalne, możesz wpisać je w cudzysłowie „@ MyPass123%”, jak w powyższym przykładzie.

Jeśli masz dostęp do usługi HTTPS, trzeba użyć https.proxyHost, https.proxyPortetc.

Jeśli masz dostęp do usługi HTTP, trzeba użyć http.proxyHost, http.proxyPortetc.


5
ProxyUser i proxyPassword nie są właściwościami systemu Java, ale właściwościami klienta Apache HTTP, więc nie we wszystkich przypadkach.
THelper

8

odczytuje plik XML i musi pobrać jego schemat

Jeśli liczysz na pobieranie schematów lub DTD przez Internet, budujesz powolną, gadatliwą, delikatną aplikację. Co się stanie, gdy zdalny serwer hostujący plik zajmie planowane lub nieplanowane przestoje? Twoja aplikacja się psuje. Czy to w porządku?

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

Adresy URL schematów i tym podobne najlepiej traktować jako unikalne identyfikatory. Nie jako żądania zdalnego dostępu do tego pliku. Wyszukaj w Google „Katalog XML”. Katalog XML pozwala hostować takie zasoby lokalnie, co rozwiązuje powolność, spryt i kruchość.

Jest to zasadniczo trwale buforowana kopia zdalnej zawartości. I to jest w porządku, ponieważ zdalna zawartość nigdy się nie zmieni. Jeśli kiedykolwiek pojawi się aktualizacja, będzie ona dostępna pod innym adresem URL. Sprawienie, by faktyczne pobieranie zasobów przez Internet było szczególnie głupie.


7

Jestem również za firewallem, to zadziałało dla mnie !!

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

Jeśli chcesz użyć „Socks Proxy”, poinformuj o argumentach maszyny wirtualnej „socksProxyHost” i „socksProxyPort”.

na przykład

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

4

Dodaj to, zanim połączysz się z adresem URL za serwerem proxy.

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.proxyUseri http.proxyPasswordnie są właściwościami systemu Java. Są dla klienta HTTP Apache.
Markiz Lorne

Użyj System.setPropertyzamiastSystem.getProperties().put(...)
Simon Forsberg

4

Jest to niewielka aktualizacja, ale od wersji Java 7 połączenia proxy można teraz tworzyć programowo, a nie za pomocą właściwości systemu. Może to być przydatne, jeśli:

  1. Serwer proxy musi być dynamicznie obracany podczas działania programu
  2. Należy użyć wielu równoległych serwerów proxy
  3. Lub po prostu uczyń swój kod czystszym :)

Oto wymyślony przykład w 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()
}

Pełny opis: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html


2
Wynika to z wersji Java 1.5, a nie 1.7.
Markiz Lorne

3

Ostatnio odkryłem sposób, w jaki JVM może korzystać z ustawień proxy przeglądarki. Musisz dodać ${java.home}/lib/deploy.jardo projektu i zainicjować bibliotekę w następujący sposób:

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

Następnie ustawienia proxy są dostępne dla Java API poprzez java.net.ProxySelector.

Jedynym problemem związanym z tym podejściem jest to, że musisz uruchomić JVM deploy.jarw ścieżce rozruchowej, np java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. Jeśli ktoś wie, jak pokonać to ograniczenie, daj mi znać.


1
Chciałbym móc to wielokrotnie głosować, to jedyne rozwiązanie, które dla mnie zadziałało; Dziękuję Ci! Musiałem pobrać słoik rejestrujący apache commons stąd: commons.apache.org/proper/commons-logging/download_logging.cgi Mój kod w Main (): System.setProperty („java.net.useSystemProxies”, „true”) ; System.out.println („wykrywanie serwerów proxy”); ExtendedProxyManager.init ();
Boris

Co xbootclasspathwskazywałoby na wdrożenie deploy.jar, czy nie mogę przenieść tego słoika na moją normalną ścieżkę klasy (podczas uruchamiania bez uruchamiania sieci)?
Houtman

1
w JDK 9 nie udaje się :( 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

To działa dla mnie:

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: Opieram się na odpowiedzi GHada.


Ta odpowiedź nie zawiera niczego, co nie zostało jeszcze powiedziane w innych odpowiedziach.
Simon Forsberg

1

Jak wskazano w innych odpowiedziach, jeśli chcesz używać uwierzytelnionych serwerów proxy, nie ma niezawodnego sposobu, aby to zrobić przy użyciu zmiennych wiersza polecenia - co jest denerwujące, jeśli używasz aplikacji innej osoby i nie chcesz zadzierać z kod źródłowy.

Czy Iverson przedstawia przydatne sugestie na temat korzystania z HttpProxy w celu połączenia się z hostem za pomocą wstępnego uwierzytelnienia w celu skorzystania z narzędzia do zarządzania proxy, takiego jak Proxifier ( http://www.proxifier.com/ dla Mac OS X i Windows).

Na przykład w Proxifier możesz ustawić, aby przechwytywał tylko polecenia Java, którymi można zarządzać i przekierowywać przez (uwierzytelnione) proxy. Będziesz jednak chciał ustawić wartości proxyHost i proxyPort na puste w tym przypadku, np. Przekaż -Dhttp.proxyHost= -Dhttp.proxyPort=komendę java.


-1

Możesz użyć zmiennych http.proxy * JVM, jeśli jesteś w autonomicznej JVM, ale NIE POWINIENEŚ modyfikować ich skryptów startowych i / lub robić tego na serwerze aplikacji (z wyjątkiem może jboss lub tomcat). Zamiast tego należy użyć interfejsu API serwera proxy JAVA (nie System.setProperty) lub własnych opcji konfiguracji dostawcy. Zarówno WebSphere, jak i WebLogic mają bardzo zdefiniowane sposoby konfigurowania serwerów proxy, które są znacznie potężniejsze niż J2SE. Ponadto w przypadku WebSphere i WebLogic prawdopodobnie zepsujesz serwer aplikacji w niewielki sposób, zastępując skrypty startowe (w szczególności procesy międzyoperacyjne serwera, ponieważ możesz im również powiedzieć, aby korzystali z twojego serwera proxy ...).


-5

Myślę, że konfiguracja WINHTTP również będzie działać.

Wiele programów, w tym aktualizacje systemu Windows, ma problemy z serwerem proxy. Skonfigurowanie WINHTTP zawsze rozwiąże tego rodzaju problemy

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.