Bahadır Yağan
Bahadır Yağan

Reputation: 5967

Spring Boot YAML configuration for a list of strings

I am trying to load an array of strings from the application.yml file. This is the config:

ignore:
    filenames:
        - .DS_Store
        - .hg

This is the class fragment:

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

There are other configurations in the same class that loads just fine. There are no tabs in my YAML file. Still, I get the following exception:

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

Upvotes: 267

Views: 381385

Answers (13)

user3808122
user3808122

Reputation: 823

This one works for me.

servers:
  server1,
  server2,
  server3

Upvotes: 0

Wladimir Diskowski
Wladimir Diskowski

Reputation: 640

I don't know from which version comme this feature, but I am using currently spring-boot 3.3.4 and it works yet simple with List and comma separated value:

ignore.filenames: name1, name2

    @Value("${ignore.filenames}")
    private List<String> sampleListValues;

Upvotes: 0

Supreet Singh
Supreet Singh

Reputation: 1010

@Value("${coupon.update.fieldsToIgnore}") private List fieldsToIgnore;

coupon:
  update:
    fieldsToIgnore: dbVersion, createdAt, updatedAt

simply use this

Upvotes: 0

dskow
dskow

Reputation: 944

From the Spring Boot docs:

YAML lists are represented as property keys with [index] dereferencers, for example this YAML:

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

Would be transformed into these properties:

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

To bind to properties like that using the Spring DataBinder utilities (which is what @ConfigurationProperties does) you need to have a property in the target bean of type java.util.List and you either need to provide a setter, or initialize it with a mutable value, e.g. this will bind to the properties above. Here is what the question's code would look like.

(Note: The example below only works on Spring Boot 3.0 and greater. Previous versions require the @ConstructorBinding annotation to be present to not throw exceptions when this object is being constructed.)

@ConfigurationProperties(prefix="ignore")
//@ConstructorBinding // uncomment if using Spring Boot 2.x.
public class Filenames {

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

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

Upvotes: 72

Matt Campbell
Matt Campbell

Reputation: 2227

In my case, this was a syntax issue in the .yml file. I had:

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

and the list in my .yml file:

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

was not reading into the @Value-annotated field. When I changed the syntax in the .yml file to:

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

it worked fine.

Upvotes: 50

Paramesh Korrakuti
Paramesh Korrakuti

Reputation: 2067

Configuration in yaml file:

ignore:
    filenames: >
        .DS_Store
        .hg

In spring component:

@Value("#{'${gnore.filenames}'.split(' ')}")
private List<String> igonoredFileNames;

This worked fine for me.

Upvotes: 3

Vivek Swansi
Vivek Swansi

Reputation: 419

@Value("#{'${your.elements}'.split(',')}")  
private Set<String> stringSet;

yml file:

your:
 elements: element1, element2, element3

There is lot more you can play with spring spEL.

Upvotes: 15

Roland Roos
Roland Roos

Reputation: 1083

Well, the only thing I can make it work is like so:

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

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

And dont forget the @Configuration above your class....

Without the "," separation, no such luck...

Works too (boot 1.5.8 versie)

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

Upvotes: 19

Ahmet Vehbi Olga&#231;
Ahmet Vehbi Olga&#231;

Reputation: 2935

use comma separated values in application.yml

ignoreFilenames: .DS_Store, .hg

java code for access

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

It is working ;)

Upvotes: 226

Sasha Shpota
Sasha Shpota

Reputation: 10280

In addition to Ahmet's answer you can add line breaks to the coma separated string using > symbol.

application.yml:

ignoreFilenames: >
  .DS_Store, 
  .hg

Java code:

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

Upvotes: 57

Deepak
Deepak

Reputation: 1042

Ahmet's answer provides on how to assign the comma separated values to String array.

To use the above configuration in different classes you might need to create getters/setters for this.. But if you would like to load this configuration once and keep using this as a bean with Autowired annotation, here is the how I accomplished:

In ConfigProvider.java

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

In outside classes:

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

you can use the same list everywhere else by autowiring.

Upvotes: 11

cfrick
cfrick

Reputation: 37008

My guess is, that the @Value can not cope with "complex" types. You can go with a prop class like this:

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

Please note: This code is Groovy - not Java - to keep the example short! See the comments for tips how to adopt.

See the complete example https://github.com/christoph-frick/so-springboot-yaml-string-list

Upvotes: 122

sashanet buryk
sashanet buryk

Reputation: 17

@Value("${your.elements}")    
private String[] elements;

yml file:

your:
 elements: element1, element2, element3

Upvotes: -3

Related Questions