Java resource localization and Internationalization

Source: Internet
Author: User
Tags locale setting

Java resource localization and Internationalization

 

Resource Package

 

When writing an application, you need to deal with some information related to locale. For example, some static text on the page is expected to be displayed in a language that you are used. The most primitive approach is to hard encode the information into a program (which may be a large string of judgment statements), but in this way, the program code and variable locale information are bundled together, if you need to modify the locale information or add other locale information, you have to modify the code again. The resource package can help you solve this problem. It puts the variable locale information into the resource package to achieve the purpose of separating the two. The application can automatically obtain the required information from the corresponding resource package through the current locale settings. The concept of a resource package is similar to the resource file (rc file) used by Windows programmers ).

 

Generally, a resource package requires two functions: binding with a specific locale and reading information about locale.

 

ResourceBundle class

You can view the resource package as a big family composed of many Members (Child classes). Each member is associated with a different locale object. How does it complete the association function?

 

Each member in the resource package shares a name called basename, which is then extended according to certain naming rules. The names of some members are listed below:

LabelResources

LabelResources_de

LabelResources_de_CH

LabelResources_de_CH_UNIX

It can be seen that these sub-classes are based on the naming rules basename_policage_country_variant. The language and other variables are used when you construct the Locale class. The resource package is associated with locale through the name that complies with the naming conventions. For example, LabelResource_de_CH corresponds to the locale object composed of German (de) and Swiss (CH.

 

Locale currentLocale = new Locale ("de", "CH", "UNIX"); ResourceBundle myResources = ResourceBundle. getBundle ("LabelResources", currentLocale); ResourceBundle. getBundle (message) // obtain the region environment used by the current system to obtain the specified resource file ResourceBundle. getBundle (message, locale) // obtain the corresponding resource file based on the specified region

 

When your application needs to find the resource package associated with a specific locale object, it can call the getBundle method of ResourceBundle and pass the locale object as a parameter.

 

 

ResourceBundle. getBundle (message) // obtain the region environment used by the current system to obtain the specified resource file ResourceBundle. getBundle (message, locale) // obtain the corresponding resource file according to the specified region

 

If the resource package subclass matching the locale object cannot be found, getBundle will try to find the most matched subclass. The specific search policy is as follows: getBundle uses the base name, locale object and default locale to generate a sequence of candidate resource package names. If the language code, country code, and optional variables of a specific locale object are null, the base name is the unique candidate resource package name. Otherwise, the specific locale object (regionage1, country1 and variant1) and default locale (regionage2, country2 and variant2) will generate the following sequence:

 

BaseName + "_" + language1 + "_" + country1 + "_" + variant1

BaseName + "_" + language1 + "_" + country1

BaseName + "_" + language1

BaseName + "_" + language2 + "_" + country2 + "_" + variant2

BaseName + "_" + language2 + "_" + country2

BaseName + "_" + language2

BaseName

 

Then, the getBundle method searches for matched resource package subclass in sequence based on the generated sequence and initializes the result subclass. First, it will look for a class that matches the name of the candidate resource package. If it finds a class that will create an instance of this class, we call it the result resource package. Otherwise, the getBundle method will find the corresponding resource file, which obtains the complete path of the resource file through the candidate resource package name ("Replace with"/"and add". properties). If a matching file is found, the getBundle method uses the resource file to create a PropertyResourceBundle instance, that is, the final result resource package. At the same time, the getBundle method caches these resource package instances for future use.

 

If no result resource package is found, this method throws a MissingResourceException. Therefore, to prevent exceptions from being thrown, at least one base name resource package subclass is required.

 

Note: The base name parameter must be a complete Class Name (such as LabelResources and resource. LabelResources), which is equivalent to specifying the complete class path when you reference a class. However, to be compatible with previous versions, you can use "/" to replace "." To indicate paths when using PropertyResourceBundles.

 

For example, you have the following resource classes and resource files:

MyResources. class,

MyResources_fr_CH.properties,

MyResources_fr_CH.class,

MyResources_fr.properties,

MyResources_en.properties,

MyResources_es_ES.class

You use the following locale settings to call the getBundle method. You will get different result Resource Packages (assuming that the default locale is Locale ("en", "UK "))

Locale settings and result resource package

Locale setting result resource package

Locale ("fr", "CH") MyResources_fr_CH.class

Locale ("fr", "FR") MyResources_fr.properties

Locale ("de", "DE") MyResources_en.properties

Locale ("en", "US") MyResources_en.properties

Locale ("es", "ES") MyResources_es_ES.class

 

After creating a resource package subclass instance, You need to obtain the specific information. Information is stored as key-value pairs in the resource package.

 

LabelResources. properties

 

# This isLabelResources. properties filegreetings = hello! Farewell = goodbye. Inquiry = Hello?

 

The string on the left of the equal sign indicates the primary key, which is unique. To obtain the value corresponding to the primary key, you can call the getString method of the ResourceBundle class and use the primary key as the parameter. In addition, lines starting with "#" in the file represent comment rows.

ListResourceBundle and PropertyResourceBundle subclasses

 

Abstract class ResourceBundle has two subclasses: ListResourceBundle and PropertyResourceBundle. They indicate two different implementation methods for the resource package subclass.

 

PropertyResourceBundle is used together with the resource file. An Attribute file is a common text file. You only need to write resource files with different names for different locale settings. However,The resource file can only contain strings.To store other types of objects, you can use ListResourceBundle.

 

ListResourceBundle stores the key-Value Pair information in the list of classes, and you must implement a specific subclass of ListResourceBundle.

 

If ListResourceBundle and PropertyResourceBundle cannot meet your needs, you can implement your own ResourceBundle subclass. Your subclass must cover two methods:HandleGetObject and getKeys.

 

Use resource files

 

The simplest way to use a resource package is to use the resource file. The following steps are generally required to use the resource file:

1. Create a default resource file

To prevent the resource file from being located, you 'd better implement a default resource file. The file name is the base name of the resource package plus the. properties suffix.

2. Create the required resource file

Prepare the corresponding resource file for the supported locale settings.

3. Set locale

You must provide the locale setting or switching function somewhere in the program, or put it in the configuration file.

4. Create a resource package based on locale settings

ResourceBundleresource =

ResourceBundle. getBundle ("LabelBundle", currentLocale );

5. Obtain locale information through the resource package

String value = resource. getString ("welcome ");

 

Note:When using the base name, pay special attention to the complete class name.(Or path name). For example, the class package of your application is org. javaresearch. j2seimproved. i18n, and your resource file is in the resource subdirectory of your application, your base name should be org. javaresearch. j2seimproved. i18n. resource. labelBundleBundle instead of resource. labelBundleBundle.

 

 

Use ListResourceBundle

 

The steps for using ListResourceBundle are basically the same as those for using resource files, except that you need to replace the corresponding resource files with the ListResourceBundle subclass. For example, if the base name of your application is LabelBundle and you want to support Locale ("en", "US") and Locale ("zh", "CN "), you need to provide the following Java files. Pay attention to the correspondence between class names and locale.

LabelBundle_en_US.java

LabelBundle_zh_CN.java

LabelBundle. java (default class)

 

The following code lists the source code of LabelBundle_zh_CN.java. Compared with the "key = value" method in the resource file, you first use the key-value pair to initialize a two-dimensional array, and return the array in the getContents method.

 

LabelBundle_zh_CN.java

 

Public class LabelBundle_zh_CN extendsListResourceBundle {public Object [] [] getContents () {return contents;} private Object [] [] contents = {"title", "title "}, {"surname", "surname" },{ "firstname", "name "},};}

 

