如何在Java中学习系统(Windows)非代理主机

时间:2013-10-21 13:47:07

标签: java windows proxy localhost system

我正在编写一个在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;
}

0 个答案:

没有答案