Come posso impostare il proxy per essere utilizzato dalla JVM
Molte volte, un'app Java deve connettersi a Internet. L'esempio più comune si verifica quando si sta leggendo un file XML e ha bisogno di scaricare il suo schema.
Sono dietro un server proxy. Come posso impostare la mia JVM per utilizzare il proxy ?
20 answers
Dalla documentazione Java ( non l'API javadoc):
Http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
Impostare i flag JVM http.proxyHost
e http.proxyPort
quando si avvia la JVM sulla riga di comando.
Questo di solito viene fatto in uno script di shell (in Unix) o in un file bat (in Windows). Ecco l'esempio con lo script della shell Unix:
JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...
Quando si utilizzano contenitori come JBoss o WebLogic, la mia soluzione è modificare gli script di avvio forniti da Fornitore.
Molti sviluppatori hanno familiarità con l'API Java (javadocs), ma molte volte il resto della documentazione viene trascurato. Contiene molte informazioni interessanti: http://download.oracle.com/javase/6/docs/technotes/guides /
Aggiornamento: Se non si desidera utilizzare il proxy per risolvere alcuni host locali / intranet, controllare il commento da @ Tomalak:
Inoltre non dimenticare l'http.Proprietà nonProxyHosts!
-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc"
Per utilizzare la configurazione del proxy di sistema:
java -Djava.net.useSystemProxies=true ...
O programmaticamente:
System.setProperty("java.net.useSystemProxies", "true");
Fonte: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
Per impostare un proxy HTTP/HTTPS e/o SOCKS a livello di codice:
...
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;
}
}
...
Ricorda che i proxy HTTP e i proxy SOCKS operano a diversi livelli nello stack di rete, quindi puoi usare uno o l'altro o entrambi.
Puoi impostare quei flag a livello di codice in questo modo:
if (needsProxy()) {
System.setProperty("http.proxyHost",getProxyHost());
System.setProperty("http.proxyPort",getProxyPort());
} else {
System.setProperty("http.proxyHost","");
System.setProperty("http.proxyPort","");
}
Basta restituire i valori giusti dai metodi needsProxy()
, getProxyHost()
e getProxyPort()
e puoi chiamare questo frammento di codice ogni volta che vuoi.
JVM utilizza il proxy per effettuare chiamate HTTP
System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
Questo può utilizzare l'impostazione utente proxy
System.setProperty("java.net.useSystemProxies", "true");
È possibile impostare alcune proprietà sul server proxy come parametri jvm
-Dhttp.proxyPort=8080, proxyHost, ecc.
Ma se hai bisogno di passare attraverso un proxy di autenticazione, hai bisogno di un autenticatore come questo esempio:
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;
}
}
Esempio.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
}
}
Sulla base di questo risposta: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E
La lettura di un file XML e ha bisogno di scaricare il suo schema
Se stai contando sul recupero di schemi o DTD su Internet, stai creando un'applicazione lenta, loquace e fragile. Cosa succede quando il server remoto che ospita il file richiede tempi di inattività pianificati o non pianificati? La tua app si rompe. Va bene?
Vedere http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files
URL per schemi e simili sono i migliori pensato come identificatori univoci. Non come richieste per accedere effettivamente a quel file da remoto. Fai qualche ricerca su Google su "Catalogo XML". Un catalogo XML consente di ospitare tali risorse localmente, risolvendo la lentezza, chattiness e fragilità.
È fondamentalmente una copia permanentemente memorizzata nella cache del contenuto remoto. E va bene, dal momento che il contenuto remoto non cambierà mai. Se c'è mai un aggiornamento, sarebbe in un URL diverso. Effettuare il recupero effettivo della risorsa su Internet soprattutto sciocco.
Imposta il java.net.useSystemProxies
proprietà a true
. È possibile impostarlo, ad esempio, tramite la variabile ambientale JAVA_TOOL_OPTIONS. In Ubuntu, è possibile, ad esempio, aggiungere la seguente riga a .bashrc
:
Esporta JAVA_TOOL_OPTIONS + = "- Djava. net. useSystemProxies = true "
Sono anche dietro firewall, questo ha funzionato per me!!
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();
Combinando le risposte di Sorter e javabrett/Leonel:
java -Dhttp.proxyHost=10.10.10.10 -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password -jar myJar.jar
Aggiungi questo prima di connetterti a un URL dietro 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");
Quanto segue mostra come impostare in Java un proxy con utente proxy e password proxy dalla riga di comando, che è un caso molto comune. Non è necessario salvare password e host nel codice, di norma in primo luogo.
Passando le proprietà del sistema nella riga di comando con-D e impostandole nel codice con System.setProperty ("nome", "valore") è equivalente.
Ma nota questo
Esempio che funziona:
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
Ma il seguente lo fa non funziona
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
L'unica differenza è la posizione delle proprietà del sistema ! (prima e dopo la lezione)
Se hai caratteri speciali in password, puoi metterlo tra virgolette "@MyPass123%", come nell'esempio precedente.
Se si accede a un servizio HTTPS, è necessario utilizzare https.proxyHost, https.proxyPort ecc.
Se si accede a un servizio HTTP, è necessario utilizzare http.proxyHost, http.proxyPort ecc.
Questo è un aggiornamento minore, ma da Java 7, le connessioni proxy possono ora essere create a livello di codice piuttosto che attraverso le proprietà di sistema. Questo può essere utile se:
- Il proxy deve essere ruotato dinamicamente durante il runtime del programma
- È necessario utilizzare più proxy paralleli
- O semplicemente rendi il tuo codice più pulito :)
Ecco un esempio inventato in 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()
}
Pieno Riferimento: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html
Recentemente ho scoperto il modo per consentire a JVM di utilizzare le impostazioni proxy del browser. Quello che devi fare è aggiungere ${java.home}/lib/deploy.jar
al tuo progetto e avviare la libreria come segue:
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;
}
}
Successivamente le impostazioni proxy sono disponibili per Java API tramite java.net.ProxySelector
.
L'unico problema con questo approccio è che è necessario avviare JVM con deploy.jar
in bootclasspath ad esempio java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar
. Se qualcuno sa come superare questa limitazione, fatemelo sapere.
Che funziona per me:
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: Mi baso sulla risposta di GHad.
Se si desidera "Proxy Socks", informare gli argomenti VM "socksProxyHost" e "socksProxyPort".
Ad esempio
java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main
Come indicato in altre risposte, se è necessario utilizzare proxy autenticati, non esiste un modo affidabile per farlo utilizzando esclusivamente le variabili della riga di comando, il che è fastidioso se si sta utilizzando l'applicazione di qualcun altro e non si vuole pasticciare con il codice sorgente.
Will Htton fa il suggerimento utile su Usando HttpProxy per connettersi a un host con autenticazione preventiva per utilizzare uno strumento di gestione proxy come Proxifier ( http://www.proxifier.com / per Mac OS X e Windows) per gestire questo.
Ad esempio con Proxifier è possibile impostarlo per intercettare solo i comandi java da gestire e reindirizzare attraverso il suo proxy (autenticato). In questo caso, tuttavia, vorrai impostare i valori proxyHost e proxyPort su vuoto, ad esempio passare -Dhttp.proxyHost= -Dhttp.proxyPort=
ai comandi java.
Inoltre, se stai sempre cercando di scaricare lo stesso schema, puoi aggiungere lo schema al tuo classpath (filesystem o JAR) e quindi utilizzare un EntityResolver
Vedi qui per una discussione più completa di questo approccio.
Modifica: Vedi @me.yahoo.com/a/0QMxE ' s discussione di CatalogResolver, che utilizza l'approccio EntityResolver:
CatalogResolver cr = new CatalogResolver();
...
yourParser.setEntityResolver(cr)
È possibile utilizzare l'http.proxy * Variabili JVM se si è all'interno di una JVM autonoma ma NON si DOVREBBERO modificare i loro script di avvio e/o farlo all'interno del server delle applicazioni (tranne forse jboss o tomcat). Invece dovresti utilizzare l'API Proxy JAVA (non System.setProperty) o utilizzare le opzioni di configurazione del fornitore. Sia WebSphere che WebLogic hanno modi molto definiti per impostare i proxy che sono molto più potenti di quelli J2SE. Inoltre, per WebSphere e WebLogic probabilmente interromperai il tuo server delle applicazioni in pochi modi sovrascrivendo gli script di avvio (in particolare i processi di interoperabilità del server in quanto potresti dire loro di usare anche il tuo proxy...).