After creating a resource class, you also need to set locale and create a resource package based on locale. You cannot use the getString method when getting a specific value through the resource package. Instead, you should call the getObject method. Because the getObject method returns an Object, you also need to perform correct type conversion. In fact, we recommend that you call the getObject method instead of the getString method when using resource files for your program's versatility.

Title = (String) resource. getObject ("title ");

If the system has both resource files and class files, the system will focus on class files rather than calling resource files.

MessageFormat class

We have discussed how to use resource files to separate code and variable information. However, in the actual process, some information cannot be fully defined in advance, and some running results may be used. The most typical example is the error prompt code, for example, the system prompts that an input must be within a certain range. Using the resource file mentioned above does not solve this problem well, so the MessageFormat class is introduced in Java.

 

MessageFormat provides a language-independent way to assemble messages. It allows you to replace a part of the message string with a specified parameter at runtime. You can define a pattern for MessageFormat, in which you can use placeholders to represent the changed part. For example, you have the following sentence:

 

Hello,Clf! Welcome to csdn! The current time is:24:43:12.

 

The ITALIC underlined part is changeable. You need to determine the final display based on the current time and different login users. We use placeholders to represent the changed parts. We can see the following pattern:

 

Hello, {0 }! Welcome to csdn! The current time is: {1, date} {1, time }.

 

