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

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


当前回答

使用系统代理设置:

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

或编程:

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

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

其他回答

这对我来说很管用:

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:我基于GHad的回答。

JVM使用代理进行HTTP调用

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

这可以使用用户设置代理

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

读取一个XML文件,并需要下载它的模式

如果您依赖于通过internet检索模式或dtd,那么您正在构建一个缓慢、频繁且脆弱的应用程序。当托管文件的远程服务器发生计划内或计划外停机时,会发生什么?你的应用程序崩溃了。这样可以吗?

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

模式和类似的URL最好被认为是唯一标识符。而不是远程访问文件的请求。在“XML目录”上做一些谷歌搜索。XML目录允许您在本地托管这些资源,从而解决了慢、多和脆弱的问题。

它基本上是远程内容的永久缓存副本。这是可以的,因为远程内容永远不会改变。如果有更新,也会是另一个网址。使得在互联网上实际检索资源变得特别愚蠢。

最近,我发现了允许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;
    }
}

之后,可以通过java.net.ProxySelector将代理设置提供给Java API。

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

这是一个小更新,但是从Java 7开始,现在可以通过编程方式创建代理连接,而不是通过系统属性。这可能是有用的,如果:

代理需要在程序运行时动态旋转 需要使用多个并行代理 或者只是让你的代码更干净:)

这是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()
}

全部参考: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html