[英]Does Java's ProxySelector not work with automatic proxy configuration scripts?
我希望我的 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 上,如果有关系的话。)
不,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自动检测脚本 (不支持所有变体)
正如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);
}
}
}
是的,从版本 9开始,将从操作系统读取自动代理配置 (PAC/WPAD)。
我可以在Java上加载Proxy Auto-Config(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.
您可以使用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。
通过 web 搜索,回答一个 10 年前的问题,以帮助任何偶然发现此线程的人。
最简单的解决方案是在操作系统上配置代理,让 JVM 通过标准 JVM 系统属性java.net.useSystemProxies
在程序启动时自动获取系统值。
您可以通过命令行参数将其从外部提供给程序-Djava.net.useSystemProxies=true
或通过System.setProperty("java.net.useSystemProxies", "true")
在程序入口点硬编码此要求
这可确保您的代码易于移植并通过操作在外部进行配置,因为它不涉及任何代码位来猜测代理设置。
请参阅此处的代理文档: https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.