I am currently working on the localization of my (second) Spring Boot project. However, I have come to a halt after several hours of struggling: I am unable to get a user-editable Session localization.
The problem appears to occur as soon as the user sends a GET request with the lang parameter. (travel down below to see the results I am getting)
Details
Spring Boot version:(3.0.0-M3)
Expected localized content
i18n/messages.properties is empty
i18n/messages_en_US.properties:
morning=good morning afternoon=bye
i18n/messages_fr_FR.properties:
morning=salut afternoon=a+
i18n/messages_ja_JP.properties:
morning=ohayou afternoon=jane
Configuration
application.properties (section related to this issue):
spring.messages.always-use-message-format=true spring.messages.basename=i18n.messages spring.messages.fallback-to-system-locale=false spring.messages.use-code-as-default-message=false
LocalizationConfiguration file:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.i18n.SessionLocaleResolver; @Configuration public class LocalizationConfiguration implements WebMvcConfigurer { @Bean public LocaleResolver localeResolver() { SessionLocaleResolver localeResolver = new SessionLocaleResolver(); // localeResolver.setDefaultLocale(Locale.US); return localeResolver; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("lang"); return localeChangeInterceptor; } @Override public void addInterceptors(InterceptorRegistry interceptorRegistry) { interceptorRegistry.addInterceptor(localeChangeInterceptor()); } }
Display
Page Controller:
@GetMapping @RequestMapping(value = "/international") public String getInternationalView(Model model) { return "international"; }
Template loaded (international.html):
<!DOCTYPE html> <html xmlns:th="https://www.thymeleaf.org" th:with="lang=${#locale.language}" th:lang="${lang}"> <head> <script src="https://kit.fontawesome.com/2f4c03ee9b.js" crossorigin="anonymous"></script> <script th:src="@{/webjars/jquery/3.0.0/jquery.min.js}"></script> <script th:src="@{/webjars/popper.js/2.9.3/umd/popper.min.js}"></script> <script th:src="@{/webjars/bootstrap/5.1.3/js/bootstrap.min.js}"></script> <link th:rel="stylesheet" th:href="@{/webjars/bootstrap/5.1.3/css/bootstrap.min.css} "/> <meta charset="UTF-8"/> <title>Localization tests</title> </head> <body> <p th:text="${#locale}"></p> <p th:text="#{morning}"></p> <p th:text="#{afternoon}"></p> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false"> <i class="fa-solid fa-language fa-4x"></i> </button> <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1"> <li><a class="dropdown-item" th:href="@{''(lang=en)}">English</a></li> <li><a class="dropdown-item" th:href="@{''(lang=fr)}">Français</a></li> <li><a class="dropdown-item" th:href="@{''(lang=jp)}">日本語</a></li> </ul> </div> </body> </html>
What is being displayed
As you can see in the above gif, the first display of the page shows the messages in the browser’s language. However, as soon as an other language is selected the page breaks apart, with the exception of the #locale parameter.
Advertisement
Answer
Try it.
import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.i18n.SessionLocaleResolver; import java.util.Locale; @Configuration public class ApplicationConfig implements WebMvcConfigurer { @Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasenames("classpath:/i18n/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); localeChangeInterceptor.setParamName("lang"); return localeChangeInterceptor; } @Bean(name = "localeResolver") public SessionLocaleResolver sessionLocaleResolver() { SessionLocaleResolver localeResolver = new SessionLocaleResolver(); localeResolver.setDefaultLocale(new Locale("en")); return localeResolver; } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeChangeInterceptor()); } }