UTF-8
Spring Boot
application.properties
encoding
Java

UTF-8 encoding of application.properties attributes in Spring-Boot

Master System Design with Codemia

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

Introduction

Encoding problems in application.properties usually show up only after you add accented characters, non-Latin text, or symbols that move between editors, build tools, and runtime. In Spring Boot, the safest approach is to treat UTF-8 as an end-to-end contract: save the file as UTF-8, load it consistently, and verify that the bound values still contain the expected characters. Most real failures come from one stage in that chain silently using a different encoding.

What Actually Breaks

There are three common failure modes:

  1. The file is saved in the wrong encoding by the editor.
  2. The build process rewrites the file with another encoding.
  3. The application loads the value correctly, but later output uses a different charset.

That means an apparently simple property such as a greeting or city name can be corrupted even when Spring Boot itself is not the real problem.

Keep the Property File in UTF-8

Start with the file itself. Save application.properties as UTF-8 and keep special characters directly in the source.

properties
app.title=Gestion financière
app.city=Montréal
app.welcome=こんにちは

If you open the file in an editor that assumes another encoding, those values can already be damaged before the application starts. Keep the editor project encoding explicit and consistent across the team.

Bind and Verify the Values

A simple @ConfigurationProperties class is a good way to prove the values survive loading.

java
1package com.example.demo;
2
3import org.springframework.boot.context.properties.ConfigurationProperties;
4
5@ConfigurationProperties(prefix = "app")
6public class AppProperties {
7    private String title;
8    private String city;
9    private String welcome;
10
11    public String getTitle() {
12        return title;
13    }
14
15    public void setTitle(String title) {
16        this.title = title;
17    }
18
19    public String getCity() {
20        return city;
21    }
22
23    public void setCity(String city) {
24        this.city = city;
25    }
26
27    public String getWelcome() {
28        return welcome;
29    }
30
31    public void setWelcome(String welcome) {
32        this.welcome = welcome;
33    }
34}

Then print the values at startup:

java
1package com.example.demo;
2
3import org.springframework.boot.CommandLineRunner;
4import org.springframework.stereotype.Component;
5
6@Component
7public class StartupCheck implements CommandLineRunner {
8    private final AppProperties props;
9
10    public StartupCheck(AppProperties props) {
11        this.props = props;
12    }
13
14    @Override
15    public void run(String... args) {
16        System.out.println(props.getTitle());
17        System.out.println(props.getCity());
18        System.out.println(props.getWelcome());
19    }
20}

If the output is already wrong here, the corruption happened before business code touched the data.

Watch the Build Tooling

Maven and Gradle can transform resources. If resource filtering is enabled, lock encoding explicitly so the build does not rewrite files incorrectly.

Maven example:

xml
1<project>
2  <properties>
3    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4  </properties>
5
6  <build>
7    <resources>
8      <resource>
9        <directory>src/main/resources</directory>
10        <filtering>false</filtering>
11      </resource>
12    </resources>
13  </build>
14</project>

Filtering is not inherently wrong, but it increases the chance that placeholders and encoding settings interact badly.

@PropertySource Is a Separate Case

If you load extra property files manually with @PropertySource, be explicit about encoding. That path is more likely to cause confusion than standard Boot config loading.

java
@PropertySource(value = "classpath:custom.properties", encoding = "UTF-8")

This is especially important in older codebases where custom property loading predates current Boot conventions.

Test the Contract

A small integration test prevents future regressions when the build changes.

java
1package com.example.demo;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4
5import org.junit.jupiter.api.Test;
6import org.springframework.beans.factory.annotation.Autowired;
7import org.springframework.boot.test.context.SpringBootTest;
8
9@SpringBootTest
10class EncodingTest {
11    @Autowired
12    private AppProperties props;
13
14    @Test
15    void shouldReadUtf8Properties() {
16        assertEquals("Gestion financière", props.getTitle());
17        assertEquals("Montréal", props.getCity());
18        assertEquals("こんにちは", props.getWelcome());
19    }
20}

This catches editor, build, and loading drift early.

Common Pitfalls

  • Saving application.properties in a non-UTF-8 editor encoding.
  • Enabling resource filtering without locking build encoding explicitly.
  • Blaming Spring Boot when the corruption actually happens in output or logging.
  • Forgetting to specify encoding on custom @PropertySource files.
  • Skipping automated tests for non-ASCII configuration values.

Summary

  • Treat UTF-8 as an end-to-end contract from source file to runtime output.
  • Keep application.properties saved in UTF-8 with real sample characters.
  • Verify values through @ConfigurationProperties binding, not assumptions.
  • Configure build tooling so resources are not rewritten with the wrong charset.
  • Add a focused integration test to stop encoding regressions from reappearing.

Course illustration
Course illustration

All Rights Reserved.