Spring Boot REST – Internationalization

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 auto-configuration

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

1.1. Auto-configuration condition

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. Default resource bundle is present

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

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

The auto-configuration create default ResourceBundleMessageSource instance and customize it with other property values in name space spring.messages.*.

1.2. Default resource bundle is NOT present

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 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 user requests a message (code) that does not exist for the requested locale – either because there is no message properties file for the language at all, 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 message is not found in properties file.

4. Spring boot rest 1i8n demo

We have created two properties file with 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 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 it’s 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 ‘Accept-Language’ header to receive locale specific messages fro REST APIs.

Drop me your questions in comments.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

1 thought on “Spring Boot REST – Internationalization”

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.