JVM tarafından kullanılacak proxy'yi nasıl ayarlarım


308

Çoğu zaman, bir Java uygulamasının İnternet'e bağlanması gerekir. En yaygın örnek, bir XML dosyasını okurken ve şemasını indirmesi gerektiğinde ortaya çıkar.

Proxy sunucusunun arkasındayım. JVM'mi proxy'yi kullanacak şekilde nasıl ayarlayabilirim?


Bu konudaki Oracle belgeleri oldukça bayat görünüyor (yine de muhtemelen geçerli). İşte Spring'den daha modern bir şey: docs.spring.io/spring-integration/reference/html/…
nobar

Yanıtlar:


350

Java belgelerinden ( javadoc API'sinden değil ):

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

JVM bayraklarını http.proxyHostve http.proxyPortkomut satırında JVM'nizi başlatırken ayarlayın . Bu genellikle bir kabuk komut dosyasında (Unix'te) veya bat dosyasında (Windows'ta) yapılır. Unix kabuk komut dosyasıyla ilgili örnek:

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

JBoss veya WebLogic gibi kapları kullanırken benim çözümüm, satıcı tarafından sağlanan başlangıç ​​komut dosyalarını düzenlemektir.

Birçok geliştirici Java API'sine (javadocs) aşinadır, ancak çoğu zaman belgelerin geri kalanı göz ardı edilir. Birçok ilginç bilgi içerir: http://download.oracle.com/javase/6/docs/technotes/guides/


Güncelleme: Bazı yerel / intranet ana bilgisayarlarını çözmek için proxy kullanmak istemiyorsanız @Tomalak'ın yorumuna bakın:

Ayrıca http.nonProxyHosts özelliğini de unutmayın!

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

109
+1. Ayrıca http.nonProxyHostsözelliği unutmayın ! (Böyle kullanım: -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Tomalak

3
Merhaba arkadaşlar, buna kullanıcı adını ve şifreyi nasıl dahil edebilirsiniz? Teşekkürler
Joeblackdev

8
@Joeblackdev http.proxyUser ve http.proxyPassword'a bakın
aasukisuki

4
@aasukisuki http.proxyUserve http.proxyPasswordJava sistem özellikleri değildir. Apache HTTP istemcisi içindir.
Lorne Marquis

24
Ayrıca, HTTP'leri yapılandırmayı https.proxyHostve yapılandırmayı unutmayın https.proxyPort.
C-Otto

103

Sistem proxy kurulumunu kullanmak için:

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

Veya programlı olarak:

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

Kaynak: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html


Harika ayar jvm
tartışma

SSLSocket'imdeki proxy'yi "false" değeriyle devre dışı bırakmak için bu kodu kullandım. Teşekkürler.
Fer

1
Belki de proxy'im kimlik doğrulaması gerektiriyor, ancak bu benim için işe yaramadı. Keşke yapsaydı.
Simon Forsberg

3
Bu, Proxy Otomatik Yapılandırma (PAC) dosyalarıyla çalışmaz, bkz. Stackoverflow.com/questions/10324996/…
Michael_S

80

Programlı olarak bir HTTP / HTTPS ve / veya SOCKS proxy ayarlamak için:

...

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 proxy'lerinin ve SOCKS proxy'lerinin ağ yığınında farklı düzeylerde çalıştığını unutmayın, böylece birini veya diğerini veya her ikisini de kullanabilirsiniz.


4
"Java.net.socks.username / password" ayarlanmışsa, neden bir Kimlik Doğrulayıcı da ayarladınız?
Lorne Marquis

1
"con.setRequest ..." neden tanınmıyor. Bunun için hangi kütüphanelere ihtiyaç var.
Randnum

1
Çorap proxy seçeneği için +1 bazen http proxy sorunumu çözemez
manuzhang

1
Testlerimde, yalnızca varsayılan Kimlik Doğrulayıcıyı ayarladıysanız çalışır
Drew Stephens

1
Yalnızca sistem özelliklerini kullanırsanız çalışmaz. Java.net.socks. (Username | password) özellikleri hiçbir şey yapmaz.
Drew Stephens

46

Bu bayrakları programlı olarak şu şekilde ayarlayabilirsiniz:

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

Sadece yöntemlerinden doğru değerleri döndürmek needsProxy(), getProxyHost()ve getProxyPort()ve istediğiniz zaman bu kod parçacığı çağırabilir.


34
"proxySet" hiçbir şey yapmaz. İspat: "false" olarak ayarlayın. JDK'da böyle bir özellik yoktur ve hiç bulunmamıştır, çeşitli kitaplar ve çevrimiçi referanslar da buna rağmen. Bu, uzun feshedilmiş HotJavaBean, bir kapsüllü tarayıcıdan gelen 1998 hakkında bir şekilde ölmüş
Lorne Marquis

2
Gerçekten http / https olmayan mülk adları mı?
Betlista

18
Bu üç açıdan yanlıştır: 1: belirtildiği gibi, "proxySet" öğesi yoktur; 2: "proxyHost" ve "proxyPort", "http.proxyHost" ve "http.proxyPort" (veya 'https' eşdeğeri) olmalıdır; 3: System.getProperties (). Put (X, Y), System.setProperty (X, Y) ile aynı değildir . Bunun dışında olsa da - harika bir cevap.
Rob Cranfill


1
@RobCranfill 1: "proxySet", eski bir JDK tarafından ihtiyaç duyulan ancak artık gerekli olmayan standart olmayan bir bayraktı; 2: "proxyHost" ve "proxyPort" çalışıyor, "http". öneki sadece HTTP protokolüyle ("https" için benzer) kısıtlar, 3: işte haklısın.
toolforger

24

JVM, HTTP çağrıları yapmak için proxy'yi kullanır

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

Bu, kullanıcı ayarı proxy'sini kullanabilir

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

System.setPropertyBunun yerine kullanınSystem.getProperties().put(...)
Simon Forsberg

12

Proxy sunucusu ile ilgili bazı özellikleri jvm parametreleri olarak ayarlayabilirsiniz

-Dhttp.proxyPort = 8080, proxyHost, vb.

ancak kimlik doğrulama proxy'sinden geçmeniz gerekiyorsa, bu örnek gibi bir kimlik doğrulayıcıya ihtiyacınız vardır:

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

    }
}

