Comment définir le proxy à utiliser par la JVM

308

Plusieurs fois, une application Java doit se connecter à Internet. L'exemple le plus courant se produit lorsqu'il lit un fichier XML et doit télécharger son schéma.

Je suis derrière un serveur proxy. Comment puis-je configurer ma JVM pour utiliser le proxy?

Leonel
la source
La documentation Oracle à ce sujet semble assez obsolète (bien qu'elle soit probablement toujours valide). Voici quelque chose de plus moderne du printemps: docs.spring.io/spring-integration/reference/html/…
nobar

Réponses:

350

Depuis la documentation Java ( pas l'API javadoc):

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

Définissez les drapeaux JVM http.proxyHostet http.proxyPortlors du démarrage de votre JVM sur la ligne de commande. Cela se fait généralement dans un script shell (sous Unix) ou un fichier bat (sous Windows). Voici l'exemple avec le script shell Unix:

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

Lors de l'utilisation de conteneurs tels que JBoss ou WebLogic, ma solution consiste à éditer les scripts de démarrage fournis par le vendeur.

De nombreux développeurs connaissent l'API Java (javadocs), mais bien souvent le reste de la documentation est ignoré. Il contient de nombreuses informations intéressantes: http://download.oracle.com/javase/6/docs/technotes/guides/


Mise à jour: si vous ne souhaitez pas utiliser de proxy pour résoudre certains hôtes locaux / intranet, consultez le commentaire de @Tomalak:

N'oubliez pas non plus la propriété http.nonProxyHosts!

-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com‌​|etc"
Leonel
la source
109
+1. N'oubliez pas non plus la http.nonProxyHostspropriété! (utilisation comme ceci: -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Tomalak
3
Salut les gars, comment pouvez-vous également inclure le nom d'utilisateur et le mot de passe? Merci
Joeblackdev
8
@Joeblackdev regarde http.proxyUser et http.proxyPassword
aasukisuki
4
@aasukisuki http.proxyUseret http.proxyPasswordne sont pas des propriétés système Java. Ils sont destinés au client HTTP Apache.
Marquis de Lorne
24
N'oubliez pas non plus de configurer https.proxyHostet https.proxyPortpour HTTP.
C-Otto
103

Pour utiliser la configuration du proxy système:

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

Ou par programme:

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

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

gr5
la source
Le cadre impressionnant jvm arguement fonctionne pour moi comme un charme .. Merci
nanosoft
J'ai utilisé ce code pour désactiver le proxy par une valeur "fausse" sur mon SSLSocket. Merci.
Fer
1
C'est peut-être parce que mon proxy nécessite une authentification, mais cela n'a pas fonctionné pour moi. Je souhaite que ce soit le cas.
Simon Forsberg
3
Cela ne fonctionne pas avec les fichiers PAC (Proxy Auto-Config), voir stackoverflow.com/questions/10324996/…
Michael_S
80

Pour définir un proxy HTTP / HTTPS et / ou SOCKS par programme:

...

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

...

N'oubliez pas que les proxys HTTP et les proxys SOCKS fonctionnent à différents niveaux dans la pile réseau, vous pouvez donc utiliser l'un ou l'autre ou les deux.

Chris Carruthers
la source
4
Si "java.net.socks.username / password" est défini, pourquoi définir également un authentificateur?
Marquis de Lorne
1
pourquoi "con.setRequest ..." n'est-il pas reconnu? Quelles bibliothèques sont nécessaires pour cela.
Randnum
1
+1 pour l'option de proxy de chaussettes car parfois le proxy http ne peut pas résoudre mon problème
manuzhang
1
Dans mes tests, cela fonctionne si vous ne définissez que l'authentificateur par défaut - pas besoin de définir les propriétés d'authentification
Drew Stephens
1
Ne fonctionne pas si vous n'avez que les propriétés du système. Il me semble que les propriétés java.net.socks. (Nom d'utilisateur | mot de passe) ne font rien.
Drew Stephens
46

Vous pouvez définir ces indicateurs par programme de cette façon:

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

Il suffit de retourner les bonnes valeurs des méthodes needsProxy(), getProxyHost()et getProxyPort()vous pouvez appeler cet extrait de code chaque fois que vous voulez.

GHad
la source
34
"proxySet" ne fait rien. Preuve: réglez-le sur "faux". Il n'y a pas et n'a jamais existé une telle propriété dans le JDK, malgré divers livres et références en ligne. Il provenait du HotJavaBean, un navigateur encapsulé disparu depuis longtemps, décédé vers 1998.
Marquis de Lorne
2
Les noms de propriété sont-ils vraiment sans http / https?
Betlista
18
C'est faux sur trois points: 1: comme mentionné, il n'y a pas d'élément "proxySet"; 2: "proxyHost" et "proxyPort" doivent être "http.proxyHost" et "http.proxyPort" (ou l'équivalent 'https'); 3: System.getProperties (). Put (X, Y) n'est pas le même que System.setProperty (X, Y). Autre que cela, cependant - excellente réponse.
Rob Cranfill
1
@RobCranfill 1: "proxySet" était un indicateur non standard qui était nécessaire à un ancien JDK mais n'est plus nécessaire; 2: "proxyHost" et "proxyPort" fonctionnent, le "http". le préfixe les restreint au protocole HTTP (similaire pour "https"), 3: ici vous avez raison.
toolforger
24

