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 pour utiliser le proxy?
Dans la documentation Java ( et non l'API javadoc):
http://download.Oracle.com/javase/6/docs/technotes/guides/net/proxies.html
Définissez les indicateurs JVM http.proxyHost
et http.proxyPort
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 Unix Shell:
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 l'API Java (javadocs), mais le reste de la documentation est souvent ignoré. Il contient beaucoup d'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"
Pour utiliser la configuration du proxy système:
Java -Djava.net.useSystemProxies=true ...
Ou par programmation:
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 drapeaux 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 vous suffit de renvoyer les bonnes valeurs à partir des méthodes needsProxy()
, getProxyHost()
et getProxyPort()
. Vous pouvez appeler cet extrait de code à tout moment.
JVM utilise le proxy pour faire des appels HTTP
System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
Cela peut utiliser un proxy de paramétrage utilisateur
System.setProperty("Java.net.useSystemProxies", "true");
Combinaison des réponses de Sorter et de javabrett/Leonel:
Java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar
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 comme celui-ci:
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: http://mail-archives.Apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E
Définissez la propriété Java.net.useSystemProxies
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"
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 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. Faites des recherches google sur "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 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.
Ce qui suit montre comment définir dans Java un proxy avec tilisateur et 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 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 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 êtes autorisé à le mettre entre guillemets "@ MyPass123%", 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.
Je suis aussi 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();
Si vous voulez "Socks Proxy", indiquez les arguments "socksProxyHost" et "socksProxyPort" VM.
par exemple.
Java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main
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 par l'intermédiaire des propriétés système. Cela peut être utile si:
Voici un exemple artificiel de 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
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");
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 d’initialiser 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 Java API 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 my.jar
. Si quelqu'un sait comment surmonter cette limitation, faites le moi savoir.
Ç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.
Comme indiqué dans d'autres réponses, si vous devez utiliser des proxies authentifiés, il n'y a pas de 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 voulez pas jouer avec le code source.
Will Iverson fait la suggestion utile sur tilisation de HttpProxy pour se connecter à un hôte avec une authentification préalable pour utiliser un outil de gestion du proxy tel que Proxifier ( http://www.proxifier.com/ pour Mac OS X et Windows).
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 allez vouloir définir les valeurs proxyHost et proxyPort comme vierges, par exemple. transmettez -Dhttp.proxyHost= -Dhttp.proxyPort=
à vos commandes Java.
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 (à l'exception peut-être de jboss ou de Tomcat). À la place, vous devez utiliser l'API de proxy Java (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 aussi leur dire d’utiliser votre proxy ...).
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 discussion plus complète de cette approche.
Edit: See @ me.yahoo.com/a/0QMxE's discussion sur CatalogResolver, qui utilise l'approche EntityResolver:
CatalogResolver cr = new CatalogResolver();
...
yourParser.setEntityResolver(cr)