Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot: read list from yaml using @Value or @ConfigurationProperties

Tags:

I want to read a list of hosts from a yaml file (application.yml), the file looks like this:

cors:     hosts:         allow:              - http://foo1/             - http://foo2/             - http://foo3/ 

(Example 1)

My class used defines the value like this:

@Value("${cors.hosts.allow}")    List<String> allowedHosts; 

But reading fails as Spring complains about this:

java.lang.IllegalArgumentException: Could not resolve placeholder 'cors.hosts.allow' in string value "${cors.hosts.allow}"

When I change the file like this the property can be read but naturally it does not contain the list but only one entry:

cors:     hosts:         allow: http://foo1, http://foo2, http://foo3 

(I know that I could read the values as a single line and split them by "," but I do not want to go for a workaround yet)

This does not work either (although I think this should be valid according to snakeyamls docs):

cors:     hosts:         allow: !!seq [ "http://foo1", "http://foo2" ]  

(Skipping the !!seq and just using the [ / ] is a failure too)

I read the suggestion here which involves using @ConfigurationProperties and transferred the example to Java and used it with the yaml file you see in Example1:

@Configuration @EnableWebMvc @ConfigurationProperties(prefix = "cors.hosts") public class CorsConfiguration extends WebMvcConfigurerAdapter {     @NotNull     public List<String> allow; ... 

When I run this I get this complaint:

org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 1 errors Field error in object 'cors.hosts' on field 'allow': rejected value [null]; codes [NotNull.cors.hosts.allow,NotNull.allow,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [cors.hosts.allow,allow]; argumen ts []; default message [allow]];

I searched for other means to have my CORS hosts configurable and found this Spring Boot issue but as this is not yet finished I can't use it as a solution. All of this is done with Spring Boot 1.3 RC1

like image 655
Marged Avatar asked Oct 27 '15 13:10

Marged


People also ask

How do I read properties from YAML file in Spring boot?

Since you'r using application. yml file, you don't need to manually load the file to the context as it's the default config file for spring application. You can simply use them in a @Component decorated class like below; @Value("${app.

Does @PropertySource support YAML?

However, by default, @PropertySource doesn't load YAML files. This fact is explicitly mentioned in the official documentation. So, if we want to use the @PropertySource annotation in our application, we need to stick with the standard properties files.

How do I read a YAML file in Spring?

This post will discuss how to read values defined in the application. yml file in a Spring Boot application. In a Spring Boot application, we can use properties files, YAML files, environment variables, and command-line arguments to externalize our configuration.

How do you inject a map from a YAML file in Spring boot?

How to Inject a Map From a YAML File. Spring Boot has taken data externalization to the next level by providing a handy annotation called @ConfigurationProperties. This annotation is introduced to easily inject external properties from configuration files directly into Java objects.


1 Answers

It's easy, the answer is in this doc and also in this one

So, you have a yaml like this:

cors:     hosts:         allow:              - http://foo1/             - http://foo2/             - http://foo3/ 

Then you first bind the data

import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component;  import java.util.List;  @Component @ConfigurationProperties(prefix="cors.hosts") public class AllowedHosts {     private List<String> HostNames; //You can also bind more type-safe objects } 

Then in another component you just do

@Autowired private AllowedHosts allowedHosts; 

And you are done!

like image 145
JeanValjean Avatar answered Sep 20 '22 15:09

JeanValjean