A guide to read Application Properties file or a YAML file as a Java Map in Spring Boot.
Tutorial Contents
Overview
In a Spring or Spring Boot application, an application properties file or an application YAML file help us externalising important configurations. On top of that, the @ConfigurationProperties annotation in Spring Boot helps us to easily read and bind those configurations into Java objects.
This tutorial focuses on reading application configurations from a properties or a yaml file into Java HashMap objects.
In order to learn more about reading application properties or yaml files in to Java beans, please read Using @ConfigurationProperties in Spring Boot.
YAML or a Properties File
For the purpose of this tutorial we will work on a YAML based configuration. However make a note that, all the examples in this tutorial are also applicable when using any equivalent application properties file.
Let’s look at a typical application YAML file from a Spring Boot application.
application.yaml
spring:
application:
name: data-service
servlet:
multipart:
enabled: true
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3309/test
password: password
username: test_user
Code language: YAML (yaml)
Alternatively, We can rewrite the same configurations in a properties file as well.
application.properties
spring.application.name=data-service
spring.servlet.multipart.enabled=true
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3309/test
spring.datasource.password=password
spring.datasource.username=test_user
Code language: Properties (properties)
Both of the files contain exact same configurations and we won’t see any difference which type of configuration we use in our Spring Boot application. However, when we compare a properties file to an equivalent YAML file, the YAML syntax is more organized and more readable.
YAML file To Java Map
Both of the configurations – yaml and properties, are expressed in the form of key and value pairs. That makes it more similar to a Map data structure.
Thus, mapping a yaml file or properties file into a Java HashMap is really straightforward and easy. The next snippet demonstrates how we can use plain Java Map instances to model the properties or YAML based configurations, that we saw in the previous section.
Map<String, String> application = Map.of("name", "data-service");
Map<String, String> servlet = Map.of(
"multipart.enabled", "true"
);
Map<String, String> datasource = Map.of(
"driverClassName", "com.mysql.cj.jdbc.Driver",
"url", "mysql://localhost:3309/test",
"password", "password",
"username", "test_user"
);
Code language: Java (java)
Interestingly, in our configuration, the sub-group of “servlet” has a nested Map. We can model the nested map using a dot notation as seen here.
Alternatively, we change the type of the servlet map and make it a nested map (map of maps).
Map<String, Map<String, String>> servlet = Map.of(
"multipart", Map.of("enabled", "true")
);
Code language: Java (java)
We understood, how the Map and YAML or a Properties file have similar data structure. But more interesting is to know that Spring Boot @ConfigurationProperties supports all such mappings without any configurations.
Reading YAML Properties as Java Map
In order to create Map instances from YAML or properties file configurations, we need a @ConfigurationProperties class. This class is required for containing all the nested Map groups.
As we want to read all the properties under the group “spring”, our properties class uses it as a prefix.
@Configuration
@ConfigurationProperties(prefix = "spring")
public class MapProperties {
Map<String, String> application;
Map<String, String> servlet;
Map<String, String> datasource;
// Constructor, Getter and Setter methods
}
Code language: Java (java)
The class has all three maps and their names corresponds to the name of the properties sub groups. We have also added a well-formatted toString() method that we will use to print the bean, when application starts.
* Java Map based Properties application: name=data-service servlet: multipart.enabled=true datasource: driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3309/test password=password username=test_user
From the output, we can see all the fields in the map are populated as expected.
Reading YAML Properties as Nested Java Map
In order to read nested Java Maps from YAML file or a Properties File, we can change the type of the “servlet” field to Map<String, Map<String, String>>
.
@Configuration
@ConfigurationProperties(prefix = "spring")
public class NestedMapProperties {
Map<String, String> application;
Map<String, Map<String, String>> servlet;
Map<String, String> datasource;
// Constructor, Getter, and Setter methods
}
Code language: Java (java)
Now, when we print the populated bean, we see that the nested Maps are correctly read from our YAML file.
* Java Map based nested Properties application: name=data-service servlet: multipart={enabled=true} datasource: driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3309/test password=password username=test_user
Reading YAML Properties as Multi Value Map
Sometimes, we may have a list of values in a YAML or a Properties Files that we want to bind in a Java Bean. Spring Boot @ConfigurationProperties supports using a MultiValueMap to map the list into a Map<String, List<String>> object.
A list in a YAML file looks like this,
spring:
application:
name: data-service
servlet:
multipart:
enabled: true
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3309/test
password: password
username: test_user
profiles:
active:
- dev
- qa
- staging
- prod
Code language: YAML (yaml)
Or, simply use a in-line list with comma separated values
spring:
## Skipped
profiles:
active: dev, qa, staging, prod
Code language: YAML (yaml)
In order to read the spring.profiles.active, we can change our Map to a MultiValue Map.
@Configuration
@ConfigurationProperties(prefix = "spring")
public class NestedMapProperties {
Map<String, String> application;
Map<String, Map<String, String>> servlet;
Map<String, String> datasource;
Map<String, List<String>> profiles;
// Constructor, Getter, and Setter methods
}
Code language: Java (java)
Using that, we can verify list of all the active profiles is loaded correctly.
* Java Map based nested Properties application: name=data-service servlet: multipart={enabled=true} datasource: driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3309/test password=password username=test_user profiles: active=[dev, qa, staging, prod]
Summary
This tutorial focused on Reading key and value pairs from a YAML or a Properties file into a Java HashMap. We understood that a YAML or a Properties file are very similar to the Map data structure. Thus, we can easily bind the configurations in Java Maps.
We covered examples of reading a simple Map, Nested Map, and MultiValueMap from a YAML file, or an equivalent application properties file.
For the full source code of the examples used in this tutorial, you can refer to our Github Repository.