Question

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 machine virtuelle Java pour utiliser le proxy?

Était-ce utile?

La solution

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

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

Définissez les indicateurs http.proxyHost et http.proxyPort de la machine virtuelle Java lors du démarrage de votre machine virtuelle Java 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} ...

Lorsque j'utilise des conteneurs tels que JBoss ou WebLogic, ma solution consiste à modifier les scripts de démarrage fournis par le fournisseur.

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

Mettre à 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"

Autres conseils

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

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 proxies HTTP et SOCKS fonctionnent à différents niveaux de la pile réseau, vous pouvez donc utiliser l'un ou l'autre, voire les deux.

Vous pouvez définir ces indicateurs par programme de la manière suivante:

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

Il suffit de renvoyer les bonnes valeurs à partir des méthodes needsProxy () , getProxyHost () et getProxyPort () et vous pouvez appeler cet extrait de code quand vous voulez.

La JVM utilise le proxy pour passer des appels HTTP

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

Ceci peut utiliser un proxy de paramétrage utilisateur

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

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 avez besoin de passer par un proxy authentifiant, vous avez besoin d'un authentifiant tel que 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

    }
}

Sur la base de cette réponse: apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

Combinaison de la trieuse et des réponses de javabrett / Leonel:

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

lit 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 le serveur distant hébergeant le fichier subit 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 pour les schémas et autres sont mieux considérées comme des identificateurs uniques. Pas comme des demandes pour accéder réellement à ce fichier à distance. Effectuez des recherches google sur le "catalogue XML". Un catalogue XML vous permet d’héberger de telles ressources localement, ce qui résout les problèmes de lenteur, de discussion et de fragilité.

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

Je suis aussi derrière un 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();

Ce qui suit montre comment définir dans 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. En règle générale, vous ne devez pas enregistrer les mots de passe et les hôtes dans le code.

Passer les propriétés du système en ligne de commande avec -D et les définir dans le code avec System.setProperty ("name", "value") 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 les suivants ne fonctionnent 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 le mot de passe contient des caractères spéciaux, vous pouvez le mettre entre guillemets "@ @ MonPass123%", comme dans l'exemple ci-dessus.

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

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

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

Si vous souhaitez "Proxy Socks", informez-le "socksProxyHost". et " socksProxyPort " Arguments de la VM.

par exemple

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

Récemment, j'ai découvert un 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 d’initier 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 de 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.jar dans bootclasspath, par exemple. java -Xbootclasspath / a: "% JAVA_HOME% \ jre \ lib \ deploy.jar " -jar mon.jar . Si quelqu'un sait comment surmonter cette limitation, faites le moi savoir.

Cela fonctionne 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.

Comme indiqué dans d'autres réponses, si vous devez utiliser des proxies authentifiés, il n'existe aucun moyen fiable de le faire uniquement à l'aide de variables de ligne de commande, ce qui est gênant si vous utilisez l'application de quelqu'un d'autre et ne souhaitez pas jouer avec le code source.

Will Iverson fait une suggestion utile à l'adresse 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 ce problème.

Par exemple, avec Proxifier, vous pouvez le configurer pour n’intercepter que les commandes Java à gérer et à rediriger via son proxy (authentifié). Dans ce cas, vous souhaiterez définir les valeurs proxyHost et proxyPort comme vierges, par exemple. transmettez -Dhttp.proxyHost = -Dhttp.proxyPort = à vos commandes java.

De même, si vous souhaitez toujours télécharger le même schéma, vous pouvez l'ajouter à votre chemin de classe (système de fichiers ou JAR), puis utiliser un paramètre personnalisé EntityResolver

Voir ici pour une analyse plus complète de cette approche.

Modifier: consultez la discussion de @ me.yahoo.com / a / 0QMxE sur CatalogResolver, qui utilise l'approche EntityResolver:

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

Vous pouvez utiliser les variables http.proxy * JVM si vous vous trouvez dans une JVM autonome mais que vous NE DEVRIEZ PAS modifier leurs scripts de démarrage et / ou le faire sur votre serveur d'applications (sauf peut-être jboss ou tomcat). A la place, 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 méthodes bien définies pour configurer les proxies, qui sont bien plus puissants que ceux de J2SE. En outre, pour WebSphere et WebLogic, vous casserez probablement votre serveur d’applications en redéfinissant les scripts de démarrage (en particulier les processus d’interopérabilité du serveur, car vous pourriez peut-être également leur dire d’utiliser votre proxy ...).

Je pense que la configuration de WINHTTP fonctionnera également.

De nombreux programmes, y compris les mises à jour Windows, ont des problèmes de proxy. En configurant WINHTTP, on résoudra toujours ce type de problèmes

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top