我有一个属性文件,就像这样 -
emailFrom=hello@abc.com
emailTo=world@abc.com
# can be separated by comma
whichServer=UserServer,GuestServer
maxTestInSec=120
numberOfUsers=1000
现在我正在Java中读取这个属性文件,如果一切设置正确,它将起作用 -
private static final Properties prop = new Properties();
private static String emailFrom;
private static String emailTo;
private static List<String> whichServer;
private static String maxTestInSec;
private static String numberOfUsers;
public static void main(String[] args) {
readConfig(args);
}
private void readConfig(String[] args) throws FileNotFoundException, IOException {
if (!TestUtils.isEmpty(args) && args.length != 0) {
prop.load(new FileInputStream(args[0]));
} else {
prop.load(TestTask.class.getClassLoader().getResourceAsStream("config.properties"));
}
emailFrom = prop.getProperty("emailFrom").trim();
emailTo = prop.getProperty("emailTo").trim();
whichServer = Arrays.asList(prop.getProperty("whichServer").trim().split(","));
maxTestInSec = prop.getProperty("maxTestInSec").trim();
numberOfUsers = prop.getProperty("numberOfUsers").trim();
}
问题陈述: -
我需要确保如果缺少任何属性值,那么我想使用默认值,如果该属性被注释掉,那么我也想使用默认值,但我会记录一个警告消息说明属性丢失或为空,因此使用默认值。我试图涵盖阅读文件的所有角落案例 -
emailFrom
字段提供任何值,那么我想将默认值用作hello@abc.com
,对于其他人则类似。所有属性的默认值为:emailFrom=hello@abc.com
emailTo=world@abc.com
whichServer = UserServer的
maxTestInSec = 30
numberOfUsers = 500
我应该开始使用命令行解析器吗?什么是处理这些东西的最好和最干净的方法?
我不希望有很多if块来添加支票然后设置默认值。
答案 0 :(得分:1)
从Java 8开始,最简单的方法是使用getOrDefault()
,它允许您在get-site上指定默认值。例如:
String email = properties.getOrDefault("emailFrom", "hello@abc.com");
这是简洁明了的,但这意味着您需要在访问该属性的任何地方指定默认值。
如果这对你不起作用(即你不止一次从属性对象中读取值),你可以使用内置的默认值支持 - 注意constructor需要default
Properties
个对象。这允许您构造包含默认值的Properties
对象,然后在加载用户的属性文件时,如果用户没有指定值,它将回退到默认值。
private static final Properties DEFAULTS = new Properties();
static {
DEFAULTS.setProperty("emailFrom", "hello@abc.com");
}
public Properties getProperties() {
Properties props = new Properties(DEFAULTS);
props.load(...);
return props;
}
请注意,这与Map
的构造函数的工作方式不同 - 默认值保留为单独的地图,只有.getProperty()
也会查询默认值; Map
中定义的方法与.get()
不同。 Properties
Hashtable
扩展Properties
是一个可怕的决定的原因之一,但是c&#39; est la vie ...
这些选项有效,但它们都容易出错,因为a)default
是可变的,而b)只有一些公共方法可以回退Properties
实例。我更喜欢不直接公开public class ApplicationSettings {
private final Properties properties = new Properties();
public ApplicationSettings() {
properties.load(...);
}
public String emailFrom() {
// simple methods are concise, and encode the default right inline
return properties.getOrDefault("emailFrom", "hello@abc.com");
}
public int getMaxTestSeconds() {
// You can do more complex validation if you want, too
String value = properties.get("maxTestInSec");
if (value == null) {
return 30;
}
int maxTestSeconds = Integer.parseInt(value);
if (maxTestSeconds <= 0) {
// could instead log a warning and return the default if you want
throw new IllegalStateException(
"maxTestInSec must be positive - was " + maxTestSeconds);
}
return maxTestSeconds;
}
}
个对象,而是使用类型安全的方法创建一个包装类,公开我的应用程序将关注的值。这是一个更多的打字,但它更安全。它看起来像这样:
Properties
如果需要,还可以在将值添加到DocumentCollection collectionInfo = new DocumentCollection();
collectionInfo.Id = collectionName;
// Configure collections for maximum query flexibility including string range queries.
collectionInfo.IndexingPolicy = new IndexingPolicy(new RangeIndex(DataType.String) {
Precision = -1
});
对象之前公开类似验证值的setter,但默认情况下,将所有内容设置为只读通常是一种很好的做法。
答案 1 :(得分:0)
如果属性被注释掉,则返回值为null,因此只需进行空检查。
if (prop.getProperty("name")==null)
如果未填充值,请在修剪操作后检查其是否等于空格。
if (prop.getProperty("name").trim().equals(""))
答案 2 :(得分:0)
在实际使用之前,您可以尝试将属性兑现为静态地图并在该地图上进行处理。
private Map<String, String> rawProps = new HashMap<String, String>;
public static Map<String, String> actualProps = new HashMap<String, String>;
static {
checkMapForNullAndReport();
}
private static void checkMapForNullAndReport() {
// Null logic and Reporting logic
// Empty rawProps and populate the actualProps
}
像我这样的东西对你有用。