Internationalization in Spring Boot
Welcome, in this tutorial, we will see how to implement internationalization in a spring boot application where a single application can support multiple languages like English, French, German, etc.
1. Introduction
Before going further in this tutorial, we will look at the common terminology such as introduction to Spring Boot.
1.1 Spring Boot
- Spring boot is a module that provides rapid application development feature to the spring framework including auto-configuration, standalone-code, and production-ready code
- It creates applications that are packaged as jar and are directly started using embedded servlet container (such as Tomcat, Jetty or, Undertow). Thus, no need to deploy the war files
- It simplifies the maven configuration by providing the starter template and helps to resolve the dependency conflicts. It automatically identifies the required dependencies and imports them into the application
- It helps in removing the boilerplate code, extra annotations, and xml configurations
- It provides powerful batch processing and manages the rest endpoints
- It provides an efficient jpa-starter library to effectively connect the application with the relational databases
- It offers a Microservice architecture and cloud configuration that manages all the application related configuration properties in a centralized manner
Let us go ahead with the tutorial implementation but before going any further I’m assuming that you’re aware of the Spring boot basics.
2. Internationalization in Spring Boot
2.1 Tools Used for Spring boot application and Project Structure
We are using Eclipse Kepler SR2, JDK 8, and Maven. In case you’re confused about where you should create the corresponding files or folder, let us review the project structure of the spring boot application.
Let us start building the application!
3. Creating a Spring Boot application
3.1 Maven Dependency
Add the basic spring boot dependencies to the pom.xml
. Maven will automatically resolve the other dependencies.
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.springboot.internationalization</groupId> <artifactId>SpringbootInternationalization</artifactId> <version>0.0.1-SNAPSHOT</version> <name>SpringbootInternationalization</name> <description>Springboot and internationalization tutorial</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
3.2 Application XML file
Create a new XML file at the location: SpringbootInternationalization/src/main/resources/
and add the following code to it. Here we will define the spring configuration and a placeholder key for the internationalization.
application.yml
placeholder: greetings: welcome.message server: port: 9800 spring: application: name: springboot-and-internationalization
3.3 Language files
Create the language properties at the location: SpringbootInternationalization/src/main/resources/internationalization
. We will create 3 different properties file where we will specify the welcome.message
property in the native language. We will create the English translation file and similarly, you can create the properties file for the French and German language.
lang. properties
welcome.message=Greetings {0}
3.4 Java Classes
3.4.1 Implementation/Main class
Add the following code to the main class to bootstrap the application from the main method. Always remember, the entry point of the spring boot application is the class containing @SpringBootApplication
annotation and the static main method.
SpringbootInternationalizationApplication.java
package com.springboot.internationalization; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //lombok annotation @Slf4j //spring annotation @SpringBootApplication public class SpringbootInternationalizationApplication { public static void main(String[] args) { SpringApplication.run(SpringbootInternationalizationApplication.class, args); log.info("Springboot internationalization application is started successfully"); } }
3.4.2 Locale configuration class
Add the following code to the configuration class where will define the locale configuration as in this tutorial we will use the AcceptHeaderLocaleResolver
bean that helps to accept the Accept-Language
header from the request.
LocaleConfig.java
package com.springboot.internationalization.configuration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; import java.util.Locale; //spring annotation @Configuration public class LocaleConfig { //AcceptHeaderLocaleResolver helps to retrieve locale based on the Accept-Language // header in the request @Bean public AcceptHeaderLocaleResolver localeResolver() { final AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver(); resolver.setDefaultLocale(Locale.US); return resolver; } //ResourceBundleMessageSource resolve text messages from properties file based on different locales @Bean public ResourceBundleMessageSource messageSource() { final ResourceBundleMessageSource source = new ResourceBundleMessageSource(); source.setBasename("internationalization/lang"); return source; } }
3.4.3 Greetings controller class
Add the following code to the controller class to accept the incoming request and return a response to the user.
HelloController.java
package com.springboot.internationalization.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.bind.annotation.*; import java.util.Locale; //lombok annotation @Slf4j //spring annotations @RestController @RequestMapping("/api") public class HelloController { @Autowired private ResourceBundleMessageSource source; @Value("${placeholder.greetings}") private String greetings; //URL - http://localhost:9800/api/get-message //or //URL - http://localhost:9800/api/get-message?username=Daniel //note - incoming request to contain the optional "Accept-Language" header @GetMapping("/get-message") public String getLocaleMessage( @RequestHeader(name = "Accept-Language", required = false) final Locale locale, @RequestParam(name = "username", defaultValue = "John Wick", required = false) final String username) { //if "Accept-Language" header is not present, "en" locale is treated as default //if no matching locale is found, "en" locale is treated as default log.info("Returning greetings for locale = {}", locale); return source.getMessage(greetings, new Object[]{username}, locale); } }
4. Run the Application
To execute the application, right-click on the SpringbootInternationalizationApplication.java
class, Run As -> Java Application
.
5. Project Demo
When the application is started, open the Postman tool to hit the application endpoints to persist the data into the database or fetch from it. You are free to use any other tool of your choice to make the post and get requests to the endpoints. Remember that each incoming request contains the Accept-Language
header, where we will specify the locale, and based on this locale the appropriate message, will be returned to the user.
Application endpoints
-- HTTP GET endpoint – http://localhost:9800/api/get-message -- HTTP GET end (with username specified) – http://localhost:9800/api/get-message?username=Daniel
In the below image we have sent the Accept-Language
header value as de
and the message will be displayed in the german language. Similarly, change the header value to fr
and the message will be displayed in the French language.
That is all for this tutorial and I hope the article served you whatever you were looking for. Happy Learning and do not forget to share!
6. Summary
In this section, you learned,
- Steps to implement internationalization in spring boot
You can download the sample application as an Eclipse project in the Downloads section.
7. Download the Project
This was an example of implementing internationalization in a spring boot application.
You can download the full source code of this example here: Internationalization in Spring Boot