检索 Java net.properties 文件中定义的默认值

retrieving default values defined in Java net.properties file

如果我 Java Networking and Proxies 的理解正确,jre/lib/net.properties 文件包含在 运行 时填充到系统属性中的默认值。我的 net.properties 文件包含以下内容:

http.nonProxyHosts=localhost|127.*|[::1]

但是当我 运行 我的 Java 应用程序在 Eclipse 4.5 中时,System.getProperty("http.nonProxyHosts") returns null我没有在我的应用程序中的任何地方定义或覆盖这个值。

如何在 运行 时检索 jre/lib/net.properties 中定义的 http.nonProxyHosts 的值?

结论总结

  1. 文件 ${java.home}/lib/net.properties 没有加载到 System Properties (System::getProperties)
  2. 通过 System.setProperty 手动设置代理,或在命令行设置,例如使用 -Dhttp.proxyHost=proxy 语法,将覆盖定义的 属性,但也会覆盖任何 java.net.useSystemProxies 设置即使设置为 true.
  3. 您可以访问 net.properties 文件,方法是使用 Properties::load. The exact location is in the Java Home directory, which can be retrieved using the java.home 系统 属性 将其手动加载为属性,位于 lib 子目录中。
  4. 在 windows 桌面上,当与 java.net.useSystemProxies=true 结合使用时,您可以在 'Internet Properties' 下的控制面板中设置使用的代理。在这些设置中,您需要单击 'LAN settings' 按钮。
  5. 小程序有额外的设置级别,请参阅 Java 文档中的 Proxy Setup

研究

我已经在我的环境中复制了您的示例,实际使用 netBeans,这个简单的示例:

public class Play {
  public static void main(String args[]) { 
    System.out.println(System.getProperty("java.home"));
    System.out.println(System.getProperty("http.nonProxyHosts"));
    System.out.println(System.getProperty("java.net.useSystemProxies"));
 }
}

我打印 java.home 系统 属性 以确保我正在编辑正确的 jre/lib/net.properties

但是 http.nonProxyHostsjava.net.useSystemProxies 这两个属性打印为 null,而我可以清楚地看到这两个值都在 net.properties 文件中设置:

java.net.useSystemProxies=false
http.nonProxyHosts=localhost|127.*|[::1]

实际上文档有点不清楚,但似乎可以通过以下几种方式之一完成代理配置:

  1. jre/lib/net.properties 默认
  2. java.net.useSystemProxies 设置为 true 时,从您系统的互联网设置(控制面板等)。
  3. 来自 Java 配置,在您的 Java 控制面板中设置,当 运行 作为 Applet 时,可能继承您的浏览器设置。
  4. System.properties

在我看来,这是 java.net api 的自定义功能,只有在系统属性未明确设置的情况下才会读取 net.properties。我怀疑 not 是否意味着 net.properties 文件用于设置系统属性,但只能由 java.net api 自己读取.

另请注意默认安装的 net.properties 文件中的这段文字:

This file may contain default values for the networking system properties. These values are only used when the system properties are not specified on the command line or set programatically.

它只是说这些值将被使用,没有关于设置系统属性本身的具体说明。

[更新]

通过一个小例子,我能够证明

import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.util.List;

public class Play {
  public static void main(String args[]) { 
    System.out.println(System.getProperty("java.home"));
    System.out.println(System.getProperty("http.proxyHost"));
    ProxySelector ps = ProxySelector.getDefault();
    List<Proxy> proxies = ps.select(URI.create("http://www.yahoo.com"));
    System.out.println("HTTP Proxies");
    for (Proxy p:proxies) {
      System.out.append(p.toString()).append("\n");
    }
 }
}

您可以看到 http.proxyHost 打印为 null,而使用默认值 net.properties"http://www.yahoo.com" 的代理打印为 DIRECTDIRECT 表示没有代理。这是因为在 net.properties file,http.proxyHost` 中未定义。

现在我修改 net.properties 文件如下(取消注释并修改现有条目):

http.proxyHost=this.is.a.test.net

现在当我 运行 相同的代码时,我得到以下输出:

C:\Program Files\Java\jdk1.8.0_20\jre
null
HTTP Proxies
HTTP @ this.is.a.test.net:80

系统 属性 仍然为空,但是 net.properties 文件中的相同设置确实生效了。

其他一些观察:

  1. 当如下显式设置系统 属性 时:System.setProperty("http.proxyHost", "other.net"); 就在执行 ProxySelector::select 之前,将覆盖 net.properties 中的值。
  2. 使用系统属性覆盖将影响完全相同的系统属性。也就是说,如果你只覆盖http.proxyHost,如果在net.properties.
  3. 中设置,它仍然会继承http.proxyPort
  4. 如果在 net.properties 文件中的任何地方,或者通过在代码中明确设置系统 属性,我明确设置了 http.proxyHost,这将始终覆盖系统默认值,即使在java.net.useSystemProxies 设置为真。 java.net.useSystemProxies=true 仅在未明确设置代理时有效,否则将被忽略(我已经测试并验证了这一点)。

[更新 2]

如果您的最终目标只是访问net.properties文件的内容,您可以尝试如下操作:

import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;

public class Play {
  public static void main(String args[]) { 
    Properties props = new Properties();
    Path path = Paths.get(System.getProperty("java.home"), "lib", "net.properties");

    try (Reader r = Files.newBufferedReader(path)) {
      props.load(r);
      System.out.println("props loaded!");
    } catch (IOException x) {
      System.err.println("props failed loading!");
      x.printStackTrace(System.err);
    }
    // Now you have access to all the net.properties!
    System.out.println(props.getProperty("http.proxyHost"));
 }
}

你搞清楚了安全和特权!