Spring MVC Internationalization i18n Example
Internationalization is the process of designing your application for the international market; that is, make it able to support virtually any language, timezone or local setting. This tutorial shows how you can build Internationalized i18n web application using Spring MVC.
Project Structure
Make sure your project looks similar to the following structure. Note we configure the application using java configuration so we don’t need a web.xml
src |--main | +--java | +--com | +--memorynotfound | +--config | |--ServletInitializer.java | |--WebConfig.java | +--controller | |--HomeController.java | +--resources | |--messages_en.properties | |--messages_fr.properties | +--webapp | +--WEB-INF | +--views | |--index.jsp pom.xml
Creating Localized Language Property Files
First, we create the localized language files. We can add virtually any language which we need to support. For simplicity, I added only English and French. Note, I translated the French using Google Translate. So, don’t mind the possible spelling/grammar errors.
Add the messages_en.properties to the src/main/resources/ folder.
welcome.message = Hello, {0} welcome.greeting = Nice that you could join the meeting. We begin at {0}.
Add the messages_fr.properties to the src/main/resources/ folder.
welcome.message = Bonjour, {0} welcome.greeting = Belle que vous pourriez participer à la réunion. Nous commençons à {0}.
Using Locale in Controller
You can either add the java.util.Locale as an argument in the controller method – and spring will automatically inject it with the current locale – or you can obtain the current locale by calling the LocalContextHolder.getLocale() method.
package com.memorynotfound.controller; import org.springframework.stereotype.Controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.MessageSource; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.ui.Model; import java.util.Locale; @Controller public class HomeController { @Autowired private MessageSource messageSource; @RequestMapping(value = "/", method = RequestMethod.GET) public String index(Locale locale, Model model){ // add parametrized message from controller String welcome = messageSource.getMessage("welcome.message", new Object[]{"John Doe"}, locale); model.addAttribute("message", welcome); // obtain locale from LocaleContextHolder Locale currentLocale = LocaleContextHolder.getLocale(); model.addAttribute("locale", currentLocale); model.addAttribute("startMeeting", "10:30"); return "index"; } }
Adding Parameterized Message Programatically
By injecting the MessageSource in the controller we can create a parameterized message programatically using the MessageSource.getMessage(code, args, locale) method. This MessageSource takes care of loading the correct language message based on the given key and locale. We can optionally add some arguments.
@Autowired private MessageSource messageSource; String welcome = messageSource.getMessage( "welcome.message", new Object[]{"John Doe"}, locale);
Configure Spring MVC i18n
To support Spring MVC Internationalization (i18n), we need to configure 3 beans. A MessageSource, LocaleResolver and a LocaleInterceptor.
- ReloadableResourceBundleMessageSource is a special kind of MessageSource and is responsible for loading the messages property files. This bean can automatically load changes in the source properties file.
- CookieLocaleResolver writes the locale setting to a cookie with a fallback to the specified default locale or the request’s accept-header locale.
- LocaleChangeInterceptor allows to change the current locale on every request via a configurable request parameter.
package com.memorynotfound.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import java.util.Locale; @EnableWebMvc @Configuration @ComponentScan({"com.memorynotfound"}) public class WebConfig extends WebMvcConfigurerAdapter { @Bean public ReloadableResourceBundleMessageSource messageSource(){ ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } @Bean public CookieLocaleResolver localeResolver(){ CookieLocaleResolver localeResolver = new CookieLocaleResolver(); localeResolver.setDefaultLocale(Locale.ENGLISH); localeResolver.setCookieName("my-locale-cookie"); localeResolver.setCookieMaxAge(3600); return localeResolver; } @Bean public LocaleChangeInterceptor localeInterceptor(){ LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor(); interceptor.setParamName("lang"); return interceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeInterceptor()); } @Bean public InternalResourceViewResolver viewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
The equivalent spring mvc internationalization configuration looks like this:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <mvc:annotation-driven /> <context:component-scan base-package="com.memorynotfound" /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:messages"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <bean id="cookieResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="defaultLocale" value="en"/> <property name="cookieName" value="my-locale-cookie"/> <property name="cookieMaxAge" value="3600"/> </bean> <mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="lang"/> </bean> </mvc:interceptors> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
Adding Parameterized Message using Spring TagLibrary
This simple view illustrates how to change the default locale, and displays a couple of messages in the view. The first message is sent from the controller to the view. The second message uses spring taglib <spring:message /> which has an argument, this argument is automatically resolved by the taglib element. Finally, we display the current locale on the page.
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <html> <head> <title>Spring MVC Internationalization i18n Example</title> </head> <body> <h1>Spring MVC Internationalization i18n Example</h1> Language : <a href="?lang=en">English</a> | <a href="?lang=fr">French</a> <p>${message}</p> <p><spring:message code="welcome.greeting" arguments="${startMeeting}"/></p> Current Locale : ${pageContext.response.locale} / ${locale} </body> </html>
Demo
URL: http://localhost:8081/spring-mvc-i18n/
URL: http://localhost:8081/spring-mvc-i18n/?lang=fr
URL: http://localhost:8081/spring-mvc-i18n/?lang=en
And if we inspect the cookies for our application, we see that the my-locale-cookie has been set.
Download
From:一号门
Previous:Spring MVC Theme Switcher Example
COMMENTS