Search code examples
springmodel-view-controllerinternationalizationlocaleresourcebundle

spring mvc i18n: setting default locale seems to fallback to 'en'


I want to implement i18n in the following way:

  • have a default locale that isn't 'en' (FWIW, I am targeting a country-specific locale, like 'en_US').
  • have an 'en' specialization for some resources

Building on top of spring-by-example's simple-form project, I've changed the following:

Index: web/simple-form-annotation-config-webapp/src/main/resources/messages_en.properties
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>windows-1252
===================================================================
--- web/simple-form-annotation-config-webapp/src/main/resources/messages_en.properties  (date 1567652013000)
+++ web/simple-form-annotation-config-webapp/src/main/resources/messages_en.properties  (date 1567652013000)
@@ -0,0 +1,1 @@
+index.message=this is English (en)
Index: web/simple-form-annotation-config-webapp/src/main/webapp/WEB-INF/templates/footer.jsp
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- web/simple-form-annotation-config-webapp/src/main/webapp/WEB-INF/templates/footer.jsp   (date 1422210675000)
+++ web/simple-form-annotation-config-webapp/src/main/webapp/WEB-INF/templates/footer.jsp   (date 1567652013000)
@@ -4,13 +4,17 @@
 <div align="right">
     <div>
         <fmt:message key="button.locale"/>:
-            <c:url var="englishLocaleUrl" value="/index.html">
+            <c:url var="fooLocaleUrl" value="/index.html">
                 <c:param name="locale" value="" />
             </c:url>
+            <c:url var="englishLocaleUrl" value="/index.html">
+                <c:param name="locale" value="en" />
+            </c:url>
             <c:url var="spanishLocaleUrl" value="/index.html">
                 <c:param name="locale" value="es" />
             </c:url>
-        
+
+            <a href='<c:out value="${fooLocaleUrl}"/>'>Foo</a>
             <a href='<c:out value="${englishLocaleUrl}"/>'><fmt:message key="locale.english"/></a>
             <a href='<c:out value="${spanishLocaleUrl}"/>'><fmt:message key="locale.spanish"/></a>
     </div>

So now 'en' is a locale-specific resource, rather than the default (which is set by selecting 'Foo' as the lang).

I was expecting that clicking 'Foo' on index.html will present the original index.message from messages.properties, and clicking 'English' will present this is English (en) from the 'en'-specialized file. However, both produce the version from messages_en.properties.

How do I set it so the app considers the default to be other than 'en'?

Thanks!


Solution

  • Resolved.

    What I misunderstood is how to implement the notion of 'default' in the message bundle, and how it relates to the default locale. I was assuming that the basename resource (messages.properties) is mapped to the default locale.

    How it actually works is:

    • the default locale can be set through the locale resolver. It will then be used when no other locale is set.
    • the message bundle needs to have all common resources in the basename resource (messages.properties), and locale-specific properties in their respective resources. In this context, the ResourceBundle's 'default' set is the set of common, locale-agnostic properties.