Java的ProxySelector不能与自动代理配置脚本一起使用吗?

van*_*lle 23 java proxy

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

我知道该脚本有效,因为我的浏览器可以访问它为其返回代理服务器的主机,并且没有脚本集,它不能.我甚至尝试将脚本简化为最基本的要点:

function FindProxyForURL(url, host)
{
    return "PROXY my.proxy.mydomain:3128";
}
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么吗?(这是在Java 1.6和Windows 7上,它是否重要.)

Mad*_*sen 30

不,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自动检测脚本(不支持所有变体)

  • 谢谢你的提示.谷歌搜索"java代理选择器"找不到这个库,除非你足够清楚地意识到经过的一些代码片段是一个有用的库的一部分.遗憾的是,Java本身并没有这样做,因为它具有ProxySelector结构,并且知道如何找到普通的固定代理. (2认同)
  • 顺便说一下,这些指令有点误导,因为"默认"配置是没用的 - 它使用"读取java系统属性"策略,这是你在没有这个库的情况下获得的.对我有用的是ProxySearch proxySearch = new ProxySearch(); proxySearch.addStrategy(Strategy.OS_DEFAULT); myProxySelector = proxySearch.getProxySelector(); (2认同)

der*_*dam 12

正如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); 
   } 
 } 
}
Run Code Online (Sandbox Code Playgroud)

  • 你的代码很棒,谢谢.只是一个小问题 - 第三行应该是`proxySearch.addStrategy(Strategy.JAVA);` (2认同)
  • Proxy-Vole项目自2013年以来一直处于休眠状态,但在GitHub的分支中有一些活动:https://github.com/MarkusBernhardt/proxy-vole (2认同)

Cle*_*nUp 9

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


Hal*_*and 5

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

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

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

ProxySelector.setDefault(selector);
Run Code Online (Sandbox Code Playgroud)

这样做的好处是与用户无关。例如,如果将此作为 Windows 服务运行,您最终可能会在系统用户上运行它,该用户可能没有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); 
Run Code Online (Sandbox Code Playgroud)

首先是OS_DEFAULT,然后JAVABROWSER代理选择器的策略。

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