我使用HOCON配置格式,解析库来自typesafe.Config。HOCON支持env的注射和覆盖。像这样:
my.config = "asd"
my.config = ${?MY_ENV_VAR} 如果有一个名为MY_ENV_VAR的env var,这将替换默认值"asd“。然而,我似乎找不到任何好的方法来做列表env替换。像这样:
my.config = [1,2,3,4]
my.config = ${?MY_ENV_LIST}因为默认情况下,外部的env将默认为string,因此从库的角度来看,[1,2,3,4]将被视为"1,2,3,4“,因此不能将其视为列表,并将产生如下运行时错误:
com.typesafe.config.ConfigException$WrongType: application.conf: 5: application.boolliststring具有类型字符串而不是列表 在com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:133) at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:145) at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:151) at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:159) at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:164) at com.typesafe.config.impl.SimpleConfig.getList(SimpleConfig.java:212)
有人知道用HOCON格式做列表env替换的正确方法是什么吗?提前谢谢。
发布于 2020-12-22 22:53:37
答案
从一个环境变量转到一个数组是不可能的,因为另一个回答是这样的。
您可以重新解析从config加载的字符串:
// 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} ]未定义的任何值都将被省略。
添加默认值
如果只需要向默认值添加,则可以使用+= 语法。
my.config = [1, 2]
my.config += ${?MY_ENV_VAR}
my.config += ${?MY_ENV_VAR_TWO}未定义的任何值都不会添加到数组中。
最大灵活性
我发现最灵活的选项是在您的位置语法中使用application.conf (或者reference.conf或-D选项,或者您提供配置的任何其他地方):
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.otherField = ${?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" }
]
}发布于 2020-05-06 10:11:32
不那是不可能的。
来自霍肯文档
环境变量总是成为一个字符串值,尽管如果应用程序要求另一种类型,自动类型转换就会启动。
同一文档中与自动类型转换相关的注释:
不应执行下列类型转换: ..。 任何要数组的东西,除数字索引对象到数组之外 将对象和数组转换到字符串和从字符串中转换是很诱人的,但在实际情况下,引用和双重转义会引起棘手的问题。
https://stackoverflow.com/questions/55051789
复制相似问题