我正在编写一个在Windows上运行的Java(1.7)应用程序。该应用程序正在访问在相同主机上运行的其他服务以及在 Internet中运行的其他服务。该应用程序可以在两个环境中运行,其中一个代理设置必须指定(访问Internet时有代理);而在其他环境中,代理设置不能指定(没有代理)。
我希望应用程序很简单,不希望用户在cmd-line上指定代理设置(-Dhttp.proxyHost等) - 应用程序应该从Windows学习代理设置系统设置(IE /工具/ Internet属性/连接/ LAN设置)。
我已经编写了一段应该学习这些设置的代码,见下文。问题是这段代码不能识别 localhost , 127.0.0.1 和 my-computer-name (其中我的电脑名称)是我的计算机的名称)作为访问代理时应该绕过的URL(是的,我确实已经选中了“为本地地址绕过代理服务器”)。因此,应用程序尝试通过错误的代理访问本地服务。
到目前为止,我发现教JVM不使用代理'本地地址'的一种方法是在代理设置/异常(Do)中列出字符串(localhost,127.0.0.1,my-computer-name)不使用代理服务器的地址开头)。显然,这不是一个好的解决方案,因为通常没有人在那里列出这些字符串(第一个复选框足以用于非Java应用程序)。
第二个(普通的)解决方案就是在我的代码片段中使用这些字符串进行计数,即使JVM认为不是这样,也不要使用代理设置。我不认为这是一个很好的解决方案,如果这是唯一的解决方案,恕我直言,JVM中存在缺陷。
我在互联网上找到了很多资源如何学习系统代理设置。但是如何学习非代理设置?
谢谢, PP
public static final String HTTP_PROXY_HOST_KEY = "http.proxyHost";
public static final String HTTPS_PROXY_HOST_KEY = "https.proxyHost";
public static final String HTTP_PROXY_PORT_KEY = "http.proxyPort";
public static final String HTTPS_PROXY_PORT_KEY = "https.proxyPort";
public static final String NO_PROXY_HOSTS_KEY = "http.nonProxyHosts";
// provide list of urls which are to be accessed by this application and return proxy and non-proxy settings
private Properties getSystemProxyConfiguration(String[] urls) {
log.debug("Getting system proxy");
Properties properties = new Properties();
SortedSet<String> nonProxyHosts = new TreeSet<>();
for (String url : urls) {
URI uri;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
throw new IllegalStateException(e);
}
InetSocketAddress address = getSystemProxy(uri);
if (address != null) {
if (url.toLowerCase().startsWith("https")) {
properties.put(HTTPS_PROXY_HOST_KEY, address.getHostString());
properties.put(HTTPS_PROXY_PORT_KEY, ""+address.getPort());
//todo verify that all previous URLs in this array are using the same proxy
log.debug("HTTPS proxy: " + address.getHostString() + ":" + address.getPort());
} else {
properties.put(HTTP_PROXY_HOST_KEY, address.getHostString());
properties.put(HTTP_PROXY_PORT_KEY, ""+address.getPort());
//todo verify that all previous URLs in this array are using the same proxy
log.debug("HTTP proxy: " + address.getHostString() + ":" + address.getPort());
}
} else { //todo DEFECT -> this does not find the non-proxy hosts (even though specified in IE Internet settings)
nonProxyHosts.add(uri.getHost());
}
}
if (nonProxyHosts.size() > 0) {
String nonProxyHostsString = nonProxyHosts.first();
nonProxyHosts.remove(nonProxyHostsString);
for (String nonProxyHost : nonProxyHosts) {
nonProxyHostsString = nonProxyHostsString + "|" + nonProxyHost;
}
properties.put(NO_PROXY_HOSTS_KEY, nonProxyHostsString);
log.debug("Non HTTP(S) proxy hosts: "+nonProxyHostsString);
} else {
log.debug("No non HTTP(S) proxy hosts set");
}
return properties;
}
private InetSocketAddress getSystemProxy(URI uri) {
List<Proxy> proxyList;
proxyList = ProxySelector.getDefault().select(uri);
if (proxyList != null && proxyList.size() > 0) { //todo DEFECT - this never returns DIRECT proxy for localhost, 127.0.0.1, my-computer-name strings
Proxy proxy = proxyList.get(0);
if (proxyList.size() > 1) {
log.warn("There is more " + proxy.type() + " proxies available. Use "+PROXY_PROPERTIES_FILE_NAME+" to set the right one.");
}
InetSocketAddress address = (InetSocketAddress) proxy.address();
return address;
}
return null;
}