11.6 Internationalization Actions
The JSTL internationalization (I18N) actions help you internationalize your Web applications. Three configuration settings support these actions.
Overview of JSTL Internationalization Actions
Table 11.13 lists the JSTL I18N actions.
Table 11.13. Internationalization Actions
|
<fmt:setLocale>
|
Sets the FMT_LOCALE configuration setting, which is used for resource bundle lookups; those resource bundles are used by <fmt:message> actions.
The FMT_LOCALE configuration setting is also used by JSTL formatting actions; see page 509.
|
<fmt:setBundle>
|
Searches for a resource bundle identified with the required basename attribute. <fmt:setBundle> stores that resource bundle (and the locale used to locate that resource bundle) in the FMT_LOCALIZATION_CONTEXT configuration setting.
|
<fmt:bundle>
|
Searches for a resource bundle identified with the required basename attribute, using the same search algorithm used by <fmt:setBundle>. That resource bundle is only used by <fmt:message> actions and formatting actions in the body of the <fmt:bundle> action.
|
<fmt:message>
|
Retrieves a localized message from a resource bundle. That message is sent to the current JspWriter, or if the var attribute is specified, the message is stored in a scoped variable.
<fmt:message> searches for a resource bundle in:
Its bundle attribute
Its enclosing <fmt:bundle> action
The FMT_LOCALIZATION_CONTEXT configuration setting
|
<fmt:param>
|
Specifies a single parameter for a compound message. That parameter is used by an enclosing <fmt:message> action.
|
<fmt:requestEncoding>
|
Sets the character encoding for an HTTP request. This action is necessary because most browsers do not specify the Content-Type header, making it impossible for applications to determine the encoding of request parameters that were encoded with a charset other than ISO-8859-1.
|
JSTL Internationalization Configuration Settings
The following configuration settings support JSTL internationalization:
FMT_LOCALE
FMT_FALLBACK_LOCALE
FMT_LOCALIZATION_CONTEXT
FMT_LOCALE
The FMT_LOCALE configuration setting is listed in Table 11.14.
Table 11.14. FMT_LOCALE
|
Name
|
javax.servlet.jsp.jstl.fmt.locale
|
Type
|
java.lang.String or java.util.Locale
|
Set by
|
<fmt:setLocale>, Deployment Descriptor, Config class
|
Used by
|
<fmt:bundle>, <fmt:setBundle>, <fmt:message>,<fmt:formatNumber>, <fmt:parseNumber>, <fmt:formatDate>, <fmt:parseDate>
|
The FMT_LOCALE configuration setting specifies a locale for both internationalization and formatting actions. If you set this configuration setting, internationalization and formatting actions will ignore your browser's locale preferences. See "<fmt:setLocale>" on page 496 for more information about the <fmt:setLocale> action, which is the only JSTL action that directly sets the FMT_LOCALE configuration setting.
You can also set the FMT_LOCALE configuration setting with a context initialization parameter or in a business component. See "Configuration Settings" on page 230 for more information on how to do that.
FMT_FALLBACK_LOCALE
The FMT_FALLBACK_LOCALE configuration setting is listed in Table 11.15.
Table 11.15. FMT_FALLBACK_LOCALE
|
Name
|
javax.servlet.jsp.jstl.fmt.fallbackLocale
|
Type
|
java.lang.String or java.util.Locale
|
Set by
|
Deployment Descriptor, Config class
|
Used by
|
<fmt:bundle>, <fmt:setBundle>, <fmt:message>,
<fmt:formatNumber>, <fmt:parseNumber>, <fmt:formatDate>, <fmt:parseDate>
|
In the quest for a resource bundle or a formatting locale, JSTL I18N and formatting actions will resort to the locale stored in the FMT_FALLBACK_LOCALE configuration setting if the user's preferred locales do not yield a resource bundle.
FMT_LOCALIZATION_CONTEXT
The FMT_LOCALIZATION_CONTEXT configuration setting is listed in Table 11.16.
Table 11.16. FMT_LOCALIZATION_CONTEXT
|
Name
|
javax.servlet.jsp.jstl.fmt.localizationContext
|
Type
|
java.lang.String or javax.servlet.jsp.jstl.fmt.LocalizationContext
|
Set by
|
<fmt:setBundle>, Deployment Descriptor, Config class
|
Used by
|
<fmt:message>, <fmt:formatNumber>, <fmt:parseNumber>, <fmt:formatDate>, <fmt:parseDate>
|
<fmt:message> actions retrieve localized messages from a resource bundle. That resource bundle is stored in a read-only object known as a localization context, which also keeps track of the locale that yielded the resource bundle. The localization context's resource bundle is used by <fmt:message> and its locale is used by JSTL formatting actions.
When a <fmt:message> action searches for a resource bundle, it turns to the FMT_LOCALIZATION_CONTEXT configuration setting if you don't specify the <fmt:message> bundle attribute and if the <fmt:message> action doesn't reside in the body of a <fmt:bundle> action. <fmt:setBundle> is the only JSTL action that sets the FMT_LOCALIZATION_CONTEXT configuration setting. You can temporarily override that configuration setting with <fmt:bundle>, which creates a localization context of its own. (<fmt:bundle> does not set the FMT_LOCALIZATION_CONTEXT configuration setting.)
The value of the FMT_LOCALIZATION_CONTEXT configuration setting can be a string representing a resource bundle base name, or it can be an instance of javax.servlet.jsp.jstl.fmt.LocalizationContext.
See "Localization Context Lookup" on page 268 for more information about <fmt:setBundle> and the FMT_LOCALIZATION_CONTEXT configuration setting.
JSTL Internationalization Actions
Configures a locale for <fmt:message> and formatting actions
|
Syntax:
<fmt:setLocale value [scope] [variant]/>
Description:
The <fmt:setLocale> action sets the FMT_LOCALE configuration setting, which is used by I18N and formatting actions to locate resource bundles and formatting locales. You specify the locale by setting the required value attribute, with a string or an instance of java.util.Locale.
Attributes:
|
value
|
String or java.util.Locale
|
A value that specifies a locale. That value can be a Locale object or a string consisting of a two-letter language code and an optional two-letter country code. The language and country codes can be separated by either a hyphen or an underscore.
|
variant
|
String
|
A string representing a vendor- or browser-specific variant, such as WIN for Windows or MAC for Macintosh.
|
scope
|
String
|
The scope of the scoped variable whose name is specified by the value attribute; default is page scope.
|
Constraints and Error Handling:
If you specify null or an empty string for the value attribute, the associated <fmt:setLocale> action will store the default locale in the javax.servlet.jsp.jstl.fmt.locale configuration variable.
If you specify an invalid value attribute, <fmt:setLocale> will throw an IllegalArgumentException.
In a Nutshell:
The <fmt:setLocale> action sets a locale for any action that establishes a localization context and disables browser-based locale settings for those actions. Place this action at the beginning of a JSP page, before any action that establishes a localization context.
You specify a locale with the value attribute, which can be a string or an instance of java.util.Locale. That string represents a language and, optionally, a country. The language and country are separated by a hyphen or an underscore; for example, you can specify value='es' for Spanish or either value='es-MX' or value='es_MX' for Mexican Spanish.
If a locale is stored in the FMT_LOCALE configuration variable, JSTL uses that locale for formatting actions and also to locate a resource bundle for <fmt:message> actions. The <fmt:setLocale> action, given a valid value attribute, stores a locale in that configuration variable, like this:
<fmt:setLocale value='en-US' scope='session'/>
Optionally, you can set the value of the FMT_LOCALE configuration setting in a business component, such as a servlet, life-cycle listener, custom action, or bean; for example, a custom action could set the locale for session scope like this:
import javax.servlet.jsp.jstl.core.Config;
...
Config.set(pageContext, Config.FMT_LOCALE,
new java.util.Locale("en-US"),
PageContext.SESSION_SCOPE);
...
The preceding code fragment, which uses the Config class to set the FMT_LOCALE configuration setting, is functionally equivalent to the <fmt:setLocale> action used above. You can also set a locale for your application by specifying a context initialization parameter in your deployment descriptor (WEB-INF/web.xml) for the FMT_LOCALE configuration setting like this:
<web-app>
...
<context-param>
<param-name>
javax.servlet.jsp.jstl.fmt.locale
</param-name>
<param-value>
en-US
</param-value>
</context-param>
...
</web-app>
Creates a localization context for <fmt:message> and JSTL formatting actions
|
Syntax:
<fmt:setBundle basename [var] [scope]/>
Description:
The <fmt:setBundle> action does three things:
Searches for a resource bundle, using the basename attribute.
Stores that resource bundle, along with the locale used to locate it, in a localization context.
Stores that localization context in the FMT_LOCALIZATION_CONTEXT configuration setting, or if you specify the var attribute, stores the localization context in a scoped variable whose name is specified by the var attribute.
Subsequently, <fmt:message> actions and formatting actions access the localization context: <fmt:message> uses its resource bundle to localize messages, whereas formatting actions use its locale to format and parse numbers, currencies, percents, and dates.
Attributes:
|
basename
|
String
|
The base name of a resource bundle; for example if a resource bundle is specified by the properties file com/acme/resources/Resources_fr.properties, then the base name is com.acme.resources.Resources.
|
var
|
String
|
The name of a scoped variable that references a localization context that contains a reference to the resource bundle loaded by the <fmt:setBundle> action.
|
scope
|
String
|
The scope of the variable whose name is specified by the var attribute, or if var is not specified, the scope of the FMT_LOCALIATION_CONTEXT configuration setting. The default scope is page.
|
Constraints and Error Handling:
If the basename attribute is null or empty or <fmt:setBundle> cannot find a resource bundle, <fmt:setBundle> creates an empty localization context, meaning a localization context with a null resource bundle and locale.
In a Nutshell:
You use the <fmt:setBundle> action to specify a resource bundle that <fmt:message> actions use to localize their messages. You specify a resource bundle base name with the basename attribute, like this:
<fmt:setBundle basename='messages' scope='request'/>
The <fmt:setBundle> action in the preceding line of code locates a resource bundle from information in the action's mandatory basename attribute (messages) and the user's preferred locale and stores that resource bundle in the FMT_LOCALIZATION_CONTEXT configuration setting for request scope. Subsequently, in the absence of other <fmt:setBundle> actions, <fmt:message> actions in the same request will use the messages resource bundle to localize their messages, as long as those <fmt:message> actions do not specify their bundle attribute.
You can also use <fmt:setBundle> to store a localization context in a scoped variable by specifying the var and scope attributes, like this:
<fmt:setBundle basename='messages' var='msgs' scope='request'/>
The <fmt:setBundle> action in the preceding line of code, like the first code fragment in this section, locates a resource bundle using the value of the action's mandatory basename attribute (messages) and stores that resource bundle in a localization context. The difference between the two uses of <fmt:setBundle> is that the preceding line of code stores the localization context in a scoped variable whose name is msgs. That scoped variable is stored in request scope. Subsequently, <fmt:message> actions in the same request can access that localization context like this:
<fmt:message key='login.page.title' bundle='${msgs}'/>
The <fmt:message> action in the preceding code fragment accesses the msgs localization context by specifying that scoped variable for the <fmt:message> bundle attribute.
If you specify the var attribute, but not the scope attribute, the localization context created by <fmt:setBundle> is stored in page scope.
Creates a localization context for <fmt:message> actions and JSTL formatting actions that reside in the body of the action
|
Syntax:
<fmt:bundle basename [prefix]>
body content, presumably with other I18N and formatting actions that use the
bundle specified with the mandatory basename attribute
</fmt:bundle>
Description:
The <fmt:bundle> action does three things:
Searches for a resource bundle, using the basename attribute
Stores that resource bundle in a localization context
Stores that localization context in the <fmt:bundle> action's tag handler
Subsequently, only <fmt:message> actions and formatting actions within the body of the <fmt:bundle> action will use the localization context created by the <fmt:bundle> action.
Attributes:
|
basename
|
String
|
The base name of a resource bundle; for example if a resource bundle is specified by the properties file com/acme/resources/Resources_fr.properties, then the base name is com.acme.resources.Resources.
|
prefix
|
String
|
A prefix that's prepended to message keys specified by <fmt:message> actions that reside in the body of the <fmt:bundle> action that specified the prefix attribute.
|
Constraints and Error Handling:
In a Nutshell:
The <fmt:bundle> action finds a resource bundle specified by the basename attribute and stores that resource bundle in a localization context. The localization context is used by <fmt:message> actions and formatting actions only within the body of the <fmt:bundle> action; for example,
<fmt:bundle basename='app'>
<fmt:message key='login.title'/>
<fmt:message key='login.welcome'/>
<fmt:formatNumber value='10000' type='currency'/>
</fmt:bundle>
In the preceding code fragment, both the <fmt:message> actions and the <fmt:formatNumber> action use the localization context created by their enclosing <fmt:bundle> action. The <fmt:message> actions look up localized messages in the localization context's resource bundle, whereas the <fmt:formatNumber> action uses the localization context's locale as its formatting locale.
You can also specify a prefix for <fmt:bundle> actions that have a body. Prefixes are used for long keys; for example, the code fragment below specifies a prefix:
<fmt:bundle basename='app' prefix='com.Acme.application.'>
<fmt:message key='login.title'/>
<fmt:message key='login.welcome'/>
</fmt:bundle>
Prefixes are prepended to message keys for <fmt:message> actions in the body of the <fmt:bundle> action, so the preceding code fragment is equivalent to the code fragment listed below:
<fmt:bundle basename='app'>
<fmt:message key='com.Acme.application.login.title'/>
<fmt:message key='com.Acme.application.login.welcome'/>
</fmt:bundle>
Retrieves a localized message from a resource bundle
|
Syntax:
Syntax #1: Without a body
<fmt:message key [bundle] [var] [scope]/>
Syntax #2: With a body that specifies message parameters
<fmt:message key [bundle] [var] [scope]>
<fmt:param> actions
</fmt:message>
Syntax #3: With a body that specifies a message key and, optionally, message parameters
<fmt:message [bundle] [var] [scope]>
key
optional <fmt:param> actions
</fmt:message>
Description:
The <fmt:message> action extracts a localized message from a resource bundle and sends it to the current JspWriter (which in most cases displays the message in the browser) or stores it in a scoped variable specified with the var attribute, and optionally, the scope attribute.
Attributes:
|
key
|
String
|
The message key used by <fmt:message> to extract localized messages from a resource bundle.
|
bundle
|
LocalizationContext
|
<fmt:message> actions extract localized messages from a resource bundle stored in an instance of LocalizationContext.
|
var
|
String
|
The name of a scoped variable that references a localized message.
|
scope
|
String
|
The scope of the scoped variable whose name is specified by the var attribute; default is page scope.
|
Constraints and Error Handling:
If you specify the scope attribute, you must also specify the var attribute.
If you specify a null or empty key, the <fmt:message> action will generate an error message of the form ??????.
If the <fmt:message> action cannot locate a valid localization context, an error message of the form ???<key>??? is generated, where <key> represents the value of the key attribute.
In a Nutshell:
You can specify message keys with the key attribute, like this�
<fmt:message key='messages.loginPage.title'/>
�or within the body of <fmt:message> actions, like this:
<fmt:message>
messages.loginPage.title
</fmt:message>
The resource bundle used by the <fmt:message> actions in the two preceding code fragments is the resource bundle stored in the localization context that is stored in the FMT_LOCALIZATION_CONTEXT configuration setting (See "<fmt:setBundle>" on page 498 for more information about that configuration setting). You can also specify a localization context explicitly, with the bundle attribute, like this:
<fmt:message key='msgs.greeting' bundle='${aLocalizationContext}'/>
The <fmt:message> action in the preceding code fragment specifies a localization context stored in a scoped variable named aLocalizationContext. That localization context can be created with <fmt:setBundle> or a business component, such as a servlet, life-cycle listener, or custom action.
If a <fmt:message> action resides in the body of a <fmt:bundle> action, that <fmt:message> action extracts localized messages from the resource bundle stored in the localization context established by its enclosing <fmt:bundle> action. If the enclosing <fmt:bundle> action specifies a prefix attribute, enclosed <fmt:message> actions prepend that prefix to their message keys. See "<fmt:bundle>" on page 500 for more information about the <fmt:bundle> action.
<fmt:message> actions can also display compound messages. A compound message is a message that contains parameters that are specified at runtime. Those parameters are specified with <fmt:param>, like this:
<jsp:useBean id='now' class='java.util.Date'/>
<fmt:message key='footer.messages.todaysDate'>
<fmt:param value='${now}'/>
</fmt:message>
The preceding code fragment specifies a date as a parameter to the compound message corresponding to footer.messages.todaysDate. That compound message is specified like this in a properties file:
footer.messages.todaysDate=Today is: {0}
Supplies a parameter for an enclosing <fmt:message>
|
Syntax:
Syntax #1: Without a body
<fmt:param value/>
Syntax #2: With a body
<fmt:param>
value
</fmt:param>
Description:
The <fmt:param> action specifies a parameter for an enclosing <fmt:message> action.
Attributes:
|
value
|
Object
|
This attribute specifies a parameter for an enclosing <fmt:message> action. You can also specify parameters in the body of <fmt:param> actions.
|
Constraints and Error Handling:
In a Nutshell:
Each <fmt:param> action specifies a single parameter for a compound message. That compound message is retrieved from a resource bundle by an enclosing <fmt:message> action. The first <fmt:param> action contained in the body of a <fmt:message> action specifies the first parameter for that compound message, the second <fmt:param> action specifies the second parameter, and so on; for example, for this compound message in a resource bundle�
message=There are {0} parameters in this message: the second is \
{1} and the third is {2}.
� if you specify parameters like this�
<fmt:message key='message'>
<fmt:param value='THREE'/>
<fmt:param value='THE SECOND PARAMETER'/>
<fmt:param value='THE THIRD PARAMETER'/>
</fmt:message>
�then the <fmt:message> action in the preceding code fragment will generate the following text: There are THREE parameters in this message: the second is THE SECOND PARAMETER and the third is THE THIRD PARAMETER.
You do not have to specify a <fmt:param> action for every parameter in a compound message, but it is recommended that you do so. If you do not specify a <fmt:param> action for every parameter, no substitution is made for unspecified parameters; for example, if you specify only two parameters for the compound message in the code fragment above, like this�
<fmt:message key='message'>
<fmt:param value='TWO'/>
<fmt:param value='THE SECOND PARAMETER'/>
</fmt:message>
�then the <fmt:message> action in the preceding code fragment will generate the following text: There are TWO parameters in this message: the second is THE SECOND PARAMETER and the third is {2}.
JSP 1.2 does not support JSTL Expression Language (EL) expressions, so you cannot specify an EL expression in the body of a <fmt:param> action (or any action, for that matter). For example, that means you can do this:
<fmt:param value='${param.amount}'/>
but you cannot do this:
<fmt:param>
${param.amount}
</fmt:param>
Instead, you must do this:
<fmt:param>
<c:out value='${param.amount}'/>
</fmt:param>
JSP 2.0 will support the JSTL Expression Language, which means you will be able to specify EL expressions directly within the body of a <fmt:param> action.
Sets the request's character encoding
|
Syntax:
<fmt:requestEncoding [value]/>
Description:
The <fmt:requestEncoding> action sets an HTTP request's character encoding.
Attributes:
|
value
|
String
|
The character encoding that the servlet container uses to decode request parameters.
|
In a Nutshell:
Imagine that you have two JSP pages: one that contains an HTML form, which we'll call the form page, and another that is specified as the form's action, which we'll call the action page. Now imagine that your form page is localized for Chinese, and that you set the response charset for that page to Mainland Chinese (charset=GB2312).
When the form is submitted, the action page is loaded and accesses the request parameters to find out what the user entered in the form. Will those request parameters be decoded properly? The answer for most browsers is no, because most browsers do not specify the Content-Type request header and therefore the application cannot determine the request encoding. To force your browser to properly decode those request parameters, you must specify the action page's request encoding so that it matches the form page's response encoding. That's exactly what <fmt:requestEncoding> does. All you have to do is use the <fmt:requestEncoding> action at the top of your action page before you access request parameters.
There are two ways to use the <fmt:requestEncoding> action. If you know the response encoding of the form page, you can specify that charset with the <fmt:requestEncoding> action's value attribute. If you don't know the response encoding of the form page, don't specify the value attribute and the <fmt:requestEncoding> action will figure out what to do.
At this point you may wonder how the <fmt:requestEncoding> action knows the charset to use if you don't specify it with the value attribute. The answer is that <fmt:requestEncoding> retrieves that charset from a session attribute. That attribute was created by the JSTL internationalization actions in the form page; therefore, for <fmt:requestEncoding> to work properly, you must use JSTL internationalization actions in the form page if you don't specify the <fmt:requestEncoding> action's value attribute.
Exposed Classes
JSTL exposes two classes for internationalization:
The LocaleSupport class lets you extract localized messages from resource bundles; LocalizationContext objects store a resource bundle and the locale used to locate that resource bundle.
A class that lets you retrieve localized messages from a resource bundle
|
Definition:
class LocaleSupport {
public static String getLocalizedMessage(PageContext, String key)
public static String getLocalizedMessage(PageContext, String key,
String basename)
public static String getLocalizedMessage(PageContext, String key,
Object[] args)
public static String getLocalizedMessage(PageContext, String key,
Object[] args, String basename)
}
Description:
The four methods of the LocaleSupport class let you extract localized messages from resource bundles, just like <fmt:message> actions do. You can use those methods in a custom action; for example see "I18N Custom Actions" on page 293 for a discussion of a custom action that uses the LocaleSupport class to localize error messages.
A class that stores a resource bundle and a locale
|
Definition:
class LocalizationContext {
public LocalizationContext()
public LocalizationContext(ResourceBundle bundle, Locale locale)
public LocalizationContext(ResourceBundle bundle)
public Locale getLocale()
public ResourceBundle getResourceBundle()
}
Description:
In all likelihood, you will never have to deal with an instance of LocalizationContext directly, although you may want to create one in a business component, such as a servlet, servlet filter, or life-cycle listener.
The LocalizationContext class provides three constructors. The no-argument constructor creates an empty LocalizationContext instance with a null resource bundle and a null locale. JSTL uses that constructor when <fmt:bundle> or <fmt:setBundle> cannot find a resource bundle.
You can also create a localization context with a resource bundle and a locale. The constructor that takes those two arguments simply assigns the resource bundle and locale to the localization context's member variables. The constructor that just takes a resource bundle stores the resource bundle and its locale in the localization context.
|