Spring Boot Yaml配置以获取字符串列表


149

我正在尝试从application.yml文件加载字符串数组。这是配置:

ignore:
    filenames:
        - .DS_Store
        - .hg

这是课程:

@Value("${ignore.filenames}")
private List<String> igonoredFileNames = new ArrayList<>();

同一类中还有其他配置也可以加载。我的yaml文件中没有标签。我仍然得到以下异常:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'ignore.filenames' in string value "${ignore.filenames}"

Answers:


71

我的猜测是,@Value不能应对“复杂”类型。您可以使用以下prop类:

@Component
@ConfigurationProperties('ignore')
class IgnoreSettings {
    List<String> filenames
}

请注意:此代码是Groovy的 - 不是Java -保持示例短!有关如何采用的提示,请参见注释。

查看完整的示例https://github.com/christoph-frick/so-springboot-yaml-string-list


1
您可以绑定以逗号分隔@Value(只要注册了转换器,我认为它将在Spring Boot中)。
Dave Syer 2014年

2
它捡字符串设置而不是列表<字符串>设置
Bahadır鸭肝

1
我无法使用它@Configuration,但是使用@Component了技巧。
Stijn Van Bael

1
@cfrick是的,这是我所做的唯一更改。纵观这两个注释的目的,我会说@Component是比较合适的:stackoverflow.com/questions/12229282/...
斯泰恩范巴尔

2
这似乎是对注解的spring boot过程的限制-github.com/spring-projects/spring-boot/issues/501
wontondon 16/09/19

133

在application.yml中使用逗号分隔的值

ignoreFilenames: .DS_Store, .hg

用于访问的Java代码

@Value("${ignoreFilenames}")    
String[] ignoreFilenames

这是工作 ;)


我希望这也可以在Dropwizard中使用:'(不过,谢谢!
RST

1
那应该是最好的答案。
Mohamed Elsayed

3
在我自己的测试中,这等效于“ .DS_Store,.hg”,但不等同于“ .DS_Store”,“。hg”-后者因“ org.yaml.snakeyaml.parser.ParserException:解析块映射时失败”而失败。因此,您在这里实际要做的是将属性提供为单个逗号分隔的字符串(Spring然后将其拆分为数组或列表),而不是YAML数组。这“有效”,但没有回答原始问题。我还没有找到一种方法来解析带@Value注释的bean属性中的YAML数组。
Zirzirikos

38

从spring boot docs https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

YAML列表用[index]解引用器表示为属性键,例如,以下YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

将被转换为以下属性:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

要绑定到使用Spring DataBinder实用程序的属性(@ConfigurationProperties确实如此),您需要在类型的目标bean中具有一个属性,java.util.List并且您需要提供setter或使用可变值对其进行初始化,例如,这将绑定到上面的属性。这是问题代码的样子。

@ConfigurationProperties(prefix="ignore")
public class Filenames {

    private List<String> ignoredFilenames = new ArrayList<String>();

    public List<String> getFilenames() {
        return this.ignoredFilenames;
    }
}

2
这应该可以工作,BTW getXxx()是工作所必需的,并且必须使用List,而不是Set
Eric Wang

在yaml中,ArrayList的值列表可以是逗号分隔的列表。就我而言,我有很多值,因此一个紧凑的列表比每行一个项目更干净。因此,在此示例中,您可以做服务器:dev.bar.com,foo.bar.com
Violaman

25

除了Ahmet的答案外,您还可以使用>Symbol 将换行符添加到逗号分隔的字符串中。

application.yml

ignoreFilenames: >
  .DS_Store, 
  .hg

Java代码

@Value("${ignoreFilenames}")    
String[] ignoreFilenames;

只要您的字符串中没有逗号(,),此方法就很好用。
Valentin Despa

这无法将属性读取为arraylist。它将它们读取为单个String。
Sree Lakshmi

6

Ahmet的答案提供了如何将逗号分隔的值分配给String数组。

要在不同的类中使用上述配置,您可能需要为此创建getters / setters。但是,如果您希望一次加载此配置并继续将其用作具有Autowired注释的bean,那么我将完成以下操作:

在ConfigProvider.java中

@Bean (name = "ignoreFileNames")
@ConfigurationProperties ( prefix = "ignore.filenames" )
public List<String> ignoreFileNames(){
    return new ArrayList<String>();
}

在外面的课上:

@Autowired
@Qualifier("ignoreFileNames")
private List<String> ignoreFileNames;

您可以通过自动装配在其他任何地方使用相同的列表。


这样可行。就我而言,尽管应用程序失败了,除非我@Configuration在类的开头添加ConfigProvider.java。否则,我得到Source需要找不到类型为'java.util.List'的bean。
戴安娜


2

好吧,我唯一能使它起作用的是这样的:

servers: >
    dev.example.com,
    another.example.com

@Value("${servers}")
private String[] array;

并且不要忘记类上方的@Configuration...。

没有“,”分离,就没有运气了。

也可以工作(引导1.5.8 versie)

servers: 
       dev.example.com,
       another.example.com

-1

就我而言,这是.yml文件中的语法问题。我有:

@Value("${spring.kafka.bootstrap-servers}")
public List<String> BOOTSTRAP_SERVERS_LIST;

以及我的.yml文件中的列表:

bootstrap-servers:
  - s1.company.com:9092
  - s2.company.com:9092
  - s3.company.com:9092

没有读到@Value注释字段。当我将.yml文件中的语法更改为:

bootstrap-servers >
  s1.company.com:9092
  s2.company.com:9092
  s3.company.com:9092

工作正常。


在spring-boot 1.5上尝试此操作不起作用。您需要在引导服务器之后冒号
Taugenichts

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.