Como eu configuro o proxy para ser usado pela JVM


308

Muitas vezes, um aplicativo Java precisa se conectar à Internet. O exemplo mais comum acontece quando está lendo um arquivo XML e precisa fazer o download de seu esquema.

Estou atrás de um servidor proxy. Como posso configurar minha JVM para usar o proxy?


A documentação do Oracle em torno disso parece bastante antiga (embora ainda seja provavelmente válida). Aqui está algo mais moderno do Spring: docs.spring.io/spring-integration/reference/html/…
nobar

Respostas:


350

Na documentação Java ( não na API javadoc):

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

Defina os sinalizadores da JVM http.proxyHoste http.proxyPortao iniciar sua JVM na linha de comandos. Isso geralmente é feito em um script de shell (no Unix) ou em um arquivo bat (no Windows). Aqui está o exemplo com o script de shell Unix:

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

Ao usar contêineres como JBoss ou WebLogic, minha solução é editar os scripts de inicialização fornecidos pelo fornecedor.

Muitos desenvolvedores estão familiarizados com a API Java (javadocs), mas muitas vezes o restante da documentação é negligenciado. Ele contém muitas informações interessantes: http://download.oracle.com/javase/6/docs/technotes/guides/


Atualização: se você não deseja usar o proxy para resolver alguns hosts locais / intranet, confira o comentário em @Tomalak:

Além disso, não esqueça a propriedade http.nonProxyHosts!

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

109
+1. Também não se esqueça da http.nonProxyHostspropriedade! (uso como este: -Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com|etc")
Tomalak

3
Oi pessoal, como você pode incluir também o nome de usuário e a senha? Graças
Joeblackdev

8
@Joeblackdev veja http.proxyUser e http.proxyPassword
aasukisuki

4
@aasukisuki http.proxyUsere http.proxyPasswordnão são propriedades do sistema Java. Eles são para o cliente HTTP Apache.
Marquês de Lorne

24
Além disso, não esqueça de configurar https.proxyHoste https.proxyPortpara HTTPs.
C # Otto

103

Para usar a configuração de proxy do sistema:

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

Ou programaticamente:

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

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


Impressionantes obras configuração JVM argumento para me como charme .. Obrigado
Nanosoft

Eu usei esse código para desativar o proxy pelo valor "false" no meu SSLSocket. Obrigado.
Fer

1
Talvez seja porque meu proxy exija autenticação, mas isso não funcionou para mim. Eu gostaria que sim.
Simon Forsberg

3
Isso não funciona com arquivos de configuração automática de proxy (PAC), consulte stackoverflow.com/questions/10324996/…
Michael_S

80

Para definir um proxy HTTP / HTTPS e / ou SOCKS programaticamente:

...

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

...

Lembre-se de que os proxies HTTP e os proxies SOCKS operam em níveis diferentes na pilha da rede, para que você possa usar um ou outro ou ambos.


4
Se "java.net.socks.username / password" estiver definido, por que também definir um autenticador?
Marquês de Lorne #

1
por que não é "con.setRequest ..." o con não é reconhecido. Quais bibliotecas são necessárias para isso.
Randnum 08/12/19

1
+1 para a opção de proxy como, por vezes, proxy HTTP não pode resolver o meu problema meias
manuzhang

1
Em meus testes, ele funciona se você só definir o padrão autenticador-não há necessidade de definir as propriedades de autenticação
de Drew Stephens

1
Não funciona se você apenas as propriedades do sistema. Considera que as propriedades java.net.socks. (Nome de usuário | senha) não fazem nada.
Drew Stephens

46

Você pode definir esses sinalizadores programaticamente desta maneira:

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

Basta retornar os valores corretos a partir dos métodos needsProxy(), getProxyHost()e getProxyPort()e você pode chamar este trecho de código quando quiser.


34
"proxySet" não faz nada. Prova: defina como "false". Não existe e nunca houve essa propriedade no JDK, apesar de vários livros e referências on-line. Ele veio do HotJavaBean longo extinta, um navegador encapsulado, uma morte em cerca de 1998.
Marquês de Lorne

2
Realmente são os nomes das propriedades sem http / https?
Betlista

18
Isso está errado em três aspectos: 1: como mencionado, não há item "proxySet"; 2: "proxyHost" e "proxyPort" precisam ser "http.proxyHost" e "http.proxyPort" (ou o equivalente 'https'); 3: System.getProperties (). Put (X, Y) não é o mesmo que System.setProperty (X, Y). Fora isso, porém - ótima resposta.
precisa


1
@RobCranfill 1: "proxySet" costumava ser um sinalizador não padrão que era necessário por um JDK antigo, mas não é mais necessário; 2: "proxyHost" e "proxyPort" funcionam, o "http". O prefixo restringe-os apenas ao protocolo HTTP (semelhante a "https."), 3: aqui você está certo.
toolforger

24

A JVM usa o proxy para fazer chamadas HTTP

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

Isso pode usar o proxy de configuração do usuário

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

Use em System.setPropertyvez deSystem.getProperties().put(...)
Simon Forsberg

12

Você pode definir algumas propriedades sobre o servidor proxy como parâmetros jvm

-Dhttp.proxyPort = 8080, proxyHost, etc.

mas se você precisar passar por um proxy de autenticação, precisará de um autenticador como este exemplo:

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

    }
}

