来自环境

时间:2019-03-07 19:50:40

标签: typesafe-config hocon

我正在使用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格式进行列表环境替换的正确方法是什么? 提前致谢。

2 个答案:

答案 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=4MY_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=99MY_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

环境变量始终变为字符串值,尽管如果应用程序请求其他类型,则会自动进行类型转换

同一文档中与自动类型转换有关的注释:

不应执行以下类型转换:

...

任何要数组化的东西,数字索引对象除外

将对象和数组与字符串进行来回转换是很诱人的,但是在实际情况下会引起棘手的引号和双转义问题。