Java 如何设置 JVM 使用的代理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/120797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:30:49  来源:igfitidea点击:

How do I set the proxy to be used by the JVM

javaproxyjvm

提问by Leonel

Many times, a Java app needs to connect to the Internet. The most common example happens when it is reading an XML file and needs to download its schema.

很多时候,Java 应用程序需要连接到 Internet。最常见的示例发生在读取 XML 文件并需要下载其架构时。

I am behind a proxy server. How can I set my JVM to use the proxy ?

我在代理服务器后面。如何设置我的 JVM 以使用代理?

采纳答案by Leonel

From the Java documentation (notthe javadoc API):

从 Java 文档(不是javadoc API):

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

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

Set the JVM flags http.proxyHostand http.proxyPortwhen starting your JVM on the command line. This is usually done in a shell script (in Unix) or bat file (in Windows). Here's the example with the Unix shell script:

在命令行上设置 JVM 标志http.proxyHosthttp.proxyPort启动 JVM 时。这通常在 shell 脚本(在 Unix 中)或 bat 文件(在 Windows 中)中完成。这是 Unix shell 脚本的示例:

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

When using containers such as JBoss or WebLogic, my solution is to edit the start-up scripts supplied by the vendor.

在使用JBoss或WebLogic等容器时,我的解决方案是编辑厂商提供的启动脚本。

Many developers are familiar with the Java API (javadocs), but many times the rest of the documentation is overlooked. It contains a lot of interesting information: http://download.oracle.com/javase/6/docs/technotes/guides/

许多开发人员熟悉 Java API (javadocs),但很多时候忽略了文档的其余部分。它包含很多有趣的信息:http: //download.oracle.com/javase/6/docs/technotes/guides/



Update :If you do not want to use proxy to resolve some local/intranet hosts, check out the comment from @Tomalak:

更新:如果您不想使用代理来解析某些本地/内联网主机,请查看@Tomalak 的评论:

Also don't forget the http.nonProxyHosts property!

也不要忘记 http.nonProxyHosts 属性!

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

回答by GHad

You can set those flags programmatically this way:

您可以通过以下方式以编程方式设置这些标志:

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

Just return the right values from the methods needsProxy(), getProxyHost()and getProxyPort()and you can call this code snippet whenever you want.

单从方法返回正确的价值观needsProxy()getProxyHost()并且getProxyPort()你可以打电话,只要你想这个代码片断。

回答by John M

reading an XML file and needs to download its schema

读取 XML 文件并需要下载其架构

If you are counting on retrieving schemas or DTDs over the internet, you're building a slow, chatty, fragile application. What happens when that remote server hosting the file takes planned or unplanned downtime? Your app breaks. Is that OK?

如果您指望通过 Internet 检索模式或 DTD,那么您正在构建一个缓慢、健谈、脆弱的应用程序。当托管文件的远程服务器出现计划内或计划外停机时会发生什么?您的应用程序中断。这可以吗?

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

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

URL's for schemas and the like are best thought of as unique identifiers. Not as requests to actually access that file remotely. Do some google searching on "XML catalog". An XML catalog allows you to host such resources locally, resolving the slowness, chattiness and fragility.

模式等的 URL 最好被认为是唯一标识符。不是作为远程实际访问该文件的请求。在“XML 目录”上进行一些谷歌搜索。XML 目录允许您在本地托管此类资源,从而解决缓慢、繁琐和脆弱的问题。

It's basically a permanently cached copy of the remote content. And that's OK, since the remote content will never change. If there's ever an update, it'd be at a different URL. Making the actual retrieval of the resource over the internet especially silly.

它基本上是远程内容的永久缓存副本。没关系,因为远程内容永远不会改变。如果有更新,它将位于不同的 URL。使通过互联网实际检索资源变得特别愚蠢。

回答by Alex. S.

You can set some properties about the proxy server as jvm parameters

您可以将有关代理服务器的一些属性设置为 jvm 参数

-Dhttp.proxyPort=8080, proxyHost, etc.

-Dhttp.proxyPort=8080、proxyHost等

but if you need pass through an authenticating proxy, you need an authenticator like this example:

但是如果你需要通过一个身份验证代理,你需要一个像这个例子一样的身份验证器:

ProxyAuthenticator.java

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

例子.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

    }
}

Based on this reply: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

基于此回复:http: //mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E

回答by Chris Carruthers

To set an HTTP/HTTPS and/or SOCKS proxy programmatically:

以编程方式设置 HTTP/HTTPS 和/或 SOCKS 代理:

...

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

...

Remember that HTTP proxies and SOCKS proxies operate at different levels in the network stack, so you can use one or the other or both.

请记住,HTTP 代理和 SOCKS 代理在网络堆栈中的不同级别运行,因此您可以使用其中一个或两者。

回答by Chris Carruthers

You can utilize the http.proxy* JVM variables if you're within a standalone JVM but you SHOULD NOT modify their startup scripts and/or do this within your application server (except maybe jboss or tomcat). Instead you should utilize the JAVA Proxy API (not System.setProperty) or utilize the vendor's own configuration options. Both WebSphere and WebLogic have very defined ways of setting up the proxies that are far more powerful than the J2SE one. Additionally, for WebSphere and WebLogic you will likely break your application server in little ways by overriding the startup scripts (particularly the server's interop processes as you might be telling them to use your proxy as well...).

如果您在独立的 JVM 中,您可以使用 http.proxy* JVM 变量,但您不应该修改它们的启动脚本和/或在您的应用程序服务器中执行此操作(jboss 或 tomcat 除外)。相反,您应该使用 JAVA 代理 API(而不是 System.setProperty)或使用供应商自己的配置选项。WebSphere 和 WebLogic 都有非常明确的设置代理的方法,这些方法比 J2SE 强大得多。此外,对于 WebSphere 和 WebLogic,您可能会通过覆盖启动脚本(特别是服务器的互操作进程,因为您可能会告诉它们也使用您的代理……)以小方式破坏您的应用程序服务器。

回答by dma_k

Recently I've discovered the way to allow JVM to use browser proxy settings. What you need to do is to add ${java.home}/lib/deploy.jarto your project and to init the library like the following:

最近我发现了允许 JVM 使用浏览器代理设置的方法。您需要做的是添加${java.home}/lib/deploy.jar到您的项目并像下面这样初始化库:

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

Afterwards the proxy settings are available to Java API via java.net.ProxySelector.

之后,代理设置可通过java.net.ProxySelector.

The only problem with this approach is that you need to start JVM with deploy.jarin bootclasspath e.g. java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. If somebody knows how to overcome this limitation, let me know.

这种方法的唯一问题是您需要deploy.jar在引导类路径中启动 JVM,例如java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar. 如果有人知道如何克服这个限制,请告诉我。

回答by nylas

I think configuring WINHTTPwill also work.

我认为配置WINHTTP也可以。

Many programs including Windows Updates are having problems behind proxy. By setting up WINHTTP will always fix this kind of problems

包括 Windows 更新在内的许多程序在代理背后都存在问题。通过设置 WINHTTP 总能解决这类问题

回答by gr5

To use the system proxy setup:

要使用系统代理设置:

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

Or programatically:

或以编程方式:

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

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

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

回答by Pallavi

I am also behind firewall, this worked for 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();