springboot
application.yml
special characters
configuration
properties

How to read properties with special characters from application.yml in springboot

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Spring Boot reads YAML configuration well, but special characters in keys need extra care. The tricky part is not reading the file itself; it is preserving keys exactly when Spring binds them into maps or configuration classes.

Quote YAML Keys and Values Correctly

YAML treats characters such as :, [, ], #, and spaces as meaningful syntax. If those characters are part of the key or value, quote them.

yaml
1app:
2  headers:
3    "[X-App-Token]": "secret-token"
4    "[/internal/path]": "enabled"
5  messages:
6    welcome: "Hello: world"

Quoting is a YAML concern. Without quotes, the parser may split or reinterpret the content before Spring sees it.

Preserve Special Keys with @ConfigurationProperties

Spring Boot's map binding is the main place where people get surprised. For map keys containing characters outside the normal relaxed-binding set, use bracket notation so Spring preserves the original key.

java
1import org.springframework.boot.context.properties.ConfigurationProperties;
2
3import java.util.HashMap;
4import java.util.Map;
5
6@ConfigurationProperties(prefix = "app")
7public class AppProperties {
8
9    private Map<String, String> headers = new HashMap<>();
10
11    public Map<String, String> getHeaders() {
12        return headers;
13    }
14
15    public void setHeaders(Map<String, String> headers) {
16        this.headers = headers;
17    }
18}

With the YAML shown earlier, headers.get("X-App-Token") and headers.get("/internal/path") work as expected because the bracketed keys were preserved during binding.

A minimal boot application can print the values:

java
1import org.springframework.boot.CommandLineRunner;
2import org.springframework.boot.SpringApplication;
3import org.springframework.boot.autoconfigure.SpringBootApplication;
4import org.springframework.boot.context.properties.EnableConfigurationProperties;
5
6@SpringBootApplication
7@EnableConfigurationProperties(AppProperties.class)
8public class DemoApplication implements CommandLineRunner {
9
10    private final AppProperties appProperties;
11
12    public DemoApplication(AppProperties appProperties) {
13        this.appProperties = appProperties;
14    }
15
16    @Override
17    public void run(String... args) {
18        System.out.println(appProperties.getHeaders().get("X-App-Token"));
19    }
20
21    public static void main(String[] args) {
22        SpringApplication.run(DemoApplication.class, args);
23    }
24}

When to Use Environment

If you only need one property and do not want a full configuration class, inject Environment.

java
import org.springframework.core.env.Environment;

String value = environment.getProperty("app.messages.welcome");

This works well for ordinary property paths. For collections or special map keys, @ConfigurationProperties is usually clearer and less fragile.

Reading Structured Maps Instead of Flattened Strings

Suppose you need to configure dynamic HTTP headers whose names come from another system. A map-based configuration model is much easier to maintain than several separate @Value fields.

yaml
1app:
2  headers:
3    "[X-Tenant-Id]": "acme"
4    "[X-Trace-Id]": "demo-trace"

Then iterate over the bound map at runtime:

java
for (Map.Entry<String, String> entry : appProperties.getHeaders().entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}

That keeps the special-character handling in one place and avoids scattering literal property names across the codebase.

Choosing the Right Shape

If the keys are fixed and known in advance, prefer normal field names:

yaml
app:
  endpoint-url: "https://example.test/api"

If the keys are truly dynamic, such as HTTP header names or external identifiers, bind them to a Map<String, String> and preserve special characters with bracket notation.

Common Pitfalls

The first pitfall is forgetting to quote YAML keys that contain brackets or colons. The parser may reject the file or interpret it differently.

The second is expecting Spring to preserve every unusual map key automatically. For map binding, bracket notation is what keeps characters such as / from being stripped.

The third is using @Value for large groups of dynamic properties. It becomes difficult to maintain and easy to misread.

Summary

  • Quote YAML keys and values when special characters are part of the literal text.
  • Use bracket notation for map keys that must be preserved exactly.
  • '@ConfigurationProperties is the cleanest way to bind dynamic key-value configuration.'
  • 'Environment is fine for one-off reads of simple property paths.'
  • Prefer normal named fields when the configuration shape is fixed.

Course illustration
Course illustration

All Rights Reserved.