如何在 Typesafe Config 中获取解开的密钥?

2024-02-05

测试用例:

import org.specs2.mutable._
class HelloWorldSpec extends Specification {
  "Typesafe Config" should "allow me to see my escaped key" in {
    val entries = ConfigFactory.parseString("""
      "quoted.key.1" = 5
      "quoted.key.2" = 6""").entrySet
    entries.head.getKey === "quoted.key.1"
  }
}

这个测试失败了,因为关键实际上是"quoted.key.1", not quoted.key.1。是否有建议的方法来解开这个问题,或者我是否必须手动查找周围的引号并每次删除它们?


在此处阅读 API 文档中的“路径、键和 Config 与 ConfigObject”:http://typesafehub.github.io/config/latest/api/com/typesafe/config/Config.html http://typesafehub.github.io/config/latest/api/com/typesafe/config/Config.html并在自述文件中:https://github.com/typesafehub/config#understanding-config-and-configobject https://github.com/typesafehub/config#understanding-config-and-configobject

(欢迎提出改进这些文档的建议。)

条目集中(和配置)中的键是路径表达式。这些是需要解析的字符串。 ConfigUtil中有一个parse方法,参见http://typesafehub.github.io/config/latest/api/com/typesafe/config/ConfigUtil.html#splitPath%28java.lang.String%29 http://typesafehub.github.io/config/latest/api/com/typesafe/config/ConfigUtil.html#splitPath%28java.lang.String%29

仅删除引号是行不通的,解析比这要复杂一些。幸运的是你可以使用ConfigUtil.splitPath method.

因此,在根级别迭代键的两种方法类似于,首先使用 Config:

Config config = ... ;
for (Map.Entry<String, ConfigValue> entry: config.entrySet()) {
  String[] keys = ConfigUtil.splitPath(entry.getKey());
  System.out.println("Root key = " + keys[0]);
}

然后使用 ConfigObject:

Config config = ... ;
for (Map.Entry<String, ConfigValue> entry: config.root().entrySet()) {
  System.out.println("Root key = " + entry.getKey());
}

我没有尝试编译上面的示例,因此请原谅任何愚蠢的语法错误。

如果您的配置仅包含一层(无嵌套对象),则上述两种迭代方式是相同的;但如果你有嵌套值,它们就不一样了,因为迭代Config会给你一切leaf迭代时的值ConfigObject (config.root())将为您提供根的所有直接子代,即使这些直接子代本身就是对象。

假设你有:

foo {
   bar {
       baz = 10
   }
}

如果你将其迭代为Config你会得到one具有路径的条目foo.bar.baz作为键和值10。如果你将它迭代为ConfigObject那么你将拥有一个包含密钥的条目foo该值将是一个对象,该对象又包含键bar。当将其迭代为Config你可以splitPath the foo.bar.baz你会得到一个由三个字符串组成的数组,foo, bar, and baz.

要转换一个Config to a ConfigObject使用root()方法并转换ConfigObject to Config使用toConfig()方法。所以config.root().toConfig() == config.

另外,上面的配置文件可以等效地写为:

foo.bar.baz = 10

但如果写成:

"foo.bar.baz" = 10

因为在第一种情况下,您有嵌套对象,而在第二种情况下,您有一个键名称中带有句点的单个对象。这是由于引号造成的。

如果你写"foo.bar.baz"带引号,然后在迭代时Config你返回的路径将被引用并且splitPath()将返回一个包含一个元素的数组foo.bar.baz。迭代时ConfigObject您将有一个对象,其中包含一个条目foo.bar.baz作为关键和10作为价值。包含的键.或其他特殊字符必须用引号引起来,以便将它们解释为单个键而不是路径。

为了让你的测试用例通过,你可以使用 splitPath 来做到这一点:

import org.specs2.mutable._
class HelloWorldSpec extends Specification {
  "Typesafe Config" should "allow me to see my escaped key" in {
    val entries = ConfigFactory.parseString("""
      "quoted.key.1" = 5
      "quoted.key.2" = 6""").entrySet
    // the ordering of entrySet is not guaranteed so this may
    // still fail because it gets quoted.key.2 instead
    ConfigUtil.splitPath(entries.head.getKey).head === "quoted.key.1"
  }
}

你也可以这样做,使用ConfigObject:

import org.specs2.mutable._
class HelloWorldSpec extends Specification {
  "Typesafe Config" should "allow me to see my escaped key" in {
    val entries = ConfigFactory.parseString("""
      "quoted.key.1" = 5
      "quoted.key.2" = 6""").root.entrySet // note ".root." here
    // the ordering of entrySet is not guaranteed so this may
    // still fail because it gets quoted.key.2 instead
    // no need to splitPath because ConfigObject has keys not paths
    entries.head.getKey === "quoted.key.1"
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Typesafe Config 中获取解开的密钥? 的相关文章

随机推荐