我正在使用HOCON配置格式,并且解析lib来自typesafe.Config。 HOCON支持环境变量注入和覆盖。喜欢:
my.config = "asd"
my.config = ${?MY_ENV_VAR}
如果存在名为MY_ENV_VAR的环境变量,它将替换默认值“ asd”。但是我似乎找不到任何好的方法来进行列表环境替换。喜欢:
my.config = [1,2,3,4]
my.config = ${?MY_ENV_LIST}
因为默认情况下,外部的env vars将默认为字符串,所以从库的角度来看,[1,2,3,4]
将被视为“ [1,2,3,4]”,因此无法看到作为列表,将产生如下运行时错误:
com.typesafe.config.ConfigException $ WrongType:application.conf:5: application.boolliststring的类型为STRING,而不是LIST
在com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:133) 在com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:145) 在com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:151) 在com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:159) 在com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:164) 在 com.typesafe.config.impl.SimpleConfig.getList(SimpleConfig.java:212)
任何人都知道用HOCON格式进行列表环境替换的正确方法是什么? 提前致谢。
答案 0 :(得分:2)
从一个环境变量到一个数组是不可能的,正如另一个答案所述。
您可以重新解析从配置加载的字符串:
// application.conf
my.config = "list = [1, 2, 3]"
my.config = ${?LIST_VAR}
// code
String listString = ConfigFactory.load().getString("my.config")
ConfigFactory.parseString(listString).getIntList("list")
然后设置 LIST_VAR='list = [4, 5, 6]'
以覆盖默认值。请注意,您需要 list =
因为对象是
需要在 hocon 的顶层,您不能使用数组。
如果您的数据足够干净,您可以在 ,
上拆分:
// application.conf
my.config = "foo,bar,baz"
my.config = ${?CSV_VAR}
// java code
String csvString = ConfigFactory.load().getString("my.config")
String[] parameters = csvString.split(",")
然后,只需设置 CSV_VAR=bing,bang,boom,pow
(没有 []
)。
另一方面,如果您为每个值使用单独的环境变量,则有多种选择。
最简单的,如果你不需要默认值,看起来像这样:
my.config = [ ${?MY_ENV_VAR}, ${?MY_ENV_VAR_TWO} ]
任何未定义的值都将被省略。
如果您只需要添加到默认值,您可以使用 +=
syntax:
my.config = [1, 2]
my.config += ${?MY_ENV_VAR}
my.config += ${?MY_ENV_VAR_TWO}
任何未定义的值都不会添加到数组中。
我发现的最灵活的选项是在您的 application.conf
(或 reference.conf
或 -D
选项或您提供的任何其他配置)中使用 positional syntax:>
my.config.0 = 1 // always set to 1
my.config.1 = 2 // defaults to 2 if MY_ENV_VAR is not set
my.config.1 = ${?MY_ENV_VAR}
my.config.2 = ${?MY_ENV_VAR_TWO} // totally optional
my.config.3 = ${MY_ENV_VAR_THREE} // doesn't have ?, so it is required
任何已定义的值都将被包含在内,任何未定义的值都将被跳过。例如,如果 MY_ENV_VAR=4
,
MY_ENV_VAR_THREE=6
,并且未设置 MY_ENV_VAR_TWO
,结果列表将为 [1, 4, 6]
。
您甚至可以在列表中定义对象,如下所示:
my.nested.0.myField = 1
my.nested.0.otherField = "hello"
my.nested.1.myField = 2
my.nested.1.myField = ${?MY_INT}
my.nested.1.otherField = "goodbye"
my.nested.1.myField = ${?MY_STRING}
my.nested.2.myField = ${OTHER_INT} // Note lack of ?
my.nested.2.otherField = ${OTHER_STRING} // Note lack of ?
配置对象列表的一个问题,至少在我的测试中,是所有项目都需要完全定义。这就是为什么
没有默认值的字段是必需的替换。如果 MY_INT=99
,MY_STRING
未设置,OTHER_INT=100
,
和 OTHER_STRING=foo
,以上呈现为:
other {
nested = [
{ myField = 1, otherField = "hello" },
{ myField = 99, otherField = "goodbye" },
{ myField = 100, otherField = "foo" }
]
}
答案 1 :(得分:0)
不,那不可能。
从Hocon docs:
环境变量始终变为字符串值,尽管如果应用程序请求其他类型,则会自动进行类型转换
同一文档中与自动类型转换有关的注释:
不应执行以下类型转换:
...
任何要数组化的东西,数字索引对象除外
将对象和数组与字符串进行来回转换是很诱人的,但是在实际情况下会引起棘手的引号和双转义问题。