Bu yanıta dayanarak: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E


bu çalışmıyor. zaten kimliği doğrulanmamışsa, ana işlevdeki ilk satır bir grup boş değer alır ve kod durur. Bu, bir kullanıcının jvm'lerini doğrulamasına yardımcı olmaz, böylece bir proxy üzerinden URL aramaları yapabilir.
Randnum

12

Sorter ve javabrett / Leonel'in cevaplarını birleştirmek:

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


9

Aşağıda, Java'da proxy kullanıcılı bir proxy'nin ve komut satırından proxy şifresinin nasıl ayarlanacağı gösterilmektedir , bu çok yaygın bir durumdur. İlk etapta, şifreleri ve ana bilgisayarları koda kaydetmemelisiniz.

Sistem özelliklerini -D ile komut satırına geçirmek ve bunları System.setProperty ("name", "value") ile kodda ayarlamak eşdeğerdir.

Ama buna dikkat et

Çalışan örnek:

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

Ancak aşağıdakiler işe yaramaz :

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

Tek fark sistem özelliklerinin konumudur! (dersten önce ve sonra)

Şifrede özel karakterleriniz varsa, yukarıdaki örnekteki gibi "@ MyPass123%" kotasına koyabilirsiniz.

Bir HTTPS hizmetine erişiyorsanız https.proxyHost, https.proxyPortvb. Kullanmanız gerekir .

Bir HTTP hizmetine erişiyorsanız http.proxyHost, http.proxyPortvb. Kullanmanız gerekir .


5
ProxyUser ve proxyPassword, Java sistem özellikleri değil, Apache HTTP istemci özellikleridir, bu nedenle bu her durumda çalışmaz.
THelper

8

XML dosyasını okuma ve şemasını indirmesi gerekiyor

Şemaları veya DTD'leri internet üzerinden almaya güveniyorsanız, yavaş, konuşkan, kırılgan bir uygulama oluşturuyorsunuz. Dosyayı barındıran uzak sunucu planlanmış veya planlanmamış kesinti süreleri aldığında ne olur? Uygulamanız kırılıyor. Tamam mı?

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

Şemalar ve benzerleri için URL'ler en iyi benzersiz tanımlayıcılar olarak düşünülür. Bu dosyaya uzaktan erişme isteği olarak değil. "XML kataloğu" nda biraz google araması yapın. Bir XML kataloğu, bu tür kaynakları yerel olarak barındırmanıza izin vererek yavaşlığı, konuşkanlığı ve kırılganlığı çözmenizi sağlar.

Temel olarak uzak içeriğin kalıcı olarak önbelleğe alınmış bir kopyasıdır. Ve bu sorun değil, çünkü uzak içerik asla değişmeyecek. Bir güncelleme varsa, farklı bir URL'de olur. Kaynağın gerçekten internet üzerinden alınmasını aptalca yapmak.


7

Ben de güvenlik duvarının arkasındayım, bu benim için çalıştı !!

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" istiyorsanız, "socksProxyHost" ve "socksProxyPort" VM bağımsız değişkenlerini bilgilendirin.

Örneğin

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

4

