Windows で実行する Java (1.7) アプリケーションを作成しています。アプリケーションは、同じホストで実行されている追加のサービスと、インターネットで実行されている他のサービスにアクセスしています。アプリケーションは 2 つの環境で実行できますが、一方ではプロキシ設定を指定する必要があります (インターネットへのアクセス時にプロキシが存在します)。一方、他の環境では、プロキシ設定を指定してはなりません(プロキシはありません)。
アプリケーションをシンプルにして、ユーザーがコマンドライン (-Dhttp.proxyHost など) でのプロキシ設定の指定に煩わされないようにしたい - アプリケーションは、Windows システム設定(IE / Tools)からプロキシ設定を学習する必要があります。 / インターネット プロパティ / 接続 / LAN 設定)。
その設定を学習するはずのコードを書きました。以下を参照してください。問題は、このコードがlocalhost、127.0.0.1、およびmy-computer-name ( my-computer-name は私のコンピューターの名前) を、アクセス時にプロキシをバイパスする必要がある URL として識別しないことです (yes 、「ローカルアドレスにはプロキシサーバーをバイパスする」がチェックされています)。その結果、アプリケーションは間違ったプロキシ経由でローカル サービスにアクセスしようとします。
これまでのところ、「ローカルアドレス」にプロキシを使用しないようにJVMに教える1つの方法は、プロキシ設定/例外に文字列(localhost、127.0.0.1、my-computer-name)をリストすることです(プロキシを使用しないでくださいで始まるアドレスのサーバー)。明らかに、これは適切な解決策ではありません。通常、これらの文字列をそこにリストする人は誰もいないからです (Java 以外のアプリケーションの場合は、最初のチェック ボックスで十分です)。
2番目の(簡単な)解決策は、コードの一部でこれらの文字列をカウントし、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;
}