YAML to Map with Spring Boot

A guide to read Application Properties file or a YAML file as a Java Map in Spring Boot.

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.