Com base nesta resposta: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E


isso não funciona. se você ainda não está autenticado, a primeira linha na função principal obtém vários valores nulos e o código para. Isso não ajuda alguém a autenticar sua jvm, para que possa fazer chamadas de URL por meio de um proxy.
Randnum 8/12

12

Combinando as respostas de Sorter e javabrett / Leonel:

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

10

Defina a java.net.useSystemProxiespropriedade como true. Você pode configurá-lo, por exemplo, através da variável de ambiente JAVA_TOOL_OPTIONS . No Ubuntu, você pode, por exemplo, adicionar a seguinte linha a .bashrc:

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


9

A seguir, mostramos como configurar em Java um proxy com usuário proxy e senha de proxy na linha de comandos, que é um caso muito comum. Você não deve salvar senhas e hosts no código, como regra geral.

Passar as propriedades do sistema na linha de comando com -D e defini-las no código com System.setProperty ("name", "value") é equivalente.

Mas observe isso

Exemplo que funciona:

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

Mas o seguinte não funciona :

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

A única diferença é a posição das propriedades do sistema! (antes e depois da aula)

Se você tiver caracteres especiais na senha, poderá colocá-lo entre aspas "@ MyPass123%", como no exemplo acima.

Se você acessar um serviço HTTPS, você tem que usar https.proxyHost, https.proxyPortetc.

Se você acessar um serviço HTTP, você tem que usar http.proxyHost, http.proxyPortetc.


5
ProxyUser e proxyPassword não são propriedades do sistema Java, mas propriedades do cliente HTTP Apache, portanto, isso não funciona em todos os casos.
THelper

8

lendo um arquivo XML e precisa fazer download de seu esquema

Se você está contando com a recuperação de esquemas ou DTDs pela Internet, está criando um aplicativo lento, falador e frágil. O que acontece quando o servidor remoto que hospeda o arquivo leva um tempo de inatividade planejado ou não planejado? Seu aplicativo é interrompido. Tudo bem?

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

URLs para esquemas e afins são mais bem pensados ​​como identificadores exclusivos. Não como solicitações para acessar esse arquivo remotamente. Faça uma pesquisa no google no "catálogo XML". Um catálogo XML permite que você hospede esses recursos localmente, resolvendo a lentidão, a propriedade e a fragilidade.

É basicamente uma cópia permanentemente em cache do conteúdo remoto. E tudo bem, já que o conteúdo remoto nunca muda. Se houver alguma atualização, ela estará em um URL diferente. Tornar a recuperação real do recurso pela Internet especialmente boba.


7

Também estou atrás de firewall, isso funcionou para mim !!

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

5

Se você deseja "Socks Proxy", informe os argumentos da VM "socksProxyHost" e "socksProxyPort".

