无法使用嵌套键读取配置
Fail to read configuration with nested keys
使用 Ficus 库,我正在尝试读取具有以下外观的配置文件:
//myfile.conf
macro: {
micro: {
a: "a"
security.something: "b"
}
}
当我尝试从中获取 Map[String, String]
时,使用:
import net.ceedubs.ficus.Ficus._
import net.ceedubs.ficus.Ficus.toFicusConfig
import net.ceedubs.ficus.readers.ArbitraryTypeReader._
...
myfileConfig.getConfig("macro").as[Map[String, String]](micro)
,我收到以下错误:
Exception in thread "main" com.typesafe.config.ConfigException$WrongType: myfile.conf @ file:/[XXX]/myfile.conf: 5: security has type OBJECT rather than STRING
我没有找到解决该错误的方法。此错误的解决方法是什么?
--------编辑------
我不知道结构可能是什么,也不知道键;但我知道它永远不会超过一维对象,因此仅限于泛型。
所以背后的想法是无论结构解释成什么都得到配置(String, String)
。
你的 as[Map[String, String]]
说所有值都应该是字符串,正如异常消息所说,键 security
的值不是字符串(你的配置等同于
macro: {
micro: {
a: "a"
security: {
something: "b"
}
}
}
)。所以你不想要 Map[String, String]
。
但是应该如何修复取决于您对 micro
下预期结构的了解程度:例如应该总是有一个 a
和一个 security.something
吗?还是可以有任意键?等等等等
你的结构比Map[String, String]
复杂得多。
我会使用 pureconfig,这样可以非常简单地将配置直接映射到 case classes
。
你的例子是:
case class Micro(a: String, security: Security)
case class Security(soemthing: String)
import pureconfig.generic.auto._
pureconfig.loadConfig[Micro]
我找到了一些方便的东西:
import scala.collection.JavaConversions._
implicit class ConfigurationBouiboui(myConfiguration: Config) {
def load[T](name: String): Map[String, T] = {
myConfiguration // configuration before target
.getConfig(name).entrySet() // configuration as path-value pairs
.map(x => (x.getKey, x.getValue.unwrapped().asInstanceOf[T])) // (dirty) cast value to T
.toMap
}
}
与:
// complex.conf
complex: {
a: "a"
b: {
ba: "4"
bb: 4
bc: {
bca: "bca"
}
}
c: "c"
}
,我得到:
val config = ConfigFactory.load("complex.conf")
val configurationMap = load(complex)
println(configurationMap)
//outputs: Map(b.bc.bca -> bca, a -> a, b.bb -> 4, b.ba -> 4, c -> c)
使用 Ficus 库,我正在尝试读取具有以下外观的配置文件:
//myfile.conf
macro: {
micro: {
a: "a"
security.something: "b"
}
}
当我尝试从中获取 Map[String, String]
时,使用:
import net.ceedubs.ficus.Ficus._
import net.ceedubs.ficus.Ficus.toFicusConfig
import net.ceedubs.ficus.readers.ArbitraryTypeReader._
...
myfileConfig.getConfig("macro").as[Map[String, String]](micro)
,我收到以下错误:
Exception in thread "main" com.typesafe.config.ConfigException$WrongType: myfile.conf @ file:/[XXX]/myfile.conf: 5: security has type OBJECT rather than STRING
我没有找到解决该错误的方法。此错误的解决方法是什么?
--------编辑------
我不知道结构可能是什么,也不知道键;但我知道它永远不会超过一维对象,因此仅限于泛型。
所以背后的想法是无论结构解释成什么都得到配置(String, String)
。
你的 as[Map[String, String]]
说所有值都应该是字符串,正如异常消息所说,键 security
的值不是字符串(你的配置等同于
macro: {
micro: {
a: "a"
security: {
something: "b"
}
}
}
)。所以你不想要 Map[String, String]
。
但是应该如何修复取决于您对 micro
下预期结构的了解程度:例如应该总是有一个 a
和一个 security.something
吗?还是可以有任意键?等等等等
你的结构比Map[String, String]
复杂得多。
我会使用 pureconfig,这样可以非常简单地将配置直接映射到 case classes
。
你的例子是:
case class Micro(a: String, security: Security)
case class Security(soemthing: String)
import pureconfig.generic.auto._
pureconfig.loadConfig[Micro]
我找到了一些方便的东西:
import scala.collection.JavaConversions._
implicit class ConfigurationBouiboui(myConfiguration: Config) {
def load[T](name: String): Map[String, T] = {
myConfiguration // configuration before target
.getConfig(name).entrySet() // configuration as path-value pairs
.map(x => (x.getKey, x.getValue.unwrapped().asInstanceOf[T])) // (dirty) cast value to T
.toMap
}
}
与:
// complex.conf
complex: {
a: "a"
b: {
ba: "4"
bb: 4
bc: {
bca: "bca"
}
}
c: "c"
}
,我得到:
val config = ConfigFactory.load("complex.conf")
val configurationMap = load(complex)
println(configurationMap)
//outputs: Map(b.bc.bca -> bca, a -> a, b.bb -> 4, b.ba -> 4, c -> c)