Java message bundle locale
Providing Localized Messages and Labels
Messages and labels should be tailored according to the conventions of a user’s language and region. There are two approaches to providing localized messages and labels in a web application:
- Provide a version of the web page in each of the target locales and have a controller servlet dispatch the request to the appropriate page depending on the requested locale. This approach is useful if large amounts of data on a page or an entire web application need to be internationalized.
- Isolate any locale-sensitive data on a page into resource bundles, and access the data so that the corresponding translated message is fetched automatically and inserted into the page. Thus, instead of creating strings directly in your code, you create a resource bundle that contains translations and read the translations from that bundle using the corresponding key.
The Duke’s Tutoring application follows the second approach. Here are a few lines from the default resource bundle messages.properties:
nav.main=Main page nav.status=View status nav.current_session=View current tutoring session nav.park=View students at the park nav.admin=Administration admin.nav.main=Administration main page admin.nav.create_student=Create new student admin.nav.edit_student=Edit student admin.nav.create_guardian=Create new guardian admin.nav.edit_guardian=Edit guardian admin.nav.create_address=Create new address admin.nav.edit_address=Edit address admin.nav.activate_student=Activate student
Establishing the Locale
To get the correct strings for a given user, a web application either retrieves the locale (set by a browser language preference) from the request using the getLocale method, or allows the user to explicitly select the locale.
A component can explicitly set the locale by using the fmt:setLocale tag.
The locale-config element in the configuration file registers the default locale and other supported locales. This element in Duke’s Tutoring registers English as the default locale and indicates that German, Spanish, Portuguese, and Chinese are supported locales.
The Status Manager in the Duke’s Tutoring application uses the getLocale method to retrieve the locale and a toString method to return a localized translation of a student’s status based on the locale.
public class StatusManager < private FacesContext ctx = FacesContext.getCurrentInstance(); private Locale locale; /** Creates a new instance of StatusManager */ public StatusManager() < locale = ctx.getViewRoot().getLocale(); >public String getLocalizedStatus(StatusType status) < return status.toString(locale); >>
Setting the Resource Bundle
The resource bundle is set with the resource-bundle element in the configuration file. The setting for Duke’s Tutoring looks like this:
dukestutoring.web.messages.Messages bundle
After the locale is set, the controller of a web application could retrieve the resource bundle for that locale and save it as a session attribute (see Associating Objects with a Session) for use by other components or simply to return a text string appropriate for the selected locale:
public String toString(Locale locale)
Alternatively, an application could use the f:loadBundle tag to set the resource bundle. This tag loads the correct resource bundle according to the locale stored in FacesContext.
Resource bundles containing messages that are explicitly referenced from a JavaServer Faces tag attribute using a value expression must be registered using the resource-bundle element of the configuration file.
For more information on using this element, see Registering Application Messages.
Retrieving Localized Messages
A web component written in the Java programming language retrieves the resource bundle from the session:
ResourceBundle messages = (ResourceBundle)session.getAttribute("messages");
Then it looks up the string associated with the key person.lastName as follows:
messages.getString("person.lastName");
You can only use a message or messages tag to display messages that are queued onto a component as a result of a converter or validator being registered on the component. The following example shows a message tag that displays the error message queued on the userNo input component if the validator registered on the component fails to validate the value the user enters into the component.
Messages that are not queued on a component and are therefore not loaded automatically are referenced using a value expression. You can reference a localized message from almost any JavaServer Faces tag attribute.
The value expression that references a message has the same notation whether you loaded the resource bundle with the f:loadBundle tag or registered it with the resource-bundle element in the configuration file.
The value expression notation is var.message, in which var matches the var attribute of the f:loadBundle tag or the var element defined in the resource-bundle element of the configuration file, and message matches the key of the message contained in the resource bundle, referred to by the var attribute.
Here is an example from editAddress.xhtml in Duke’s Tutoring:
Notice that bundle matches the var element from the configuration file and that country matches the key in the resource bundle.
Copyright © 2013, Oracle and/or its affiliates. All rights reserved. Legal Notices
Message Bundles
The most common task of localization is to provide messages depending on the current user locale. To achieve this, messages must be extracted from code and placed in special property files, one file per language. A collection of such files is called a message bundle.
Apart from messages, the message bundle can also contain localized data format strings.
The default message bundle of your project is a set of messages_.properties files located in the base package under the src/main/resources folder.
Setting Up Locales
When you create a new project using Studio, you can set up the list of supported locales in the Locales field of the project wizard. This field allows you to select a languages and their codes.
Studio writes the list of language codes to the jmix.core.available-locales application property and language names to the corresponding messages_.properties files with localeDisplayName. key. You can later edit these properties manually or use the Locales tab of the Project Properties window in Studio.
For example, if you have defined two languages for your application: English (en) and Deutsch (de) , you have the following file structure in the project (provided that the base package is com.company.demo ):
src/main/resources/ com/company/demo/ messages_en.properties messages_de.properties application.properties
And the files have the following contents:
localeDisplayName.en=English
localeDisplayName.de=Deutsch
jmix.core.available-locales = en,de
Creating Messages
Group and Key
Usually, an application contains a single message bundle. Because the number of messages even in a simple application can be quite large, we recommend making property keys of two parts: the group and the message key, separated by the forward slash ( / ). It allows you to group related messages and avoid naming conflicts. In the following example, com.company.demo.view.main is the group and applicationTitle.text is the message key:
com.company.demo.view.main/applicationTitle.text=Demo App
But you can also define a message without a group, for example:
messageWithoutGroup = Message without a group
Localizing Data Model
Jmix introduces some conventions on localization of the data model elements: entity and attribute names, enumeration values. It allows the framework to find the localized names when displaying entities and enumerations in UI components.
Entity name is localized using the / format, attribute name — using the /. format. For example:
# entity name com.company.demo.entity/User=User # attribute names com.company.demo.entity/User.id=ID com.company.demo.entity/User.username=Username com.company.demo.entity/User.firstName=First name com.company.demo.entity/User.lastName=Last name com.company.demo.entity/User.password=Password com.company.demo.entity/User.email=Email
Enumeration name is localized using the / format, enumeration value — using the /. format. For example:
# enumeration name com.company.demo.entity/Status=Status # enumeration values com.company.demo.entity/Status.ACTIVE=Active com.company.demo.entity/Status.INACTIVE=Inactive com.company.demo.entity/Status.SUSPENDED=Suspended
You can easily create localized names of the data model elements in Studio visual designers. Click the 🌐 (globe) button next to the element name and enter localized values for available locales in the Localized Message dialog. |
Additional Bundles
In a big application with a lot of messages you can maintain a reasonable size of the property files by defining additional message bundles:
- Create a set of property files with arbitrary name in any directory under src/main/resources . In the example below, we created additional_messages files in the same base package as the main message bundle:
src/main/resources/com/company/demo/ additional_messages_en.properties additional_messages_de.properties messages_en.properties messages_de.properties
@SpringBootApplication @MessageSourceBasenames() public class DemoApplication implements AppShellConfigurator
Messages from all bundles of the application are loaded into a single list, so property keys must be unique among all your bundles. |