por exemplo

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

4

Adicione isso antes de se conectar a um URL atrás de um 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");

4
http.proxyUsere http.proxyPasswordnão são propriedades do sistema Java. Eles são para o cliente HTTP Apache.
Marquês de Lorne

Use em System.setPropertyvez deSystem.getProperties().put(...)
Simon Forsberg

4

Esta é uma atualização secundária, mas desde o Java 7, as conexões de proxy agora podem ser criadas de forma programática, e não através das propriedades do sistema. Isso pode ser útil se:

  1. O proxy precisa ser rotacionado dinamicamente durante o tempo de execução do programa
  2. Vários proxies paralelos precisam ser usados
  3. Ou apenas faça seu código mais limpo :)

Aqui está um exemplo artificial no 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()
}

Referência completa: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html


2
Isso ocorre desde Java 1.5, não 1.7.
Marquês de Lorne

3

Recentemente, descobri a maneira de permitir que a JVM use as configurações de proxy do navegador. O que você precisa fazer é adicionar ${java.home}/lib/deploy.jarao seu projeto e iniciar a biblioteca da seguinte maneira:

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

Posteriormente, as configurações de proxy estão disponíveis para a API Java via java.net.ProxySelector.

O único problema com essa abordagem é que você precisa iniciar a JVM deploy.jarno bootclasspath, por exemplo java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. Se alguém souber como superar essa limitação, me avise.


1
Eu gostaria de poder votar isso várias vezes, é a única solução que funcionou para mim; obrigado! Eu tive que baixar o jar de logon do apache commons a partir daqui: commons.apache.org/proper/commons-logging/download_logging.cgi Meu código em Main (): System.setProperty ("java.net.useSystemProxies", "true") ; System.out.println ("detectando proxies"); ExtendedProxyManager.init ();
Boris

O que o xbootclasspathapontar para deploy.jar teria efeito?
21718 Houtman

1
no JDK 9, ele falha :( 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

Isso funciona para mim:

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: Baseio-me na resposta do GHad.


Esta resposta não fornece nada que ainda não tenha sido dito nas outras respostas.
Simon Forsberg

1

Conforme indicado em outras respostas, se você precisar usar proxies autenticados, não há uma maneira confiável de fazer isso puramente usando variáveis ​​de linha de comando - o que é irritante se você estiver usando o aplicativo de outra pessoa e não quiser mexer com o Código fonte.

Will Iverson faz a sugestão útil em Como usar o HttpProxy para conectar-se a um host com autenticação preventiva para usar uma ferramenta de gerenciamento de proxy como o Proxifier ( http://www.proxifier.com/ para Mac OS X e Windows) para lidar com isso.

Por exemplo, com o Proxifier, você pode configurá-lo para interceptar apenas comandos java para serem gerenciados e redirecionados por meio de seu proxy (autenticado). Você vai querer definir os valores proxyHost e proxyPort como em branco neste caso, por exemplo, passe -Dhttp.proxyHost= -Dhttp.proxyPort=para seus comandos java.


-1

Você pode utilizar as variáveis ​​http.proxy * JVM se estiver dentro de uma JVM autônoma, mas NÃO DEVE modificar os scripts de inicialização e / ou fazer isso no servidor de aplicativos (exceto talvez o jboss ou o tomcat). Em vez disso, você deve utilizar a API do Proxy JAVA (não System.setProperty) ou utilizar as opções de configuração do próprio fornecedor. O WebSphere e o WebLogic têm maneiras muito definidas de configurar os proxies que são muito mais poderosos que o J2SE. Além disso, para o WebSphere e o WebLogic, você provavelmente interromperá o servidor de aplicativos de pequenas maneiras, substituindo os scripts de inicialização (particularmente os processos de interoperabilidade do servidor, como você pode estar dizendo a eles para usar seu proxy também ...).


-5

Eu acho que configurar o WINHTTP também funcionará.

Muitos programas, incluindo as atualizações do Windows, estão tendo problemas por trás do proxy. A configuração do WINHTTP sempre corrigirá esse tipo de problema

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.