简体   繁体   English

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

[英]Does Java's ProxySelector not work with automatic proxy configuration scripts?

I want my Java program to use the system's proxy configuration.我希望我的 Java 程序使用系统的代理配置。 Accordingly, I used the code found in many places, such as this answer , to set java.net.useSystemProxies to true and call ProxySelector.getDefault().select(...) to discover the proxy for the particular host I want to reach.因此,我使用在许多地方找到的代码,例如这个 answer ,将java.net.useSystemProxies设置为 true 并调用ProxySelector.getDefault().select(...)来发现我想要的特定主机的代理抵达。 This works fine when I've configured a single explicit proxy server in Internet Properties.当我在 Internet 属性中配置了单个显式代理服务器时,这可以正常工作。 But if I have set "Use automatic configuration script", it always returns the DIRECT "proxy".但是如果我设置了“使用自动配置脚本”,它总是返回直接的“代理”。

I know that the script works, as my browser can access the hosts for which it returns a proxy server, and without the script set, it can't.我知道该脚本有效,因为我的浏览器可以访问它为其返回代理服务器的主机,而如果没有脚本集,它就不能。 I even tried simplifying the script to its barest essentials:我什至尝试将脚本简化为最基本的要素:

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

and it works in my browser, but ProxySelector.getDefault().select(...) still returns only DIRECT.它在我的浏览器中工作,但ProxySelector.getDefault().select(...)仍然只返回 DIRECT。

Am I missing something?我错过了什么吗? (This is on Java 1.6 & Windows 7, should it matter.) (这是在 Java 1.6 和 Windows 7 上,如果有关系的话。)

No, the Java ProxySelector does not read Proxy Auto-Config (PAC) files. 不,Java ProxySelector不读取代理自动配置(PAC)文件。

However, as suggested by Brian de Alwis as an answer to my similar question, the Proxy Vole library appears to provide that support/capability. 但是, 正如Brian de Alwis对我的类似问题的回答所建议的那样, Proxy Vole库似乎提供了这种支持/功能。

To provide network connectivity out of the box for you Java application you can use the Proxy - Vole library. 要为Java应用程序提供开箱即用的网络连接,您可以使用Proxy-Vole库。 It provides some strategies for autodetecting the current proxy settings. 它提供了一些自动检测当前代理设置的策略。 There are many configureable strategies to choose from. 有许多可配置的策略可供选择。 At the moment Proxy - Vole supports the following proxy detection strategies. 目前,Proxy-Vole支持以下代理检测策略。

  • Read platform settings (Supports: Windows, KDE, Gnome, OSX) 读取平台设置(支持:Windows,KDE,Gnome,OSX)
  • Read browser setting (Supports: Firefox 3.x, Internet Explorer; Chrome and Webkit use the platform settings) 读取浏览器设置(支持:Firefox 3.x,Internet Explorer; Chrome和Webkit使用平台设置)
  • Read environment variables (often used variables on Linux / Unix server systems) 读取环境变量(Linux / Unix服务器系统上经常使用的变量)
  • Autodetection script by using WPAD/PAC (Not all variations supported) 使用WPAD / PAC自动检测脚本 (不支持所有变体)

As already suggested by Mads Hansen, Proxy-Vole does the trick! 正如Mads Hansen已经提出的那样, Proxy-Vole可以解决问题!

You just need to add the jar from the download site to your classpath (dlls are included) and this code helped me to configure the proxy stettings: 您只需要将下载站点中的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); 
   } 
 } 
}

Yes, from version 9 automatic proxy configurations (PAC/WPAD) will be read from the operating system.是的,从版本 9开始,将从操作系统读取自动代理配置 (PAC/WPAD)。

I could load Proxy Auto-Config (PAC) file on Java. 我可以在Java上加载Proxy Auto-Config(PAC)文件。 Please see below codes and package. 请参阅以下代码和包装。 I hope this would what you were looking for: 我希望这会是你想要的:

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

You already have a [com.sun.deploy.net.proxy] package on your machine! 您的计算机上已经有[com.sun.deploy.net.proxy]包了! Find [deploy.jar] ;D 找到[deploy.jar]; D.

You can use Proxy Vole to solve this issue: 您可以使用Proxy Vole来解决此问题:

If you know exactly which PAC-file you want to use, you can do: 如果您确切知道要使用哪个PAC文件,则可以执行以下操作:

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

ProxySelector.setDefault(selector);

The advantage of this is that it is not user-related. 这样做的好处是它与用户无关。 For example if running this as a Windows service, you may end up running it on the SYSTEM-user which may not have the same OS_DEFAULT proxy settings (if any) as the Administrator-user. 例如,如果将其作为Windows服务运行,则可能最终在SYSTEM用户上运行它,该用户可能没有与管理员用户相同的OS_DEFAULT代理设置(如果有)。

The approach using system/software values is: 使用系统/软件值的方法是:

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

ProxySelector.setDefault(proxySelector); 

This starts with OS_DEFAULT , then JAVA and lastly BROWSER as strategies for the proxy selector. 这从OS_DEFAULT开始,然后是JAVA ,最后是BROWSER作为代理选择器的策略。

This code is based on the GitHub code, release version 1.0.3. 此代码基于GitHub代码,发行版本1.0.3。

Answering a 10-year-old question for benefit of anybody who stumbles to this thread via web search.通过 web 搜索,回答一个 10 年前的问题,以帮助任何偶然发现此线程的人。

The simplest solution is to configure the proxy on the OS and let the JVM pick up the system values on the program startup automatically via the standard JVM system property java.net.useSystemProxies .最简单的解决方案是在操作系统上配置代理,让 JVM 通过标准 JVM 系统属性java.net.useSystemProxies在程序启动时自动获取系统值。

You could supply this externally to the program via command line args as -Djava.net.useSystemProxies=true or hardcode this requirement in the program entry point via System.setProperty("java.net.useSystemProxies", "true")您可以通过命令行参数将其从外部提供给程序-Djava.net.useSystemProxies=true或通过System.setProperty("java.net.useSystemProxies", "true")在程序入口点硬编码此要求
This ensures your code is easily portable and externally configurable by operations, as it does not involve any code bits to guess the proxy setting.这可确保您的代码易于移植并通过操作在外部进行配置,因为它不涉及任何代码位来猜测代理设置。

Refer the documentation for proxies here: https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies请参阅此处的代理文档: https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM