Internationalization and Localization in struts2

Internationalization (i18n) is the process of planning and implementing products and services so that they can easily be adapted to specific local languages and cultures, a process called localization. The internationalization process is sometimes called translation or localization enablement. Internationalization is abbreviated i18n because the word starts with an i and ends with an n, and there are 18 characters between the first i and the last n.

Will create a simple employee form screen, display the message from resource bundle via the Struts 2 UI components, and change the locale base on the selected language option.

Resource Bundles:
Struts2 uses resource bundles to provide multiple language and locale options to the users of the web application. You don't need to worry about writing pages in different languages. All you have to do is to create a resource bundle for each language that you want. The resource bundles will contain titles, messages, and other text in the language of your user. Resource bundles are the file that contains the key/value pairs for the default language of your application.

When you reference a message element by its key, Struts framework searches for a corresponding message bundle in the following order:

  • ActionClass.properties
  • Interface.properties
  • SuperClass.properties
  • model.properties
  • package.properties
  • struts.properties
  • global.properties
To develop your application in multiple languages, you would have to maintain multiple property files corresponding to those languages/locale and define all the content in terms of key/value pairs. 

For example if you are going to develop your application for US English (Default), Hindi,Spanish, Chinese, German and Franch the you would have to create three properties files. Here I will use global.properties file only, you can make use of different property files to segregate different type of messages.
  • global.properties: By default English (United States) will be applied
  • global_fr.properties: This will be used for Franch locale.
  • global_es.properties: This will be used for Spanish locale.
  •  global_de.properties: This will be used for German locale.
  • global_hn.properties: This will be used for Hindi locale.
  • global_zh_CN.properties: This will be used for China locale. 
global.name = Name
global.age = Age
global.telephone = Telephone
global.email = Email
global.submit = Submit
global.success = Employee Successfully Added
global.form = Employee Form
global.name = \u0928\u093E\u092E
global.age = \u0909\u092E\u094D\u0930
global.telephone = \u091F\u0947\u0932\u0940\u092B\u094B\u0928
global.email = \u0908\u092E\u0947\u0932
global.submit = \u092A\u094D\u0930\u0938\u094D\u0924\u0941\u0924 \u0915\u0930\u0928\u093E
global.success = \u0915\u0930\u094D\u092E\u091A\u093E\u0930\u0940 \u0938\u092B\u0932\u0924\u093E\u092A\u0942\u0930\u094D\u0935\u0915 \u091C\u094B\u0921\u093C\u093E \u0917\u092F\u093E
global.form = \u0915\u0930\u094D\u092E\u091A\u093E\u0930\u0940 \u092A\u0930\u094D\u091A\u093E
global.name = Nennen
global.age = Alter
global.submit = Einreichen
global.form = Angestellter Formular
global.telephone = Telefonieren
global.email = Emaeiln
global.success = Mitarbeiter erfolgreich am
global.name = Nombre de usuario
global.age = Edad
global.telephone = Teléfono
global.email = Emaile
global.submit = Presentar
global.form = Formulario Empleado
global.success = Empleado con éxito Agregado
global.name = Nom d'utilisateur 
global.age = l'âge
global.telephone = téléphone
global.email = Emailé
global.submit = Soumettre des
global.form = Formulaire d'employés
global.success = Employé ajouté avec succès
global.name = \u540D
global.age =\u5E74\u9F84
global.telephone = \u7535\u8BDD
global.email = \u7535\u5B50\u90AE\u4EF6
global.form = \u5458\u5DE5\u8868\u5355
global.success = \u5458\u5DE5\u6210\u529F\u6DFB\u52A0

Access the messages:
There are several ways to access the message resources, including getText, the text tag, key attribute of UI tags, and the i18n tag. Let us see them in brief:

To display i18n text, use a call to getText in the property tag, or any other tag, such as the UI tags as follows:
<s:property value="getText('some.key')" />
The text tag retrieves a message from the default resource bundle ie. struts.properties
<s:text name="some.key" />
The i18n tag pushes an arbitrary resource bundle on to the value stack. Other tags within the scope of the i18n tag can display messages from that resource bundle:
<s:i18n name="some.package.bundle">
     <s:text name="some.key" />
The key attribute of most UI tags can be used to retrieve a message from a resource bundle:
<s:textfield key="some.key" name="textfieldName"/>
Localization Example:
Internationalization and Localization in struts2

