25

我希望我的 Java 程序使用系统的代理配置。因此,我使用在许多地方找到的代码(例如这个 answer)设置java.net.useSystemProxies为 true 并调用ProxySelector.getDefault().select(...)以发现我想要访问的特定主机的代理。当我在 Internet 属性中配置了单个显式代理服务器时,这可以正常工作。但是如果我设置了“使用自动配置脚本”,它总是返回直接的“代理”。

我知道该脚本有效,因为我的浏览器可以访问它为其返回代理服务器的主机,而如果没有脚本集,它就不能。我什至尝试将脚本简化为最基本的要素:

function FindProxyForURL(url, host)
{
    return "PROXY my.proxy.mydomain:3128";
}

它在我的浏览器中工作,但ProxySelector.getDefault().select(...)仍然只返回 DIRECT。

我错过了什么吗?(这是在 Java 1.6 和 Windows 7 上,如果有关系的话。)

4

5 回答 5

32

不,Java ProxySelector 不读取代理自动配置 (PAC)文件。

但是,正如 Brian de Alwis对我的类似问题的回答所建议的那样,Proxy Vole库似乎提供了这种支持/功能。

要为您的 Java 应用程序提供开箱即用的网络连接,您可以使用 Proxy - Vole 库。它提供了一些自动检测当前代理设置的策略。有许多可配置的策略可供选择。目前 Proxy - Vole 支持以下代理检测策略。

  • 读取平台设置(支持:Windows、KDE、Gnome、OSX)
  • 读取浏览器设置(支持:Firefox 3.x、Internet Explorer;Chrome 和 Webkit 使用平台设置)
  • 读取环境变量(Linux/Unix 服务器系统上常用的变量)
  • 使用 WPAD/PAC 的自动检测脚本(不支持所有变体)
于 2012-04-26T01:03:32.883 回答
15

正如 Mads Hansen 已经建议的那样,Proxy-Vole可以做到这一点!

您只需将下载站点中的 jar 添加到您的类路径(包括 dll),此代码帮助我配置代理设置:

ProxySearch proxySearch = new ProxySearch();
proxySearch.addStrategy(Strategy.OS_DEFAULT); 
proxySearch.addStrategy(Strategy.JAVA); 
proxySearch.addStrategy(Strategy.BROWSER); 
ProxySelector proxySelector = proxySearch.getProxySelector(); 

ProxySelector.setDefault(proxySelector); 
URI home = URI.create("http://www.google.com"); 
System.out.println("ProxySelector: " + proxySelector); 
System.out.println("URI: " + home); 
List<Proxy> proxyList = proxySelector.select(home); 
if (proxyList != null && !proxyList.isEmpty()) { 
 for (Proxy proxy : proxyList) { 
   System.out.println(proxy); 
   SocketAddress address = proxy.address(); 
   if (address instanceof InetSocketAddress) { 
     String host = ((InetSocketAddress) address).getHostName(); 
     String port = Integer.toString(((InetSocketAddress) address).getPort()); 
     System.setProperty("http.proxyHost", host); 
     System.setProperty("http.proxyPort", port); 
   } 
 } 
}
于 2012-09-26T15:01:46.750 回答
5

您可以使用 Proxy Vole 来解决此问题:

如果您确切知道要使用哪个 PAC 文件,您可以执行以下操作:

UrlPacScriptSource source = new UrlPacScriptSource("http://www.example.org/proxy.pac");
PacProxySelector selector = new PacProxySelector(source);

ProxySelector.setDefault(selector);

这样做的好处是它与用户无关。例如,如果将此作为 Windows 服务运行,您最终可能会在 SYSTEM 用户上运行它,该用户可能OS_DEFAULT与管理员用户没有相同的代理设置(如果有)。

使用系统/软件值的方法是:

ProxySearch proxySearch = new ProxySearch();
proxySearch.addStrategy(Strategy.OS_DEFAULT);
proxySearch.addStrategy(Strategy.BROWSER);
proxySearch.addStrategy(Strategy.JAVA);
ProxySelector proxySelector = proxySearch.getProxySelector();

ProxySelector.setDefault(proxySelector); 

这从 开始OS_DEFAULT,然后是JAVA代理BROWSER选择器的策略。

此代码基于 GitHub 代码,发布版本 1.0.3。

于 2017-12-11T13:14:35.750 回答
4

我可以在 Java 上加载代理自动配置 (PAC) 文件。请参阅下面的代码和包装。我希望这将是您正在寻找的:

import com.sun.deploy.net.proxy.*;
.
.
BrowserProxyInfo b = new BrowserProxyInfo();        
b.setType(ProxyType.AUTO);
b.setAutoConfigURL("http://yourhost/proxy.file.pac");       
DummyAutoProxyHandler handler = new DummyAutoProxyHandler();
handler.init(b);

URL url = new URL("http://host_to_query");
ProxyInfo[] ps = handler.getProxyInfo(url);     
for(ProxyInfo p : ps){
    System.out.println(p.toString());
}

您的机器上已经有一个 [com.sun.deploy.net.proxy] 包!查找 [deploy.jar] ;D

于 2012-06-08T15:22:31.553 回答
4

是的,从版本 9开始,将从操作系统读取自动代理配置 (PAC/WPAD)。

于 2019-09-11T14:53:27.513 回答