维护Java应用程序配置文件的最佳方法

12

我正在编写一个Java应用程序,其中包含许多可保存的设置。基本上我的配置结构看起来像这样:

Config
|_ 游戏1
   |_ 游戏名称: blah...
   |_ 玩家名称: alice
   |_ 玩家名称: bob
   |_ 其他设置...
|_ 游戏2
   |_ 游戏名称: hah
   |_ 玩家名称: alice
   |_ 玩家名称: bob
   |_ 其他设置...
|_ 游戏n....

你明白了。我尝试使用XML,但使用DOM4J很痛苦,特别是有许多具有相同名称的子节点存在于不同和相同的父节点中,而且我需要经常更改它们。到目前为止,我发现最无麻烦的方法是使用纯文本文件,如下所示:

[游戏1]
游戏名称: blah
玩家名称: alice
玩家名称: bob
...
[游戏2] ...

但我感觉这非常简陋。那么,在Java中维护配置文件的最佳实践或标准做法是什么?

编辑:我希望解决方案是可移植的,例如从一台计算机复制文件到另一台计算机不会导致程序出错。(抱歉忘记提前说明这一点了。)

4个回答

5

2
考虑使用YAML来定义您的配置,与XML相比,它要简洁得多,例如:

YAML

games:
  - name: 'game 1'
    players: ['Bob', 'Alice']
    ...
  - name: 'game 2'
    players: ['Bob', 'Alice']
    ...

您可以使用Jackson库和YAML扩展来与配置进行交互,例如解析配置:

File configFile = new File("...");
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
Configuration config = mapper.readValue(configFile, Configuration.class);

YAML 在不同的堆栈之间至少非常可移植。这是作者要求之一。 - nialloc

2
您应该使用自动序列化程序来编写您的XML文件。几年前,我使用了CastorXML,但今天可能有更现代的API来实现这个目的。
使用此API,您基本上需要:
  • 将所有配置存储在一个简单的POJO中
  • 实例化一个Marshaller
  • 调用marshaller.write(MyConfig)
当您想要加载配置时:
  • 实例化Unmarshaller
  • 调用Marshaller.read(yourFile)
您可以在配置文件中描述XML映射,也可以使用默认的Marshaller(1个属性~ 1个XML标记)。
就是这么简单。
编辑:
this thread的搜索之后,JAXB规范在CastorXML的第一个版本之后出现,Sun对JAXB的实现现在似乎成为Java <-> XML映射的标准。

关键问题在于我有很多相同名称的属性,比如“玩家名称”。因此,当我想将“Alice”更改为“Leo”时,我希望确保它不会覆盖这里的“Bob”。CastorXML能保证吗?谢谢。 - YankeeWhiskey

1

请查看Apache Commons Configuration

它为分层配置提供了良好的支持。

XMLConfiguration config = new XMLConfiguration("games.xml");
String gameName = config.getString("game1.name");
List<Object> playerNames = config.getList("game1.players.player.name");
// ...
config.setProperty("game1.name", "Space Invaders"); // update game name
config.addProperty("game1.players.player(-1).name", "ted"); // add new players
config.addProperty("game1.players.player(-1).name", "carol"); 
config.clearTree("game1.players.player(1)"); // remove a player

// Or with XPath 
config.setExpressionEngine(new XPathExpressionEngine());
config.addProperty("game1/players player/name", "ted"); 
config.addProperty("game1/players player/name", "carol"); 
config.clearTree("game1/players/player[2]");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接