Internationalization with Spring Boot REST

Learn to add internationalization (i18n) support to spring boot REST APIs through the auto-configuration of MessageSource bean and locale-specific messages.properties file.

1. Internationalization AutoConfiguration

Spring boot i18n autoconfiguration scans for resource bundles and configures an instance of org.springframework.context.MessageSource.

1.1. Default Autoconfiguration

To auto-configure and enable internationalization, MessageSourceAutoConfiguration looks for:

  • No bean present with name “messageSource“.
  • Presence of resource bundle with name messages.properties or name configured using spring.messages.basename property.

1.2. Custom Resource Bundle

We can customize the name of the resource bundle using property spring.messages.basename in application.properties file.

spring.messages.basename=messages,config.i18n.messages

The auto-configuration creates default ResourceBundleMessageSource instance and customize it with other property values in namespace spring.messages.*.

If your resource bundle contains only language-specific properties files, you are required to add the default. Otherwise NoSuchMessageException is thrown by the application at runtime similar to below:

{
"timestamp": "2019-09-28T17:03:36.056+0000",
"status": 500,
"error": "Internal Server Error",
"message": "No message found under code 'error.notfound' for locale 'en_US'.",
"path": "/"
}

If no properties file is found that matches any of the configured base names, there will be no auto-configured MessageSource.

2. Locale Resolution

By default, Spring boot uses Accept-Language header to determine the user locale.

Accept-Language: es_ES

3. MessageSource Properties

We can further customize the behavior during message resolution for any locale in the request header.

# Whether to always apply the MessageFormat rules, parsing even messages without arguments.
spring.messages.always-use-message-format=false

# Comma-separated list of basenames
spring.messages.basename=messages

# Loaded resource bundle files cache duration.
# When not set, bundles are cached forever.
# If a duration suffix is not specified, seconds will be used.
spring.messages.cache-duration=

# Message bundles encoding.
spring.messages.encoding=UTF-8

# Whether to fall back to the system Locale
# if no files for a specific Locale have been found.
spring.messages.fallback-to-system-locale=true

# Whether to use the message code as the default message instead of throwing a "NoSuchMessageException".
# Recommended during development only.
spring.messages.use-code-as-default-message=false
  • fallback-to-system-locale – control what to do when the user requests a message (code) that does not exist for the requested locale – either because there is no message properties file for the language or just because the message file does not contain the message code.
  • use-code-as-default-message – setting to ‘true’ will default the message code if the message is not found in the properties file.

4. Spring Boot i18n Demo

We have created two properties files with a single message.

error.notfound=Resource not available

//Spanish locale

error.notfound=Recurso no disponible

Then we created a simple @RestController which returns the locale-specific message. See without any configuration, Spring boot auto-configure MessageSource bean.

import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

@Autowired
MessageSource messageSource;

@GetMapping("/")
public String index(Locale locale) {
    return messageSource.getMessage("error.notfound", null, locale);
}
}

Start the application and get the resource with and without “Accept-Language” header.

4.1. Without ‘Accept-Language’ Header

It will resolve to the default locale i.e. messages.properties file.

Without accept language header
Without accept language header

4.2. With ‘Accept-Language’ Header

It will resolve to requests locale i.e. spanish.

With accept language header
With accept language header

5. Conclusion

Spring boot provides excellent support for message localization using its auto-configuration feature. All we have to do is provide locale-specific resource bundle properties and MessageSource is automatically configured for us.

We can start sending the ‘Accept-Language’ header to receive locale-specific messages fro REST APIs.

Happy Learning !!

Sourcecode Download

1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Comments are closed for this article!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.