Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Struts2 Localization/Internationalization (i18n)


May 15, 2021 Struts2


Table of contents


Internationalization (i18n) is the process of planning and implementing products and services to better adapt to a particular local language and culture, i.e. the localization process, which is sometimes referred to as translation or localization implementation. The internationalization abbreviation is i18n, and the word starts with i and ends with n because there are 18 characters between the first i and the last n.
Struts2 uses bundle resource bundles, interceptors, and tag libraries to provide localization, i18n support, primarily in the following places:

  • UI tag

  • Information and errors.

  • Action class.

The resource bundle

Struts2 uses resource bundles to provide users with multiple language and locale settings options for Web applications. Y ou don't have to worry about writing pages in different languages, all you need to do is create a resource bundle for each language you want. The resource bundle will contain the title, message, and other text in the user's language, which is a pair of key/value files that contain the application's default language.
The simplest naming format for a resource file is:

bundlename_language_country.properties

Bundlename can be ActionClass, Interface, SuperClass, Model, Package, Global Resource Properties. T he next section language_country represents the country locale, for example, the Spanish (Spain) locale is represented by es_ES, the English (United States) locale is represented by en_US, and so on. Skip the optional country section here first.
When you reference message elements through key, the Struts framework searches for the appropriate bundles of information in the following order:

  • ActionClass.properties

  • Interface.properties

  • SuperClass.properties

  • model.properties

  • package.properties

  • struts.properties

  • global.properties

To develop applications in multiple languages, you must maintain multiple property files corresponding to those languages/locales and define everything based on each pair of key/values. F or example, if you want to develop applications in U.S. English (default), Spanish, and French, you must create three property files. H ere we will use global.properties files, and you can also use different property files to separate different types of information.

  • global.properties: English by default (UNITED States)

  • global_fr.properties: This will be used in French environments.

  • global_es.properties: This will be used in Spanish environments.

Access the information

There are several ways to access information resources, including getText, text tags, key properties of UI tags, and i18n tags. Let's take a brief look at:

To display i18n text, getText needs to be called in the property label or any other label, such as a UI label, as follows:

<s:property value="getText('some.key')" />

The text label retrieves information from the default resource bundle, struts.properties:

<s:text name="some.key" />

The i18n label pushes any resource bundle to the value stack, while other labels within the i18n tag display information from the resource bundle:

<s:i18n name="some.package.bundle">
     <s:text name="some.key" />
</s:i18n>

The key property of most UI tags can be used to retrieve information from a resource bundle:

<s:textfield key="some.key" name="textfieldName"/>

Example of localization

Now let's create the index file in the previous chapter in multiple .jsp, as follows:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Employee Form with Multilingual Support</title>
</head>

<body>
   <h1><s:text name="global.heading"/></h1>

   <s:url id="indexEN" namespace="/" action="locale" >
      <s:param name="request_locale" >en</s:param>
   </s:url>
   <s:url id="indexES" namespace="/" action="locale" >
      <s:param name="request_locale" >es</s:param>
   </s:url>
   <s:url id="indexFR" namespace="/" action="locale" >
      <s:param name="request_locale" >fr</s:param>
   </s:url>

   <s:a href="%{indexEN}" >English</s:a>
   <s:a href="%{indexES}" >Spanish</s:a>
   <s:a href="%{indexFR}" >France</s:a>

   <s:form action="empinfo" method="post" namespace="/">
      <s:textfield name="name" key="global.name" size="20" />
      <s:textfield name="age" key="global.age" size="20" />
      <s:submit name="submit" key="global.submit" />
   </s:form>

</body>
</html>

Now create .jsp file, which will be called if action returns SUCCESS results.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Success</title>
</head>
<body>
   <s:property value="getText('global.success')" />
</body>
</html>

Here we need to create the following two actions. ( a) the first action handles the locale and displays the same index .jsp file in different languages; B oth actions will return TOCSS, but we will take different actions based on the return value, because the purpose of both actions is different:

Locale Action

package cn.w3cschool.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class Locale extends ActionSupport{
   public String execute() 
   {
       return SUCCESS;
   }
}

Submit form Action

package cn.w3cschool.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class Employee extends ActionSupport{
   private String name;
   private int age;
   
   public String execute() 
   {
       return SUCCESS;
   }
   
   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public int getAge() {
       return age;
   }
   public void setAge(int age) {
       this.age = age;
   }
}

Now, let's create the following three global.properties files and put CLASSPATH in:

global.properties

global.name = Name
global.age = Age
global.submit = Submit
global.heading = Select Locale
global.success = Successfully authenticated

global_fr.properties

global.name = Nom d'utilisateur 
global.age = l'âge
global.submit = Soumettre des
global.heading = Sé lectionnez Local
global.success = Authentifi	é  avec succès

global_es.properties

global.name = Nombre de usuario
global.age = Edad
global.submit = Presentar
global.heading = seleccionar la configuracion regional
global.success = Autenticado correctamente

Let's go on to create a struts file .xml action, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name="struts.devMode" value="true" />
   <constant name="struts.custom.i18n.resources" value="global" />

   <package name="helloworld" extends="struts-default" namespace="/">
      <action name="empinfo" 
         class="cn.w3cschool.struts2.Employee"
         method="execute">
         <result name="input">/index.jsp</result>
         <result name="success">/success.jsp</result>
      </action>
      
      <action name="locale" 
         class="cn.w3cschool.struts2.Locale"
         method="execute">
         <result name="success">/index.jsp</result>
      </action>
   </package>

</struts>

Here's .xml the web 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">

   <display-name>Struts 2</display-name>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

Now, right-click on the project name, and then click "Export" and "WAR File" to create a WAR file. T he WAR file is then deployed in Tomcat's webapps directory. Finally, start the Tomcat server and try to access the URL http://localhost:8080/HelloWorldStruts2/index.jsp display the following interface:

Struts2 Localization/Internationalization (i18n)

You can now select any language, and if you choose Spanish, the following results are displayed:

Struts2 Localization/Internationalization (i18n)

You can also try French. F inally, click the Submit button and the following interface will appear when you are in a Spanish-speaking environment:

Struts2 Localization/Internationalization (i18n)

Congratulations, you now have a multilingual page where you can try to push your site around the world.