JVM utilise le proxy pour effectuer des appels HTTP

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

Cela peut utiliser un proxy de configuration utilisateur

System.setProperty("java.net.useSystemProxies", "true");
Sarath
la source
Utiliser System.setPropertyau lieu deSystem.getProperties().put(...)
Simon Forsberg
12

Vous pouvez définir certaines propriétés du serveur proxy en tant que paramètres jvm

-Dhttp.proxyPort = 8080, proxyHost, etc.

mais si vous devez passer par un proxy d'authentification, vous avez besoin d'un authentificateur comme cet exemple:

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

    }
}

Basé sur cette réponse: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

Alex. S.
la source
cela ne fonctionne pas. si vous n'êtes pas déjà authentifié, la première ligne de la fonction principale obtient un tas de valeurs nulles et le code s'arrête. Cela n'aide pas quelqu'un à authentifier son jvm afin de pouvoir passer des appels URL via un proxy.
Randnum
12

Combiner les réponses de Sorter's et javabrett / Leonel:

java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar
Bamboomy
la source
10

Définissez la java.net.useSystemProxiespropriété sur true. Vous pouvez le définir, par exemple, via la variable d'environnement JAVA_TOOL_OPTIONS . Dans Ubuntu, vous pouvez, par exemple, ajouter la ligne suivante à .bashrc:

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

Mihai Capotă
la source
9

Ce qui suit montre comment définir en Java un proxy avec un utilisateur proxy et un mot de passe proxy à partir de la ligne de commande, ce qui est un cas très courant. Vous ne devez pas enregistrer les mots de passe et les hôtes dans le code, en règle générale en premier lieu.

Passer les propriétés système en ligne de commande avec -D et les définir dans le code avec System.setProperty ("nom", "valeur") est équivalent.

Mais notez ceci

Exemple qui fonctionne:

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

Mais ce qui suit ne fonctionne pas :

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

La seule différence est la position des propriétés du système! (avant et après le cours)

Si vous avez des caractères spéciaux dans le mot de passe, vous pouvez le mettre entre guillemets "@ MyPass123%", comme dans l'exemple ci-dessus.

Si vous accédez à un service HTTPS, vous devez utiliser https.proxyHost, https.proxyPortetc.

Si vous accédez à un service HTTP, vous devez utiliser http.proxyHost, http.proxyPortetc.

Andreas Panagiotidis
la source
5
ProxyUser et proxyPassword ne sont pas des propriétés système Java, mais des propriétés du client HTTP Apache, donc cela ne fonctionne pas dans tous les cas.
THelper
8

lire un fichier XML et doit télécharger son schéma

Si vous comptez récupérer des schémas ou des DTD sur Internet, vous créez une application lente, bavarde et fragile. Que se passe-t-il lorsque ce serveur distant hébergeant le fichier prend un temps d'arrêt planifié ou non planifié? Votre application se casse. Est-ce que ça va?

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

Les URL des schémas et similaires sont mieux considérées comme des identifiants uniques. Pas comme des demandes d'accès à ce fichier à distance. Faites une recherche google sur "catalogue XML". Un catalogue XML vous permet d'héberger ces ressources localement, ce qui résout la lenteur, la causerie et la fragilité.

Il s'agit essentiellement d'une copie en cache permanente du contenu distant. Et c'est OK, car le contenu distant ne changera jamais. S'il y a une mise à jour, ce serait à une URL différente. Rendre la récupération réelle de la ressource sur Internet particulièrement stupide.

John M
la source
7

Je suis également derrière le pare-feu, cela a fonctionné pour moi !!

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
la source
5

Si vous voulez "Socks Proxy", indiquez les arguments de la machine virtuelle "socksProxyHost" et "socksProxyPort".