Let us target to create employee.jsp from the previous chapter in multiple languages. Same file would be written as follows:
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<title><s:property value="getText('global.form')" /> - Struts2 Demo | dineshonjava.com</title>
<s:head />
<h2><s:property value="getText('global.form')" /></h2>
<s:form action="employee" method="post" validate="true">
    <s:textfield name="name" key="global.name" size="20" />
    <s:textfield name="age" key="global.age" size="20" />
    <s:textfield name="email" key="global.email" size="20" />
    <s:textfield name="telephone" key="global.telephone" size="20" />
    <s:submit name="submit" key="global.submit" align="center" />

<s:url id="localeEN" namespace="/" action="locale" >
   <s:param name="request_locale" >en</s:param>
<s:url id="localeHN" namespace="/" action="locale" >
   <s:param name="request_locale" >hn</s:param>
<s:url id="localeES" namespace="/" action="locale" >
   <s:param name="request_locale" >es</s:param>
<s:url id="localezhCN" namespace="/" action="locale" >
   <s:param name="request_locale" >zh_CN</s:param>
<s:url id="localeDE" namespace="/" action="locale" >
   <s:param name="request_locale" >de</s:param>
<s:url id="localeFR" namespace="/" action="locale" >
   <s:param name="request_locale" >fr</s:param>
<s:a href="%{localeEN}" >English</s:a>
<s:a href="%{localeHN}" >Hindi</s:a>
<s:a href="%{localeES}" >Spanish</s:a>
<s:a href="%{localezhCN}" >Chinese</s:a>
<s:a href="%{localeDE}" >German</s:a>
<s:a href="%{localeFR}" >France</s:a>
We will create success.jsp file which will be invoked in case defined action returns SUCCESS.
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<title><s:property value="getText('global.form')" /> - Struts2 Demo | dineshonjava.com</title>
    <h2><s:property value="getText('global.success')" />.</h2>
Here we would need to create following two actions.
(a) First action a to take care of Locale and display same success.jsp file with different language
(b) Another action is to take care of submitting form itself.
Both the actions will return SUCCESS, but we will take different actions based on return values because our purpose is different for both the actions:

package com.dineshonjava.com.struts2.action.locale;

import com.opensymphony.xwork2.ActionSupport;

 * @author Dinesh Rajput
public class EmployeeLocaleAction extends ActionSupport {

 private static final long serialVersionUID = 1L;
    public String execute() {
        return SUCCESS;
package com.dineshonjava.com.struts2.action;

import com.opensymphony.xwork2.ActionSupport;

 * @author Dinesh Rajput
public class EmployeeAction extends ActionSupport {

 private static final long serialVersionUID = 1L;
 private String name;
    private Integer age;
    private String email;
    private String telephone;
    public String addEmployee() {
        return SUCCESS;
 public String getName() {
  return name;
 public void setName(String name) {
  this.name = name;
 public Integer getAge() {
  return age;
 public void setAge(Integer age) {
  this.age = age;
 public String getEmail() {
  return email;
 public void setEmail(String email) {
  this.email = email;
 public String getTelephone() {
  return telephone;
 public void setTelephone(String telephone) {
  this.telephone = telephone;
We will create our struts.xml with two actions as follows:
<?xml version="1.0" encoding="UTF-8" ?>
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="false" />
    <constant name="struts.custom.i18n.resources" value="global" />
    <package name="default" extends="struts-default" namespace="/">
        <action name="employee" class="com.dineshonjava.com.struts2.action.EmployeeAction">
            <result name="success">/success.jsp</result>
      <result name="input">/employee.jsp</result>
          <result name="error">/error.jsp</result>
        <action name="locale" class="com.dineshonjava.com.struts2.action.locale.EmployeeLocaleAction">
            <result name="success">/employee.jsp</result>
Following is the content of web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

Now, right click on the project name and click Export > WAR File to create a War file. Then deploy this WAR in the Tomcat's webapps directory. Finally, start Tomcat server and try to access
URL http://localhost:8080/doj/employee.jsp.

This will give you following screen:


Now select on Hindi language.


Now select on Spanish language.


Now select on Chines language.


Now select on German language.


Now select on German language.


Now after submit the form following success messages display as per as languages selected.


Download Source Code

<<Previous <<   || Index ||   >>Next >>