The placeholder format is {ArgumentIndex, FormatType, FormatStyle}. For details, refer to the MessageFormat API instructions. Here we define two placeholders. The numbers correspond to the indexes in the input parameter array, the {0} placeholder is replaced by the first parameter, and the {1} placeholder is replaced by the second parameter, and so on.

You can set up to 10 placeholders. Each placeholder can appear multiple times and in different formats, such as {1, date} and {1, time }. By placing these schema definitions in different resource files, you can get different schema definitions based on different locale settings and dynamically replace placeholders with parameters.

 

The following uses the MessageFormatSample. java program as an example to describe each step in detail.

1. Find the variable part and define the mode accordingly. Put the mode into different resource files.

For example, the following two resource files are defined for the above mode:

MessagesBundle_en_US.properties

Welcome = Hi, {0 }! Welcome to Java Research Organization!

MessagesBundle_zh_CN.properties

Welcome = Hello, {0 }! Welcome to csdn!

 

2. Create a MessageFormat object and set its locale attribute.

 

  MessageFormat formatter = newMessageFormat("");      formatter.setLocale(currentLocale);

 

 

3. Get the mode definition from the resource package and set parameters.

 

messages = ResourceBundle.getBundle(  "MessagesBundle",currentLocale);Object [] testArgs = {"peachpi",new Date()};

 

4. format the schema definition and parameters.

 

 System.out.println(formatter.format(messages.getString("welcome"),testArgs));

 

 

About resource package Organization

Generally, you organize resource packages based on the purpose of resources. For example, you will put all the page buttons in a resource package named ButtonResources. In actual application, the following principles help you decide how to organize resource packages:

1. easy to maintain.

2. It is best not to put all the information into a resource package, because it will take a lot of time to load the resource package into the memory.

3. It is best to divide a large resource package into several small resource packages so that necessary resources can be imported during use to reduce memory consumption.

JSTL international label

   Function: Specifies the file used by the message resource.

   Function: displays messages with a specified key in the message resource file. Messages with parameters are supported.

   Function: Set parameter values for messages with parameters.

   Function: sets the message resource file.

  

An international example of multi-resource source files supporting modules

  

Resources \ IAMResources_zh_CN.properties, the content is

Test. common. message = test. common. message {0}

  

Resources \ UserSynResources_zh_CN.properties

Test. usersyn. message = test. usersyn. message {0}

  

IncludeTld. jsp:

 

  
   
  
  

 

Test. jsp

  

<%@include file="/includeTld.jsp"%>    
  
          
   
      
   
          
  
          
   
                  
    
            
    
         
  

 

 

Output: test. common. message clf

Test. usersyn. message clf

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.