Domanda

Molte volte, un'app Java deve connettersi a Internet. L'esempio più comune si verifica quando sta leggendo un file XML e deve scaricare il suo schema.

Sono dietro un server proxy. Come posso impostare la mia JVM per usare il proxy?

È stato utile?

Soluzione

Dalla documentazione Java ( non l'API javadoc):

http://download.oracle.com/ JavaSE / 6 / docs / technotes / guide / net / proxies.html

Imposta i flag JVM http.proxyHost e http.proxyPort quando avvii JVM dalla 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 è quella di modificare gli script di avvio forniti dal 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 / note tecniche / guide /


Aggiornamento: se non si desidera utilizzare il proxy per risolvere alcuni host locali / intranet, consultare il commento da @Tomalak:

  

Inoltre, non dimenticare la proprietà http.nonProxyHosts!

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

Altri suggerimenti

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 l'uno o l'altro o entrambi.

È possibile impostare tali 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","");
}

Restituisci i giusti valori dai metodi needsProxy () , getProxyHost () e getProxyPort () e puoi chiamare questo frammento di codice quando vuoi.

JVM utilizza il proxy per effettuare chiamate HTTP

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

Questo può utilizzare il proxy delle impostazioni utente

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

È possibile impostare alcune proprietà sul server proxy come parametri jvm

-Dhttp.proxyPort = 8080, proxyHost, ecc.

ma se è necessario passare attraverso un proxy di autenticazione, è necessario 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;
    }
}

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

    }
}

Sulla base di questa risposta: http: // mail. apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

Combinando Sorter e javabrett / le risposte di Leonel:

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

legge un file XML e deve scaricare il suo schema

Se stai contando sul recupero di schemi o DTD su Internet, stai costruendo un'applicazione lenta, loquace e fragile. Cosa succede quando il server remoto che ospita il file richiede tempi di inattività pianificati o non pianificati? L'app si interrompe. Va bene?

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

Gli URL per schemi e simili sono meglio pensati come identificatori univoci. Non come richieste per accedere effettivamente a quel file da remoto. Fai qualche ricerca su Google nel " catalogo XML " ;. Un catalogo XML ti consente di ospitare tali risorse localmente, risolvendo la lentezza, la confusione e la fragilità.

Fondamentalmente è una copia memorizzata nella cache permanente del contenuto remoto. E va bene, dal momento che il contenuto remoto non cambierà mai. Se c'è mai un aggiornamento, sarebbe su un URL diverso. Rendere il recupero effettivo della risorsa su Internet particolarmente sciocco.

Sono anche dietro il 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();

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, come regola in primo luogo.

Passare le proprietà di sistema nella riga di comando con -D e impostarle 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 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 si dispone di caratteri speciali nella password, è possibile inserirlo tra virgolette "@ MyPass123%", come nell'esempio sopra.

Se accedi a un servizio HTTPS, devi utilizzare https.proxyHost, https.proxyPort ecc.

Se accedi a un servizio HTTP, devi usare http.proxyHost, http.proxyPort ecc.

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

Se vuoi "Socks Proxy", informa il "socksProxyHost" e "socksProxyPort" Argomenti VM.

per es.

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

Di recente 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 la seguente:

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 l'API Java tramite java.net.ProxySelector .

L'unico problema con questo approccio è che è necessario avviare JVM con deploy.jar nel bootclasspath ad es. java -Xbootclasspath / a: "% JAVA_HOME% \ jre \ lib \ deploy.jar " -jar my.jar . Se qualcuno sa come superare questa limitazione, fammelo sapere.

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.

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 utilizza l'applicazione di qualcun altro e non si desidera pasticciare con il codice sorgente.

Will Iverson fornisce suggerimenti utili su Utilizzo di 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 gestirlo.

Ad esempio con Proxifier è possibile configurarlo per intercettare solo i comandi Java da gestire e reindirizzare tramite il suo proxy (autenticato). In questo caso, tuttavia, vorrai impostare i valori proxyHost e proxyPort su blank, ad es. passa -Dhttp.proxyHost = -Dhttp.proxyPort = ai tuoi comandi java.

Inoltre, se si cerca sempre di scaricare lo stesso schema, è possibile aggiungere lo schema al proprio percorso di classe (filesystem o JAR), quindi utilizzare un EntityResolver

Vedi qui per una discussione più completa di questo approccio.

Modifica: vedi @ me.yahoo.com / a / 0QMxE nella discussione di CatalogResolver, che utilizza l'approccio EntityResolver:

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

È possibile utilizzare le variabili JVM http.proxy * se ci si trova in una JVM autonoma ma NON DOVREBBE modificare i loro script di avvio e / o farlo all'interno del proprio server delle applicazioni (tranne forse jboss o tomcat). Dovresti invece utilizzare l'API proxy JAVA (non System.setProperty) o utilizzare le opzioni di configurazione del fornitore. Sia WebSphere che WebLogic hanno modi ben definiti di impostare i proxy che sono molto più potenti di quello J2SE. Inoltre, per WebSphere e WebLogic probabilmente si romperà il server delle applicazioni in pochi modi sovrascrivendo gli script di avvio (in particolare i processi di interoperabilità del server in quanto si potrebbe dire loro di utilizzare anche il proxy ...).

Penso che anche la configurazione di WINHTTP funzionerà.

Molti programmi, inclusi gli aggiornamenti di Windows, hanno problemi dietro il proxy. Configurando WINHTTP risolverà sempre questo tipo di problemi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top