par exemple

java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main
Marcelo C.
la source
4

Ajoutez ceci avant de vous connecter à une URL derrière un 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");
Trieur
la source
4
http.proxyUseret http.proxyPasswordne sont pas des propriétés du système Java. Ils sont destinés au client HTTP Apache.
Marquis de Lorne
Utilisez System.setPropertyau lieu deSystem.getProperties().put(...)
Simon Forsberg
4

Il s'agit d'une mise à jour mineure, mais depuis Java 7, les connexions proxy peuvent désormais être créées par programme plutôt que via les propriétés système. Cela peut être utile si:

  1. Le proxy doit être tourné dynamiquement pendant l'exécution du programme
  2. Plusieurs proxys parallèles doivent être utilisés
  3. Ou tout simplement rendre votre code plus propre :)

Voici un exemple artificiel dans 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()
}

Référence complète: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html

Philip M.
la source
2
C'est depuis Java 1.5, pas 1.7.
Marquis de Lorne
3

Récemment, j'ai découvert le moyen d'autoriser la JVM à utiliser les paramètres de proxy du navigateur. Ce que vous devez faire est d'ajouter ${java.home}/lib/deploy.jarà votre projet et de lancer la bibliothèque comme suit:

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

Ensuite, les paramètres du proxy sont disponibles pour l'API Java via java.net.ProxySelector.

Le seul problème avec cette approche est que vous devez démarrer JVM avec deploy.jardans bootclasspath par exemple java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. Si quelqu'un sait comment surmonter cette limitation, faites-le moi savoir.

dma_k
la source
1
J'aimerais pouvoir voter plusieurs fois, c'est la seule solution qui a fonctionné pour moi; Merci! J'ai dû télécharger le pot de journalisation d'apache commons à partir d'ici: commons.apache.org/proper/commons-logging/download_logging.cgi Mon code dans Main (): System.setProperty ("java.net.useSystemProxies", "true") ; System.out.println ("détection des mandataires"); ExtendedProxyManager.init ();
Boris du
Qu'est-ce que le xbootclasspathpointage sur deploy.jar aurait pour effet, ne pourrais-je pas prendre ce pot dans mon chemin de classe normal (lors de l'exécution sans webstart)?
Houtman
1
dans JDK 9, il échoue :( 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

Ça marche pour moi:

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: Je me base sur la réponse de GHad.

Viet Tran
la source
Cette réponse ne fournit rien qui n'ait déjà été dit dans les autres réponses.
Simon Forsberg
1

Comme indiqué dans d'autres réponses, si vous devez utiliser des proxys authentifiés, il n'y a pas de moyen fiable de le faire en utilisant uniquement des variables de ligne de commande - ce qui est ennuyeux si vous utilisez l'application de quelqu'un d'autre et que vous ne voulez pas jouer avec le code source.

Will Iverson fait la suggestion utile à l' aide de HttpProxy pour se connecter à un hôte avec une authentification préventive afin d'utiliser un outil de gestion de proxy tel que Proxifier ( http://www.proxifier.com/ pour Mac OS X et Windows) pour gérer cela.

Par exemple, avec Proxifier, vous pouvez le configurer pour intercepter uniquement les commandes java à gérer et à rediriger via son proxy (authentifié). Vous allez vouloir mettre les valeurs proxyHost et proxyPort à blanc dans ce cas, par exemple, passez -Dhttp.proxyHost= -Dhttp.proxyPort=à vos commandes java.

patdevelop
la source
-1

Vous pouvez utiliser les variables JVM http.proxy * si vous êtes dans une JVM autonome mais vous NE DEVEZ PAS modifier leurs scripts de démarrage et / ou le faire sur votre serveur d'applications (sauf peut-être jboss ou tomcat). Au lieu de cela, vous devez utiliser l'API JAVA Proxy (pas System.setProperty) ou utiliser les propres options de configuration du fournisseur. WebSphere et WebLogic ont tous deux des façons très définies de configurer les proxys qui sont beaucoup plus puissants que celui de J2SE. De plus, pour WebSphere et WebLogic, vous casserez probablement votre serveur d'applications de petites manières en remplaçant les scripts de démarrage (en particulier les processus d'interopérabilité du serveur car vous pourriez leur dire d'utiliser également votre proxy ...).


la source
-5

Je pense que la configuration de WINHTTP fonctionnera également.

De nombreux programmes, y compris les mises à jour Windows, rencontrent des problèmes derrière le proxy. La configuration de WINHTTP résoudra toujours ce genre de problèmes

nylas
la source