【问题标题】:Java properties containing dollar delimited variables包含美元分隔变量的 Java 属性
【发布时间】:2011-12-08 00:17:34
【问题描述】:

我将我的应用程序设置存储在我在 Ant 和 Java 应用程序中使用的属性文件中。也许这不是很好的做法,但我发现避免重复非常方便。该文件包含以下变量:

usefulstuff.dir = ${user.home}/usefulstuff

这样其他人就可以在 *nix 系统上运行该程序,前提是他们的主目录中有有用的文件夹。

现在,令人着迷的是,这个属性文件在 Ant 中运行良好(变量被解析为 /home/username),而当我直接在 Java 应用程序中加载同一个文件时,我得到了一个包含${user.home}/usefulstuff的字符串,确实不是很有用。

我在 Ant 中使用此代码加载道具:

   <loadproperties srcFile="myProps.properties"/>

在 Java 应用程序中:

    FileInputStream ins = new FileInputStream(propFilePath);
    myProps.load(ins);
    ins.close();

我错过了什么吗?也许有比load() 更好的方式在Java 应用程序中加载属性?

【问题讨论】:

标签: java variables ant properties dollar-sign


【解决方案1】:

我不认为这在 Ant 中工作特别“令人着迷” - Ant is deliberately written to do so:

属性是 Apache Ant 尝试在运行时将 ${key} 扩展为值的键值对。

Ant 提供对所有系统属性的访问,就好像它们是使用&lt;property&gt; 任务定义的一样。例如,${os.name} 扩展为操作系统的名称。

如果您想要相同的行为,则需要实现相同的逻辑。您可以直接使用 Ant 中的类,前提是它们可以满足您的需求 - 并且您愿意发布相关的二进制文件(并遵守许可证)。

否则,您可能希望使用正则表达式来查找所有匹配项 - 或者(可能更简单)迭代所有系统属性并对其进行简单替换。

【讨论】:

    【解决方案2】:

    正如 Jon 所说,自己编写属性处理应该是直截了当的。例如:

    import java.util.*;
    
    public class PropertiesTest
    {
        public static void main(String[] args)
        {
            Properties props = new Properties();
            props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
            props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
    
            System.out.println("BEFORE:");
            printProperties(props);
    
            resolveSystemProperties(props);
    
            System.out.println("\n\nAFTER:");
            printProperties(props);
        }
    
        static void resolveSystemProperties(Properties props)
        {
            Map<String, String> sysProps = readSystemProperties();
            Set<String> sysPropRefs = sysProps.keySet();
    
            Enumeration names = props.propertyNames();
            while (names.hasMoreElements())
            {
                String name = (String) names.nextElement();
                String value = props.getProperty(name);
                for (String ref : sysPropRefs)
                {
                    if (value.contains(ref))
                    {
                        value = value.replace(ref, sysProps.get(ref));
                    }
                }
                props.setProperty(name, value);
            }
        }
    
        static Map<String, String> readSystemProperties()
        {
            Properties props = System.getProperties();
            Map<String, String> propsMap = 
                new HashMap<String, String>(props.size());
    
            Enumeration names = props.propertyNames();
            while (names.hasMoreElements())
            {
                String name = (String) names.nextElement();
                propsMap.put("${" + name + "}", props.getProperty(name));
            }
            return propsMap;
        }
    
        static void printProperties(Properties props)
        {
            Enumeration names = props.propertyNames();
            while (names.hasMoreElements())
            {
                String name = (String) names.nextElement();
                String value = props.getProperty(name);
                System.out.println(name + " => " + value);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2017-09-15
      • 2020-09-29
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多