Internationalization in modern applications is a joint effort between three layers.
Spring Core defines the MessageSource interface and provides the ResourceBundleMessageSource implementation to handle core translation mechanics. (tutorial here)
Spring MVC introduces the LocaleResolver interface to extract and manage the user's language preferences from web requests. (tutorial here) Spring Boot acts as the glue, automatically detecting these components and configuring them behind the scenes so you can use localized messages instantly with zero boilerplate code.
In Spring Boot, we can still register the MessageSource as seen in Spring MVC example. If we want to take advantage of Boot's auto-configuration, we just have to place messages.properties along with a couple of optional messages_xy.properties (where xy represents language codes) files in the classpath.
Note that a default file without a language code must be provided for Boot's auto-configuration to work (e.g., messages.properties along with messages_fr.properties or myFolder/msg.properties along with myFolder/msg_fr.properties). Alternatively we can explicitly register a MessageSource as a bean.
In a Spring Boot application, to use resource file names other than 'messages', we can add the following property in application.properties:
spring.messages.basename= myFolder/msg
Here is the list of Spring Boot common properties.
Example
Message Resources
src/main/resources/messages.propertiesapp.name = resource bundle test invoked by {0}
src/main/resources/messages_fr.propertiesapp.name=Test de bundle de ressources lancé par {0}
Spring Boot application.properties
src/main/resources/application.propertiesspring.mvc.view.prefix= /WEB-INF/pages/
spring.mvc.view.suffix= .jsp
I18nExampleController
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Locale;
@Controller
public class I18nExampleController {
@Autowired
MessageSource messageSource;
@RequestMapping("/test1")
@ResponseBody
public String handleRequest (Locale locale) {
return messageSource.getMessage(
"app.name", new Object[]{"Joe"}, locale);
}
}
Main class
package com.logicbig.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class I18nExampleMain {
public static void main (String[] args) {
SpringApplication.run(I18nExampleMain.class, args);
}
}
To try examples, run spring-boot maven plugin (configured in pom.xml of example project below):
mvn spring-boot:run Or run the main method class from IDE.
$ curl -s "http://localhost:8080/test1 resource bundle test invoked by Joe
Let's use curl to explicitly send a different 'Accept-Language' header:
$ curl -s -H "Accept-Language: fr-FR" "http://localhost:8080/test1" Test de bundle de ressources lancé par Joe
Resolving messages in a JSP page
In a JSP file, to resolve i18n messages by code, we will use spring:message tag.
src/main/webapp/WEB-INF/pages/myPage.jsp<%@ page language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<html>
<body>
<h3>A JSP page</h3>
<spring:message code="app.name" arguments="${by}"/>
</body>
</html>
Controller
package com.logicbig.example;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class I18nExampleController2 {
@RequestMapping("/test2")
public String handleRequest (Model model) {
model.addAttribute("by", "Joe");
return "myPage";
}
}
$ curl -s "http://localhost:8080/test2"
<html> <body> <h3>A JSP page</h3> resource bundle test invoked by Joe </body> </html>
Dependencies and Technologies Used: - Spring Boot 4.0.0
- spring-boot-starter-web (Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container (deprecated in favor of spring-boot-starter-webmvc))
- tomcat-embed-jasper 11.0.14 (Core Tomcat implementation)
- JDK 25
- Maven 3.9.11
|