Proxy'nin arkasındaki bir URL'ye bağlanmadan önce bunu ekleyin.

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.proxyUserve http.proxyPasswordJava sistem özellikleri değildir. Apache HTTP istemcisi içindir.
Lorne Marquis

System.setPropertyBunun yerine kullanınSystem.getProperties().put(...)
Simon Forsberg

4

Bu küçük bir güncellemedir, ancak Java 7'den beri proxy bağlantıları artık sistem özellikleri yerine programlı olarak oluşturulabilir. Bu, aşağıdaki durumlarda yararlı olabilir:

  1. Proxy'nin programın çalışma süresi boyunca dinamik olarak döndürülmesi gerekir
  2. Birden fazla paralel proxy kullanılması gerekir
  3. Veya sadece kodunuzu daha temiz yapın :)

İşte harika bir örnek:

// 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()
}

Tam Referans: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html


2
Bu Java 1.5'ten beri, 1.7 değil.
Lorne Marquis

3

Son zamanlarda JVM'nin tarayıcı proxy ayarlarını kullanmasına izin vermenin yolunu keşfettim. Yapmanız gereken ${java.home}/lib/deploy.jar, projenize eklemek ve kütüphaneyi aşağıdaki gibi başlatmaktır:

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

Daha sonra proxy ayarları Java API'sı aracılığıyla kullanılabilir java.net.ProxySelector.

Bu yaklaşımla ilgili tek sorun deploy.jar, JVM'yi bootclasspath ile başlatmanız gerektiğidir java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. Birisi bu sınırlamanın nasıl aşılacağını biliyorsa bana bildirin.


1
Keşke bunu birden fazla kez değerlendirebilseydim, benim için çalışan tek çözüm budur; teşekkür ederim! Apache müşterilerinin günlük kavanozunu buradan indirmek zorunda kaldım: commons.apache.org/proper/commons-logging/download_logging.cgi Main () kodum (): System.setProperty ("java.net.useSystemProxies", "true") ; System.out.println ("proxy'leri algılama"); ) (ExtendedProxyManager.init;
Boris

xbootclasspathDeploy.jar'a işaret etmenin etkisi ne olurdu, bu kavanozu normal sınıf yoluma (webstart olmadan çalıştırırken) alamadım mı?
Houtman

1
JDK 9'da başarısız oluyor :(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

Benim için işe yarıyor:

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'ın cevabına dayanıyorum.


Bu cevap, diğer cevaplarda henüz söylenmemiş hiçbir şey sağlamaz.
Simon Forsberg

1

Diğer yanıtlarda da belirtildiği gibi, Doğrulanmış proxy'leri kullanmanız gerekiyorsa, bunu yalnızca komut satırı değişkenleri kullanarak yapmanın güvenilir bir yolu yoktur - bu, başka birinin uygulamasını kullanıyorsanız ve kaynak kodu.

Will Iverson , bunu gerçekleştirmek için Proxifier ( http://www.proxifier.com/) gibi bir Proxy yönetim aracı kullanmak üzere önleyici kimlik doğrulaması olan bir ana bilgisayara bağlanmak için HttpProxy'yi kullanma konusunda yararlı bir öneri yapar .

Örneğin Proxifier ile, yalnızca (kimliği doğrulanmış) proxy'si aracılığıyla yönetilecek ve yönlendirilecek java komutlarını kesecek şekilde ayarlayabilirsiniz. Bu durumda proxyHost ve proxyPort değerlerini boş olarak ayarlamak istersiniz, örneğin -Dhttp.proxyHost= -Dhttp.proxyPort=java komutlarınıza geçin.


-1

Tek başına bir JVM'deyseniz http.proxy * JVM değişkenlerini kullanabilirsiniz, ancak başlangıç ​​komut dosyalarını değiştirmemeli ve / veya bunu uygulama sunucunuzda YAPMAMALISINIZ (belki jboss veya tomcat hariç). Bunun yerine JAVA Proxy API'sini (System.setProperty değil) veya satıcının kendi yapılandırma seçeneklerini kullanmalısınız. Hem WebSphere hem de WebLogic, J2SE'den çok daha güçlü olan proxy'leri kurmanın çok tanımlanmış yollarına sahiptir. Ayrıca, WebSphere ve WebLogic için, başlangıç ​​komut dosyalarını (özellikle de proxy'nizi kullanmasını söylediğiniz için sunucunun birlikte çalışma işlemleri ...) geçersiz kılarak uygulama sunucunuzu küçük yollarla bozabilirsiniz.


-5

Bence WINHTTP yapılandırması da işe yarayacak.

Windows Güncellemeleri dahil olmak üzere birçok program proxy'nin arkasında sorun yaşıyor. WINHTTP kurarak her zaman bu tür sorunları düzeltir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.