To add internationalization (i18n) to a Spring Boot app, keep user-facing text in message bundles under src/main/resources, inject Spring’s MessageSource wherever text is needed, and select a Locale deliberately for each request. For Boot’s message auto-configuration to activate, include a default messages.properties bundle—even when every supported language has its own translated file.
1. Set up message bundles Spring Boot can find
Use stable, semantic message keys rather than placing English sentences directly in Java code. For example, checkout.title identifies a message by purpose, so the key can remain the same while its translated value changes.
src/main/resources/
messages.properties
messages_fr.properties
messages_de.properties
messages_en_GB.properties
Place messages.properties at the classpath root. Spring Boot uses that default bundle as the trigger for message-source auto-configuration; a set containing only language-specific files such as messages_fr.properties does not trigger it. The default file can contain the application’s default-language text, but it must exist even if all target locales have dedicated files.
For example, the default bundle and a French translation might contain:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors# messages.properties
checkout.title=Review your order
checkout.items=You have {0} items
validation.email.invalid=Enter a valid email address
# messages_fr.properties
checkout.title=Vérifiez votre commande
checkout.items=Vous avez {0} articles
validation.email.invalid=Saisissez une adresse e-mail valide
Configure one or more bundle basenames in src/main/resources/application.properties:
spring.messages.basename=messages,config.i18n.messages
spring.messages.fallback-to-system-locale=false
spring.messages.basename accepts comma-separated classpath basenames; for example, the entries above point to bundles rooted at messages and config/i18n/messages. Keep the default bundle for each configured basename needed by Boot’s message-source auto-configuration. Setting spring.messages.fallback-to-system-locale=false avoids making fallback depend on the operating system’s locale, which can differ between developer machines and deployed hosts. Spring Boot also provides spring.messages.common-messages for configuring common message resources.
Rank #2
2. Retrieve messages with an explicit locale
Spring’s ApplicationContext implements MessageSource, so services, controllers, and validation-error mappers can receive it through dependency injection. Pass the locale you intend to use rather than relying on an implicit default.
import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
@Service
public class CheckoutMessages {
private final MessageSource messages;
public CheckoutMessages(MessageSource messages) {
this.messages = messages;
}
public String title(Locale locale) {
return messages.getMessage(
"checkout.title",
null,
"Review your order",
locale
);
}
public String itemCount(int count, Locale locale) {
return messages.getMessage(
"checkout.items",
new Object[] { count },
"You have {0} items",
locale
);
}
}
The default-message overload returns the supplied fallback text if a code cannot be resolved. If an absent key should instead be treated as an error, use the getMessage overload without a default message; it throws NoSuchMessageException when no message is found. This choice should reflect the use case: a safe fallback can keep a response usable, while an exception can expose incomplete bundles during development or in required-message paths.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Message arguments use MessageFormat-compatible placeholders such as {0}. Keep placeholder order and meaning consistent across translations, and test values that need locale-sensitive formatting. Spring’s message lookup follows the JDK ResourceBundle naming and fallback rules, so regional bundles such as messages_en_GB.properties can coexist with broader language bundles.
3. Decide how each request gets its locale
In Spring MVC, DispatcherServlet obtains the request locale through a LocaleResolver. Choose the source of that locale based on your product’s behavior: a browser’s Accept-Language header, an authenticated user profile, a cookie or session preference, or a controlled request parameter. A request parameter does not switch locales by itself; configure a locale-change interceptor when users need that mechanism.
Rank #4
| Locale source | Persistence | Useful when | Trade-off to consider |
|---|---|---|---|
Browser Accept-Language |
Usually request-derived | The app should initially follow the language preferences sent by the client. | A browser preference is not necessarily the user’s desired language inside the app. |
| Authenticated user profile | Persisted with the user account | A signed-in user expects the same choice across devices or sessions. | The application must obtain and apply the profile preference for the request. |
| Cookie or session | Persisted in browser/session state | A user should be able to retain a choice without tying it to an account profile. | Define how the preference is retained and what happens when that state is unavailable. |
| Explicit request parameter | Request-only unless separately persisted | A link or user action needs to request a locale change. | Use a configured locale-change interceptor; do not assume the parameter alone changes MVC’s locale. |
Once the resolver policy is in place, pass the resolved request locale into message lookups. Avoid storing a mutable “current locale” in shared application state: locale selection belongs to the request or user preference, and concurrent requests should not affect one another.
4. Choose bundle lookup and fallback behavior
For each lookup, Spring uses the requested locale and JDK resource-bundle resolution, which can consider language and regional variants. For example, an en_GB request may use the regional bundle when present and fall back through less-specific bundle choices when it is absent. Keep a deliberate application default in messages.properties; disabling system-locale fallback makes the result less dependent on the host environment.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
There are two separate fallback decisions to make:
- Bundle fallback: which available locale bundle is used when the requested regional or language-specific bundle is missing.
- Missing-code behavior: whether an unresolved key returns a supplied default message or raises
NoSuchMessageException.
Do not treat fallback as a substitute for complete translations. A fallback may keep a screen functional, but it can produce mixed-language output; include missing-key checks in the release process for every supported locale.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.5. Choose classpath bundles or reloadable resources
ResourceBundleMessageSource caches loaded bundles and MessageFormat instances. Classpath bundles are a straightforward choice when translations ship with the application. If translations must be external or refreshed without the same bundle-loading approach, evaluate Spring’s reloadable message-source implementation and its resource-location and cache settings against the way the application is deployed.
| Approach | What to account for |
|---|---|
Classpath bundles with ResourceBundleMessageSource |
Bundles are packaged with the app; loaded bundles and message formats are cached. |
| Reloadable message source | Evaluate supported resource locations and cache settings alongside production deployment and update requirements. |
Property-file encoding deserves attention when running on the JDK module path. The current ResourceBundleMessageSource API documentation describes UTF-8 with ISO-8859-1 fallback and the java.util.PropertyResourceBundle.encoding override. Confirm the behavior against the JDK and Spring version used in the deployed application, especially if translated characters appear corrupted.
6. Test localization behavior before release
Exercise message lookup and locale selection as separate concerns. A focused test set should cover:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute- Every supported locale, plus the application’s default locale.
- A regional locale such as
en_GB, including behavior when its regional file is absent. - A missing message code, verifying the chosen default-message or exception behavior.
- Argument substitution in translated messages, including locale-sensitive values where relevant.
- Request-scoped locale selection under concurrent requests, to catch accidental state leakage.
- Bundle loading in the actual deployment mode, including module-path encoding behavior if applicable.
Spring documentation is version-sensitive. Check the reference documentation for the Spring Boot and Spring Framework versions your app actually uses; the Spring MVC locale-resolver reference available for this topic is the 7.1 development line, not a guarantee that every detail applies unchanged to another version.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

