i want to map values between a yaml file with a Map<String, List<String>>
in springboot
country.yml
file:
entries:
map:
MY:
- en
- zh
SampleConfig
file:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("entries")
public class SampleConfig {
private Map<String, List<String>> map = new HashMap<>();
@Bean
public void bean1(){
System.err.println("map has size: "+map.size());
}
}
But the map.size()
is always 0, not sure what i do wrong.
There are two problems
1) By default spring will look for application.yml
or application.properties
in default locations
To solve the above problem you can use application.yml
instead of country.yml
2) You can use @PropertySource
to load any external properties file but yml
is not supported with this annotation
24.7.4 YAML Shortcomings you cannot use @PropertySource
with yml
file
YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.
How to read yml file using Spring @PropertySource
this will work and print out CountryData : {MY=[en, zh]}
but surely read the answer from Deadpool.
the hack is here to override the default configuration name 'application' by 'country'
in the example, I have done it by setting it via a System property, but starting your application via
java -jar mycountryapp.jar --spring.config.name=country
should work perfectly
@SpringBootApplication
public class Application {
static {
System.setProperty("spring.config.name", "country");
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Service
class CountryService {
private final CountryData countryData;
public CountryService(CountryData countryData) {
this.countryData = countryData;
}
@EventListener(ApplicationReadyEvent.class)
public void showCountryDataOnStartup() {
System.err.println("CountryData : " + countryData.getMap());
}
}
@Configuration
@ConfigurationProperties(prefix = "entries")
class CountryData {
Map<String, List<String>> map;
public Map<String, List<String>> getMap() {
return map;
}
public void setMap(Map<String, List<String>> map) {
this.map = map;
}
}
Assuming your application is picking the configuration from country.yml
(I would check that as well) - You need getters and setters to get it to work. just add:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties("entries")
public class SampleConfig {
private Map<String, List<String>> map = new HashMap<>();
public Map<String, List<String>> getMap(){
return map;
}
public void setMap(Map<String, List<String>> map){
this.map=map;
}
}