Showing posts with label Internationalization. Show all posts
Showing posts with label Internationalization. Show all posts

Sunday, 18 November 2012

Spring Internationalization Example (with Annotations)

Spring InternationalizationThis post describes how to implement message internationalization in Spring. The code example is available from GitHub in the Spring-MVC-Internationalization directory. It is based on the Spring MVC with annotations example.

Internationalization

We define two resource bundles (setA and setB) containing string translations for German, French and English. These are created in the src/main/resources maven directory.

Configuration

We need to create:
  • a ResourceBundleMessageSource bean to load the string translations
  • a LocaleChangeInterceptor bean which will intercept requests and extract a parameter value (if available) to detect language changes
  • a SessionLocaleResolver bean to store the user's locale preference in the session
  • to register the LocaleChangeInterceptor in the interceptor registry
 We extend our web configuration:
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "com.jverstry")
public class WebConfig extends WebMvcConfigurerAdapter {

    ...

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource result
            = new ResourceBundleMessageSource();

        String[] basenames = {
            "i18n.setA.setA",
            "i18n.setB.setB"
        };

        result.setBasenames(basenames);

        return result;

    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {

        LocaleChangeInterceptor result = new LocaleChangeInterceptor();
        result.setParamName("lang");

        return result;

    }

    @Bean
    public LocaleResolver localeResolver() {

        SessionLocaleResolver result = new SessionLocaleResolver();
        result.setDefaultLocale(Locale.ENGLISH);

        return result;

    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

}

Controller

We simply our controller a lot:
@Controller
public class MyController {

    @RequestMapping(value = "/")
    public String home() {
        return "index";
    }

}

JSP Page

We only keep the index.jsp page, where we add links to change the language of displayed messages:
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<!doctype html>
<html lang="en">
<head>
  <title>Welcome To Spring MVC Internationalization !!!</title>
</head>
<body>
  <h1>Spring MVC Internationalization !!!</h1>
  <p>Choose:
      <a href="<c:url value='?lang=en'/>">English</a>
      | <a href="<c:url value='?lang=fr'/>">French</a>
      | <a href="<c:url value='?lang=de'/>">German</a>
  </p>

  <p>Greetings: <spring:message code="greetings" text="missing" /></p>
  <p>Text 2: <spring:message code="text2" text="missing" /></p>
  <p>Current: <c:out value="${pageContext.response.locale}" /></p>
</body>
</html>

Running The Example

Once compiled, the example can be run with mvn tomcat:run. Then, browse:

  http://localhost:8383/spring-mvc-internationalization/

The main page will be displayed:


If you click on German, the German text is displayed:


More Spring related posts here.

Saturday, 17 November 2012

Introduction To Java Internationalization

This post is a quick introduction/reminder about internationalization (i18n) in Java. The code examples are available from GitHub in the Java-Internationalization directory.

Introduction

Making a Java application international is about dealing with:
  • Displayed text - Proper text according to user language.
  • Dates - Formatting, for example month, day year, or day, month, year?
  • Currencies - Using a comma or a dot as a separator? number of significant digits?

Locale

Localization is the process of adapting displayed text, dates and currencies to a country, region or language. Java defines the Locale class, which represents a language, and eventually a country or region associated to it.

The following describes how to list available Locale:
for ( Locale l : Locale.getAvailableLocales() ) {
    String s = l.getDisplayLanguage(Locale.ENGLISH)
        + " " + l.getDisplayCountry(Locale.ENGLISH);
    System.out.println(s);
}
The language and corresponding country is displayed (if available):
Japanese Japan
Spanish Peru
English
...

Resource Bundle & Property Files

ResourceBundles are created by providing a Locale. They contain objects and strings internationalized according to the provided locale.

Internationalized strings can be loaded from property files too:

Resource Bundles in Maven Java

Here is the content of MessageBundle_fr_FR:
greetings = Bonjour.
farewell = Au revoir.
inquiry = Comment allez-vous?
The following code describes how to create locales and load corresponding property files:
// Creating locales
Locale l_de_DE = new Locale("de", "DE");
Locale l_fr_FR = new Locale("fr", "FR");

// Resource bundles based on property files
ResourceBundle rb_de_DE
    = ResourceBundle.getBundle(
        "com.jverstry.ResourceBundles.MessagesBundle",
            l_de_DE);

ResourceBundle rb_fr_FR
    = ResourceBundle.getBundle(
        "com.jverstry.ResourceBundles.MessagesBundle",
            l_fr_FR);

// Fetching translated text
System.out.println(rb_de_DE.getString("inquiry"));
System.out.println(rb_fr_FR.getString("inquiry"));
System.out.println(rb_de_DE.getString("greetings"));
System.out.println(rb_fr_FR.getString("greetings"));

Notice that one must provide the "package path" to load the property files.

The output is:
Wie geht's?
Comment allez-vous?
Hallo.
Bonjour.

Dates & Currencies

In an earlier post, we have already described how to format currencies.

The following code describes how to format a date using locales:
// Creating locales
Locale l_de_DE = new Locale("de", "DE");
Locale l_fr_FR = new Locale("fr", "FR");

// Retrieving date formatters
DateFormat df_de_DE
    = DateFormat.getDateInstance(DateFormat.FULL, l_de_DE);

DateFormat df_fr_FR
    = DateFormat.getDateInstance(DateFormat.FULL, l_fr_FR);

Date date = new Date();

System.out.println(df_de_DE.format(date));
System.out.println(df_fr_FR.format(date));
The output is:
Samstag, 17. November 2012
samedi 17 novembre 2012

More Java related posts here.