struts i18n

Struts2 I18n

Internationalization(aka I18n) is done via message resource(also called resource bundle) and locale.

Message Resource

Message resource is a properties file which looks like next:

personBean.firstName=Nombre
personBean.lastName=Apellidos
thankyou=Gracias por registrarse, %{personBean.firstName}. 

In struts2, this file has three level:

  1. Class Level

    The name of properties file has to be same as struts action class as well as the package.

    For example, there is action src/main/java/example/struts2/Login.java, then the properties file should be src/main/resources/example/struts2/Login.properties

    This rule is suited for interface too.

  2. Package Level

    properties file name is package.properties, cannot be other names.

    For instance, package.properties placed under src/main/resources/example/struts, then all class under package
    example.struts or its sub-packages can use this resource file.

  3. Global Level

    For this level, developer need to declare the global properties file in struts.xml like , the file name can be any value without extension.

Search Order

The search order is : 1 -> 2 -> 3.

For example, there is example.struts2.i18n.Login.Java, the order is: Search Login.properties under the example.struts2.i18n, if there is not, then search the package.properties under the example.struts2.i18n, if not, search package.properties under the example.struts2, etc.

Usage

The framework supports message resource in the following places:

  • the UI tags <s:textfield key="properties-file-key-name" /> <s:text name="properties-file-key-name" /> <s:property value="getText('some.key')" /> <s:i18n name="example.struts.i18n.p"></s:i18n><s:text name="user.name" /></s:i18n> it ask for user.name message from example/struts/i18n/p.properties
  • messages and errors from the ValidationAware
  • within action class through the getText() method

    public void validate(){
          if("".equals(getUsername())){
               addFieldError("username", getText("username.required"));
          }
    		
     }
    

Using only global bundle

If you don’t need to use the package-scan-functionality and only base on the global bundles (those provided by the framework and via struts.custom.i18n.resources) you can use existing GlobalLocalizedTextProvider implementation. To use this please define the following option in your struts.xml:

<constant name="struts.localizedTextProvider" value="global-only" />

Custom TextProvider and TextProviderFactory

If you want use a different logic to search for localized messages, or you want to use a database or just want to
search default bundles, you must implement both those interfaces (or subclass the existing implementations). You can check a small example app how to use both. Please remember that the TextProvider interface is implemented by the ActionSupport class, that’s why an extra layer - TextProviderFactory - is needed.

Locale

By default, struts2 uses the user’s default locale.
The convention of properties file name is File-name_locale-code.properties, such as A_zh-CN.properties. If locale is en for English then locale code can be ignored.

Set locale value

Developer is able to set locale value by parameter request_locale.

```Java Server Pages

zh-CN

Change language to chinese simplified

```

By specifying the locale as a url parameter, it tells struts to look for property files ends with zh-CN.

I18n Interceptor

Following is the info from struts official doc about the I18n Interceptor:

An interceptor that handles setting the locale specified in a session as the locale for the current action request. In addition, this interceptor will look for a specific HTTP request parameter and set the locale to whatever value is
provided, it also looks for specific cookie to read locale from. This means that this interceptor can be used to allow for your application to dynamically change the locale for the
user’s session or, alternatively, only for the current request. This is very useful for applications that require multi-lingual support and want the user to be able to set his or her language preference at any point. The locale parameter is removed during the execution of this interceptor, ensuring that properties aren’t set on an action (such as request_locale) that have no typical corresponding setter in your action. For example, using the default parameter name, a request to foo.action?request_locale=en_US, then the locale for US
English is saved in the user’s session and will be used for all future requests. If there is no locale set (for example with the first visit), the interceptor uses the browser locale. Parameters parameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to and save in the session. By default this is request_locale requestCookieParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to and save in a cookie. By default this is request_cookie_locale requestOnlyParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to for the current request only, without saving it in the session. By default this is request_only_locale attributeName (optional) - the name of the session key to store the selected locale. By default this is
WW_TRANS_I18N_LOCALE localeStorage (optional) - the name of storage location, it can be none, session or cookie. By default this is session Examples <interceptor name="i18nCookie" class="org.apache.struts2.interceptor.I18nInterceptor"/> <action name="someAction" class="com.examples.SomeAction"> <interceptor-ref name="i18nCookie"> <param name="localeStorage">cookie</param> </interceptor-ref> <interceptor-ref name="basicStack"/> <result name="success">good_result.ftl</result> </action>

## Front-end I18n

There is also front-end I18n, like Jquery I18n

I18n at database level

There is a good article about the i18n in DB, please refer it for detail.

Written on May 29, 2016