I18N-Capable Formatting Tags: Functional Description

<fmt:locale>
<fmt:timeZone>
<fmt:bundle>
<fmt:message>
<fmt:messageFormat>
<fmt:messageArg>
<fmt:formatNumber>
<fmt:parseNumber>
<fmt:formatDate>
<fmt:parseDate>
<fmt:exception>
<fmt:requestEncoding>


1. Introduction

With the explosion of application development based on web technologies, and the deployment of such applications on the Internet, applications must be able to adapt to the languages and formatting conventions of their clients. This means that page authors must be able to tailor any locale-specific page content according to the conventions of the client's language and cultural formatting conventions. For example, the number 345987.246 should be formatted as 345 987,246 for French, 345.987,246 for German, and 345,987.246 for clients in the U.S.

The process of designing an application (or page content) so that it can be adapted to various languages and regions without requiring any engineering changes is known as internationalization, or I18N for short. Once a web application has been internationalized, it can be adapted for a number of regions or languages by adding locale-specific components and translating text. This process is known as localization.

There are two approaches to internationalizing a web application:

This proposal supports both approaches. It defines two sets of tags: I18N tags, whose purpose is to assist page authors with creating internationalized page content that can be localized into any locale available in the JSP container  (this addresses the second approach), and formatting tags, which allow various data elements such as numbers, currencies, dates and times to be formatted and parsed in a locale-sensitive or customized manner (this may be used in either approach).

2. Locale selection

JSTL supports both browser- and application-based locales, which are discussed in more detail.

2.1 Browser-based locales

By default, browser-sensing capabilities for locales are enabled. This means that the client determines (via its browser settings) which locale to use, and allows page authors to cater to the language preferences of their clients. For example, a shopping application may want to greet its customers in their language, and it may even want to label its GUI components in that language (for example, a cancel button would be labelled Cancel  for English and Abbrechen for German speaking customers).

Any action that requires a locale first calls the ServletRequest.getLocales() method on the incoming request, which provides a list, in order of preference, of the locales that the client wants to use. This list is processed differently depending on whether the action is an I18N or a formatting tag.

2.1.1 Resource bundle locale
Any I18N actions that acquire a resource bundle based on its base name (that is, the <bundle> action which (always) takes a basename attribute and the <message> action which may use the default resource bundle base name defined by the javax.servlet.jsp.jstl.i18n.basename attribute) determine the best matching locale by comparing the list of client locales against the list of available locales for the resource bundle in question, as follows:

For each of the client's preferred locales (in order of preference), the action checks if there is a matching locale for the resource bundle in question, by passing the resource bundle's base name and the client's requested locale to the java.util.ResourceBundle.getBundle() method.

ResourceBundle.getBundle() implements the following search algorithm for resource bundles: It first appends the name of the requested client locale to the given base name and searches for a resource bundle with that name. A resource bundle may be backed by a class or a properties file. If no resource bundle with that name exists (and the requested locale has both a language and a country component), ResourceBundle.getBundle() appends just the requested locale's language name to the given base name and searches for a resource bundle with that name. If no resource bundle with that name exists, and the requested locale differs from the default locale of the container's Java runtime, ResourceBundle.getBundle() continues the search by appending the name of the container's default locale to the given base name. If no resource bundle with that name exists (and the container's default locale has both a language and a country component), ResourceBundle.getBundle() appends just the language component of the container's default locale to the given base name. If there still is no match, ResourceBundle.getBundle() searches for a resource bundle with just the given base name (without any locale name appended to it). If there still is no match, ResourceBundle.getBundle() raises a MissingResourceException, which is caught by the action's tag handler implementation and interpreted as if the resource bundle with the given base name does not exist for the requested client locale.

As a result of this search algorithm for resource bundles, the locale of the resource bundle returned by ResourceBundle.getBundle() may either match both the country and language components of the requested locale ("exact match"), only its language ("language match"), or neither (depending on the container's default locale). Note that the locale of the returned resource bundle may not even have any language and country components. An exact match may exist only if the client's preferred locale specifies a country.

If there is an exact match, it is used, and no further client locales are checked. Otherwise, all remaining client locales are checked, and the first language match is used. If no such match exists, the fallback locale from the javax.servlet.jsp.jstl.i18n.fallbackLocale scoped attribute, which is searched in the page, request, session (if valid), and application scope(s) (in this order), or context configuration parameter (see Section 17.2) is used. If no fallback locale has been specified, the default locale of the container's Java runtime is used. If no resource bundle (with the given base name) exists for the fallback or the container's default locale, an error message of the form "???<key>???" (where <key> is the name of the message key to be looked up) is returned (see Section 8).

The behavior is implementation-defined if the set of available resource bundles changes during execution of the page. Implementations may thus cache the best matching locale for a given resource bundle when one is found.

The following example assumes that a message key needs to be looked up in a resource bundle with base name "MyResources" which is available only in the US-English ("en-US") locale. Furthermore, it assumes that the client's only preferred locale is British-English ("en_UK"). Passing the requested base name ("MyResources") along with the preferred locale ("en-UK") to the ResourceBundle.getBundle() method will result in the following search order of resource bundles, assuming that the container's default locale is set to English ("en"):

    (class) MyResources_en_UK              (exact match)
    (file)  MyResources_en_UK.properties   (exact match)
    (class) MyResources_en                 (language match)
    (file)  MyResources_en.properties      (language match)
    (class) MyResources                    (no match)
    (file)  MyResources.properties         (no match)

Since MyResources_en_US is never searched in this example, an error message of the form "???<key>???" (see above) is returned to the client.

With the container's default locale set to "en-US", the complete search order of ResourceBundle.getBundle() will be as follows:

    (class) MyResources_en_UK              (exact match)
    (file)  MyResources_en_UK.properties   (exact match)
    (class) MyResources_en                 (language match)
    (file)  MyResources_en.properties      (language match)
    (class) MyResources_en_US              (language match)
    (file)  MyResources_en_US.properties   (language match)
    (class) MyResources_en                 (language match)
    (file)  MyResources_en.properties      (language match)
    (class) MyResources                    (no match)
    (file)  MyResources.properties         (no match)

In this case, a language match with MyResources_en_US is found, which is returned. Since the client did not specify any additional preferred locales, the message key is looked up in this resource bundle.

If the client's preferred locales were "ja", "en-UK", "en-US", "en-CA", and "fr" (in this order), and the available ones (for the resource bundle in question) were "en" and "fr", the best match would be "en". Likewise, if the available ones were "en", "en-US", and "fr", then the best match would be "en-US".

2.1.2 Formatting locale
This is the locale used by the <formatNumber>, <parseNumber>, <formatDate>, and <parseDate> formatting actions.

If the formatting action is enclosed within a <bundle> action, the locale of the parent bundle is used as the formatting locale.

Otherwise, if the javax.servlet.jsp.jstl.i18n.basename attribute is set, the best matching locale for that base name is determined (according to the algorithm described in Section 2.1.1) and used as the formatting locale.

Otherwise, the formatting action checks, for each of the client's preferred locales (in order of preference), if there is a matching locale available. The <formatNumber> and <parseNumber>, and the <formatDate> and <parseDate> actions determine the available locales by calling java.text.NumberFormat.getAvailableLocales() and java.text.DateFormat.getAvailableLocales(), respectively. If there is an exact match (that is, a client's preferred locale specifies a country and matches both the language and country of an available locale), it is used, and no further client locales are checked. Otherwise, the first match on language is used. If no such match exists, the default locale of the JSP container's Java runtime is used. Once the best matching locale has been determined, it is cached, so that any subsequent formatting actions on the same page do not have to determine it again.

2.2. Application-based locales

The browser-sensing capabilities for locales may be disabled by setting the javax.servlet.jsp.jstl.i18n.locale scoped attribute or context configuration parameter (see Section 17.1). The scoped attribute is searched in the page, request, session (if valid), and application scope(s) (in this order), and may be set directly by application code for any of these scopes. For example, an application might let its users pick their preferred locale and then set the javax.servlet.jsp.jstl.i18n.locale attribute accordingly. Alternatively, the <locale> action may be used to set this attribute with page scope only. This may be useful in the case where a client's preferred locale is retrieved from a database (using the JSTL database tags)and installed on the page using the <locale> tag.

3. Response encoding

Any I18N-capable formatting action defined in this Functional Description that deals with locales sets the response's locale by calling ServletResponse.setLocale() with the locale determined according to the logic described in Section 2. This assumes that the response is buffered with a big enough buffer size, since ServletResponse.setLocale() and ServletResponse.setContentType() must be called before ServletResponse.getWriter() in order for the specified locale or charset to affect the construction of the writer.

More specifically, the response's setLocale() method is always called by the <locale> action. In addition, it is called by the following actions if browser-sensing capabilities for locales are enabled (that is, in the absence of the javax.servlet.jsp.jstl.i18n.locale scoped attribute or context configuration parameter):

After an action has called ServletResponse.setLocale(), it determines the character encoding associated with the locale (by calling ServletResponse.getCharacterEncoding()) and stores it in the javax.servlet.jsp.jstl.i18n.request.charset session attribute. This attribute may be used by the <requestEncoding> action (see Section 16) in a page invoked by a form included in the response to set the request charset to the same as the response charset. This makes it possible for the container to decode the form parameter values properly, since browsers typically encode form field values using the response's charset.

4. Time zone

The javax.servlet.jsp.jstl.i18n.timeZone JSP attribute specifies the time zone in which any time information formatted using the <formatDate> action is represented. This allows any time information on a page to be tailored to the preferred time zone of its clients, which is useful if the server hosting the page containing the time information and its clients reside in different time zones. Page authors could be advised to always use the "long" time format which includes the time zone, but that would still require clients to convert the formatted time into their own time zone.

The javax.servlet.jsp.jstl.i18n.timeZone attribute may be set directly by application code for any of the JSP scopes. For example, an application might let its users pick their preferred time zone and then set the javax.servlet.jsp.jstl.i18n.timeZone attribute accordingly. Alternatively, the <timeZone> action may be used to set the javax.servlet.jsp.jstl.i18n.timeZone attribute for the current page context. This may be useful in the case where a client's preferred time zone is retrieved from a database (using the JSTL database tags) and imported into the page using the <timeZone> tag.

The javax.servlet.jsp.jstl.i18n.timeZone attribute is searched in the page, request, session (if valid), and application scope(s) (in this order). If not found, the JSP container's time zone is used.

5. <locale>

The <locale> action may be used to set or override the javax.servlet.jsp.jstl.i18n.locale scoped attribute with the locale specified by the value attribute in the scope given by the scope attribute (default: "page").

The locale specified by the value attribute must contain a two-letter (lower-case) language code (as defined by ISO-639), and may contain a two-letter (upper-case) country code (as defined by ISO-3166). Language and country codes must be separated by hyphen ('-') or underscore ('_').

Optionally, a (vendor- or browser-specific) variant may be specified using the variant attribute. See the java.util.Locale javadocs for more information on variants.

Example:

    <fmt:locale value="en-US" variant="UNIX"/>

By using this action, the browser-sensing capabilities for locales described in Section 2 of this Functional Description are disabled. This means that if this action is being used, it should be declared at the beginning of a page, before any other I18N-capable formatting tags. Otherwise, a different locale might be used up to the position in the page where the <locale> action is specified.

6. <timeZone>

The <timeZone> action establishes the time zone (specified via the value attribute) to be used by any nested <formatDate> actions:

    <fmt:timeZone value="America/Los_Angeles">
      <fmt:formatDate type="time"/>
    </fmt:timeZone>

The time zone may be specified as either an abbreviation (such as "PST"), a full name (such as "America/Los_Angeles"), or a custom format (such as "GMT-8:00). See java.util.TimeZone.getTimeZone() for more details on the supported time zone formats.

The var attribute may be used to expose the time zone as a JSP-scoped attribute of type java.util.TimeZone (with visibility AT_END), so that it can be referenced by any subsequent <formatDate> actions that are not nested inside a <timeZone> action and take a timeZone attribute:

    <fmt:timeZone value="America/Los_Angeles" var="losAngelesTimeZone"/>
    <fmt:formatDate type="time" timeZone="$losAngelesTimeZone"/>

An empty <timeZone> action that is specified without the var attribute can be used to set or override the javax.servlet.jsp.jstl.i18n.timeZone attribute in the scope given by the scope attribute (default: "page"), thereby making its time zone the (new) default in that scope:

    <fmt:timeZone value="America/Los_Angeles"/>
    <fmt:formatDate type="time"/>

7. <bundle>

The <bundle> action loads the resource bundle whose base name is specified via the basename attribute:

    <fmt:bundle basename="com.acme.labels.ButtonLabels">
      <user-of-bundle/>
    </fmt:bundle>

The resource bundle's locale is determined according to Section 2 of this Functional Description.

The var attribute may be used to expose the resource bundle as a JSP-scoped attribute of type java.util.ResourceBundle (with visibility AT_END), so that it can be referenced by any subsequent <message> actions that take a bundle attribute:

    <fmt:bundle basename="com.acme.labels.ButtonLabels" var="buttonLabels"/>
    <fmt:message key="Submit" bundle="$buttonLabels"/>

Exposing a resource bundle via the var attribute is useful if the bundle needs to be accessed multiple times.

An empty <bundle> action that is specified without the var attribute can be used to set or override the javax.servlet.jsp.jstl.i18n.basename attribute in the scope given by the scope attribute (default: "page"), thereby making its base name the (new) default in that scope:

    <fmt:bundle basename="com.acme.labels.ButtonLabels"/>
    <fmt:message key="Submit"/>

The prefix attribute is provided as a convenience for very long key names: Its value is prepended to any message key (see the <message> action) that is to be looked up in the resource bundle that was loaded by this action.

8. <message>

The <message> action retrieves the localized message corresponding to a given message key.

The message key may be specified via the key attribute; if missing, it is read from the tag's body content.

The resource bundle in which to look up the message key may be given by the bundle attribute. If this attribute is missing, and the <message> action is nested inside a <bundle> tag, the resource bundle to use is taken from the enclosing <bundle> tag. Otherwise, the resource bundle with the default base name given by the javax.servlet.jsp.jstl.i18n.basename attribute is used,  which is searched in the page, request, session (if valid), and application scope(s) (in this order).

The <message> action outputs its result to the current JspWriter object, unless the var attribute is specified, in which case the result is stored in the named JSP attribute.

Example:

        <fmt:message key="Welcome"/>                                <%-- Key is looked up in default bundle --%>
    <fmt:bundle basename="Errors" var="errorBundle"/>
    <fmt:bundle basename="Greetings">
      <fmt:message key="Welcome"/>                              <%-- Key is looked up in parent <bundle> tag --%>
      <fmt:message key="WrongPassword" bundle="$errorBundle"/>  <%-- Key is looked up in errorBundle --%>
    </fmt:bundle>

If the given key is not found in the resource bundle, or a resource bundle with the given base name does not exist, a message is logged to the servlet context, and an error message of the form "???<key>???" (where <key> is the name of the undefined key) is output to the current JspWriter object.

If the message corresponding to the given key is compound, that is, contains one or more variables, it may be supplied with argument values for these variables via the messageArgs attribute or one or more <messageArg> subtags (one for each argument value). This procedure is referred to as parametric replacement. Parametric replacement takes place in the order of the argument values given via the messageArgs attribute or the <messageArg> subtags. If the message is compound, but neither a messageArgs attribute nor any <messageArg> subtags are specified, the message is left unmodified. Specifying a <message> tag with both a messageArgs attribute and one or more <messageArg> subtags causes a translation error.

If the parent <bundle> action specifies a prefix attribute, its value is prepended to any key names to be looked up in that bundle. For example, using the prefix attribute, the key names in:

    <fmt:bundle basename="Labels">
      <fmt:message key="com.acme.labels.firstName"/>
      <fmt:message key="com.acme.labels.lastName"/>
    </fmt:bundle>

may be abbreviated to:

    <fmt:bundle basename="Labels" prefix="com.acme.labels.">
      <fmt:message key="firstName"/>
      <fmt:message key="lastName"/>
    </fmt:bundle>

9. <messageFormat>

The <messageFormat> action performs parametric replacement on a given pattern string , using the runtime's default locale.

The pattern string may be specified via the value attribute; if missing, it is read from the tag's body content.

The argument values for parametric replacement may be supplied via the messageArgs attribute or one or more <messageArg> subtags (one for each parameter in the pattern). Parametric replacement takes place in the order of the argument values given via the messageArgs attribute or the <messageArg> subtags. If neither a messageArgs attribute nor any <messageArg> subtags are specified, the given pattern is left unmodified. Specifying a <messageFormat> tag with both a messageArgs attribute and one or more <messageArg> subtags causes a translation error.

The result is output to the current JspWriter object, unless the var attribute is given, in which case it is stored in the named JSP attribute.

The <messageFormat> action is useful if a pattern needs to be supplied from sources other than resource bundles, or if a pattern extracted from a resource bundle needs to be used multiple times.

For example, when displaying a list of products, the same internationalized message (pattern) would be used to display the price, but rather than looking up the same pattern for every single product, the pattern could be looked up once (using the <message> action) and then passed in to the <messageFormat> action for each product, as follows:

    <fmt:bundle basename="..." var="i18n"/>
    <fmt:message key="store.product.price" bundle="$i18n" var="priceMsg"/>
    <c:forEach ...>
      ... <fmt:messageFormat value="$priceMsg">...</fmt:messageFormat>
    </c:forEach>

instead of the less efficient alternative:

    <fmt:bundle basename="..." var="i18n"/>
    <c:forEach ...>
      ... <fmt:message key="store.product.price" bundle="$i18n">...</fmt:message>
    </c:forEach>

10. <messageArg>

The <messageArg> action provides a single argument (for parametric replacement) to the compound message or pattern in its parent <message> or <messageFormat> action, respectively.

One <messageArg> action must be specified for each variable in the compound message or pattern. Parametric replacement takes place in the order of the <messageArg> tags.

The argument value can be specified either via the value attribute:

    <fmt:message key="Welcome">
      <fmt:messageArg value="$dateArg"/>
    </fmt:message>
or inline via the tag's body content:

    <fmt:message key="Welcome">
      <fmt:messageArg>
        <acme:doIt .../>
      </fmt:messageArg>
    </fmt:message>

11. <formatNumber>

The <formatNumber> action allows the formatting of numbers, currencies, and percentages, using predefined or customized formatting styles.

The numeric value to be formatted may be specified via the value attribute; if missing, it is read from the tag's body content.

Depending on the value of the type attribute, which must be one of "number", "currency", or "percent" (default: "number"), the given numeric value is formatted as a number, currency, or percentage, respectively, using the default formatting pattern for numbers (currencies, percentages) of the page's locale, which is determined according to Section 2 of this Functional Description.

The result is output to the current JspWriter object, unless the var attribute is given, in which case it is stored (as a string) in the named JSP attribute.

Example: The output of

    <fmt:formatNumber value="9876543.21" type="currency"/>

varies with the page's locale (given in parentheses), as follows:

    9 876 543,21 F   (fr_FR)
    9.876.543,21 DM  (de_DE)
    $9,876,543.21    (en_US)

When formatting the given value as a number, the predefined formatting pattern of the page's locale can be overridden by using the pattern attribute, allowing page authors to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator of the formatted number. The given pattern string must follow the Number Format Pattern Syntax  specified in the tutorial trail on internationalization at java.sun.com.

For example, a pattern of ".000" will cause any numeric value formatted with it to be represented with 3 fraction digits, adding trailing zeros if necessary, so that

    <fmt:formatNumber value="12.3" pattern=".000"/>

will output "12.300".

Likewise, a pattern of "#,#00.0#" specifies that any numeric value formatted with it will be represented with a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 fraction digits, with every 3 integer digits grouped. Applied to "123456.7891", as in:

    <fmt:formatNumber value="123456.7891" pattern="#,#00.0#"/>

the formatted output will be "123,456.79" (note that rounding is handled automatically).

The value and pattern attributes accept both string literals and EL values.

If the numeric value to be formatted is given as a string literal, it is first parsed into an instance of java.lang.Number according to the default pattern of the locale specified by the parseLocale attribute. In the absence of this attribute, the English (en) locale is used. If the numeric string uses a pattern different from the parsing locale's default, it must be parsed using the <parseNumber> action.

The type attribute accepts (case-insensitive) literals only, causing an error at translation-time validation if the specified literal is illegal.

The pattern attribute may be used only when formatting numbers (that is, if the type attribute is missing or is equal to "number"). Using it with a type attribute equal to "currency" or "percent" causes a translation-time error.

12. <parseNumber>

The <parseNumber> action may be used for parsing numbers, currencies, and percentages.

The numeric string to be parsed may be specified via the value attribute; if missing, it is read from the tag's body content.

Depending on the value of the type attribute, which must be one of "number", "currency", or "percent" (default: "number"), the given numeric string is parsed as a number, currency, or percentage, respectively, using the default formatting pattern for numbers (currencies, percentages) of the locale specified by the parseLocale attribute. If the parseLocale attribute is missing, the page's locale is used, which is determined according to Section 2 of this Functional Description.

If the number specified via the value attribute uses a format different from the page locale's default, the pattern required to parse it may be specified using the pattern attribute.

If the var attribute is given, the parsing result (of type java.lang.Number) is stored in the named JSP attribute.  Otherwise, it is output to the current JspWriter object using java.lang.Number.toString().

The value and pattern attributes accept both literals and EL values, whereas the type attribute accepts (case-insensitive) literals only, causing an error at translation-time validation if the specified literal is illegal.

The pattern attribute may be used only when parsing numbers (that is, if the type attribute is missing or equals "number"). Using it with a type attribute equal to "currency" or "percent" causes a translation-time error.

13. <formatDate>

The <formatDate> action allows the formatting of dates and times using predefined or customized formatting styles.

Depending on the value of the type attribute, which must be one of "time", "date", or "both" (default: "date"), only the time, the date, or both the time and date components of the date specified via the value attribute are formatted, using one of the predefined formatting styles for dates (specified via the dateStyle attribute) and times (specified via the timeStyle attribute) of the page's locale, which is determined according to Section 2 of this Functional Description.  Legal values for the dateStyle and timeStyle attributes are "default", "short", "medium ", "long", and "full" (default: "default").

If the value attribute is missing, the current date and time are used.

Any time information is represented in the time zone given by the timeZone attribute.  If this attribute is missing, and the <formatDate> action is nested inside a <timeZone> tag, the time zone to use is taken from the enclosing <timeZone> tag. Otherwise, the default time zone given by the javax.servlet.jsp.jstl.i18n.timeZone attribute is used, which is searched in the page, request, session (if valid), and application scope(s) (in this order). If not found, the JSP container's time zone is used.

The action's result is output to the current JspWriter object, unless the var attribute is given, in which case it is stored (as a string) in the named JSP attribute.

Example: Assuming a current date of Oct 22, 2001 and a current time of 4:05:53 PM,

    <fmt:formatDate timeStyle="long" dateStyle="long"/>

will output

    October 22, 2001 4:05:53 PM PDT

for the U.S. and

    22 octobre 2001 16:05:53 GMT-07:0

for the French locale.

Page authors may also apply a customized formatting style for their times and dates by specifying the pattern attribute. The specified formatting pattern must use the Date Format Pattern Syntax specified in the tutorial trail on internationalization at java.sun.com.

Example: Assuming the same current date and time as in the above example, the output of

    <fmt:formatDate pattern="EEE, MMM d, ''yy"/>

will be

    Mon, Oct 22, '01

for the U.S. locale.

The value and pattern attributes accept both string literals and EL values (which must evaluate to objects of type java.util.Date in the case of the value attribute).

If the input to the value attribute is a string literal, it is first parsed into an instance of java.util.Date according to the default formatting style for dates of the parsing locale specified by the parseLocale attribute, that is, it is parsed in a fashion equivalent to using a <parseDate> action with type equal to "date" (its default value) and dateStyle equal to "default" (its default value). In the absence of the parseLocale attribute, the English (en) locale is used as the parsing locale. If the string in the value attribute uses a formatting style for dates different from the parsing locale's default, or includes a time component, it must first be parsed using a <parseDate> action whose parsing result can then be supplied to a <formatDate> action for formatting.

The type, timeStyle, and dateStyle attributes take (case-insensitive) literals only, causing an error at translation-time validation if the specified literal is illegal.

14. <parseDate>

The <parseDate> action may be used for parsing date and time strings.

The date string to be parsed may be specified via the value attribute; if missing, it is read from the tag's body content.

Depending on the value of the type attribute, which must be one of "time", "date", or "both" (default: "date"), the given date string is expected to contain only a time, a date, or both a time and date component, respectively. It is parsed according to one of the predefined formatting styles for dates (specified via the dateStyle attribute) and times (specified via the timeStyle attribute) of the locale specified by the parseLocale attribute. If the parseLocale attribute is missing, the page's locale is used, which is determined according to Section 2 of this Functional Description. Legal values for the dateStyle and timeStyle attributes are "default", "short", "medium ", "long", and "full" (default: "default").

If the given date string uses a different format, the pattern required to parse it may be specified via the pattern attribute.

If the given time information does not specify a time zone, it is interpreted in the time zone given by the timeZone attribute.  If this attribute is missing, and the <parseDate> action is nested inside a <timeZone> tag, the time zone is taken from the enclosing <timeZone> tag. Otherwise, the default time zone given by the javax.servlet.jsp.jstl.i18n.timeZone attribute is used, which is searched in the page, request, session (if valid), and application scope(s) (in this order). If not found, the JSP container's time zone is used.

If the var attribute is given, the parsing result (of type java.util.Date) is stored in the named JSP attribute. Otherwise, it is output to the current JspWriter object using java.util.Date.toString().

The value and pattern attributes accept both literals and EL values. The type,timeStyle, and dateStyle attributes take (case-insensitive) literals only, causing an error at translation-time validation if the specified literal is illegal.

15. <exception>

The <exception> action may be used to display the exception given by the value attribute in its localized form:

    <fmt:exception value="$exception" bundle="$errorMessages"/>

If no value attribute is given, and this action is used in an error page, the exception of the error page is used.

Developers may designate an exception as localizable by having it implement the javax.servlet.jsp.jstl.i18n.LocalizableException interface, which is defined as follows:

    public interface LocalizableException {

        /**
         * Returns the exception's message key from which the exception's
         * localized message is derived via a resource bundle lookup.
         */
        public String getMessageKey();

        /**
         * Returns the arguments for parametric replacement on the exception's
         * localized message.
         */
        public Object[] getMessageArgs();
    }

If the given exception is not an instance of this interface, the <exception> action uses its fully qualified class name as the key to look up in the resource bundle for exception messages.

Otherwise, the <exception> action uses the return value of the exception's getMessageKey() method as the key . If getMessageKey() returns null, the exception's fully qualified class name is used as the key.

The key is looked up in the resource bundle given by the bundle attribute. If this attribute is missing, and the <exception> action is nested inside a <bundle> tag, the resource bundle to use is taken from the enclosing <bundle> tag. Otherwise, the default resource bundle for exception messages, whose default base name is given by the javax.servlet.jsp.jstl.i18n.exception.basename scoped attribute, is used. This attribute is searched in the page, request, session (if valid), and application scope(s) (in this order).

The result of looking up the key in the resource bundle is used as the localized exception message. If the key is not found in the resource bundle, or the default resource bundle for exception messages does not exist, the return value of the exception's getLocalizedMessage() method is used as the localized exception message. If the exception is an instance of the LocalizableException interface, the return value of the excpetion's getMessageArgs() method is used for parametric replacement on the localized exception message.

The <exception> action outputs the localized exception message to the current JspWriter object.

If the stackTrace attribute is given with a value of true, the exception's stacktrace is printed out in addition to its localized exception message.

16. <requestEncoding>

The <requestEncoding> action may be used to set the request's character encoding, in order to be able to correctly decode request parameter values whose encoding  is different from ISO-8859-1. This action is needed because browsers do not follow the HTTP specification by failing to include a Content-Type header in their requests.

More specifically, the purpose of the <requestEncoding> action is to set the request encoding to be the same as the response encoding in a page invoked by a form included in the response. This is needed because even if the encoding of the page that is generating the response containing the form is specified via the contentType attribute of a page directive, the response's actual locale (and thus character encoding) may differ from the value specified in the page directive if the page contains an I18N-capable formatting action which sets the response's locale (and thus character encoding) by calling ServletResponse.setLocale(), thereby overriding any encoding specified in the page directive (see Section 3). This assumes that the JSP container calls ServletResponse.setContentType() (with the value of the page directive's contentType attribute, if present) at the beginning of the page, and that any subsequent call to ServletResponse.setLocale() (by any I18N-capable formatting action in the page) overrides the page's existing encoding, so that the locale (and encoding) set by the last I18N-capable formatting action in the page wins. (This assumes that the response is buffered with a big enough buffer size, since ServletResponse.setLocale() and ServletResponse.setContentType() must be called before ServletResponse.getWriter() in order for the specified locale or charset to affect the construction of the writer.)

Example:

    <fmt:requestEncoding value="Shift_JIS" />

This action calls the setCharacterEncoding() method on the servlet request with the character encoding name specified in the value attribute. It must be used before any parameters are retrieved, either explicitly or through the use of an EL expression.

If the character encoding of the request parameters is not known in advance (since the locale and thus character encoding of the page that generated the form collecting the parameter values was determined dynamically), the value attribute must not be specified. In this case, the <requestEncoding> action first checks if there is a charset defined in the request Content-Type header. If not, it uses the character encoding from the javax.servlet.jsp.jstl.i18n.request.charset attribute, which is searched in the page, request, session (if valid), and application scope(s) (in this order). If this attribute is not found, the default character encoding (ISO-8859-1) is used.

17. Context configuration parameters

This section discusses I18N- and formatting-related context configuration parameters that may be specified in a web application's deployment descriptor.

17.1 javax.servlet.jsp.jstl.i18n.locale

This parameter specifies the application's default locale. By specifying this parameter, browser-sensing capabilities for locales are disabled.

Example:

    <web-app>
      <context-param>
        <param-name>javax.servlet.jsp.jstl.i18n.locale</param-name>
        <param-value>fr-CA</param-value>
      </context-param>
    </web-app>

17.2 javax.servlet.jsp.jstl.i18n.fallbackLocale

This parameter specifies the application's default fallback locale for resource bundles, which is used if browser-sensing capabilities are enabled, but none of the available locales for the resource bundle in question match any of the client's preferred locales.

Example:

    <web-app>
      <context-param>
        <param-name>javax.servlet.jsp.jstl.i18n.fallbackLocale</param-name>
        <param-value>fr-CA</param-value>
      </context-param>
    </web-app>

17.3 javax.servlet.jsp.jstl.i18n.basename

This parameter specifies the base name of the application's default resource bundle, which is used if a <message> action does not specify a bundle attribute and is not nested inside a <bundle> action.

Example:

    <web-app>
      <context-param>
        <param-name>javax.servlet.jsp.jstl.i18n.basename</param-name>
        <param-value>com.acme.MyResources</param-value>
      </context-param>
    </web-app>

17.4 javax.servlet.jsp.jstl.i18n.exception.basename

This parameter specifies the base name of the application's default resource bundle for exception messages, which is used by the <exception> action.

Example:

    <web-app>
      <context-param>
        <param-name>javax.servlet.jsp.jstl.i18n.exception.basename</param-name>
        <param-value>com.acme.MyExceptionResources</param-value>
      </context-param>
    </web-app>

17.5 javax.servlet.jsp.jstl.i18n.timeZone

This parameter specifies the application's default time zone in which any times and dates formatted using the <formatDate> action are represented.

Example:

    <web-app>
      <context-param>
        <param-name>javax.servlet.jsp.jstl.i18n.timeZone</param-name>
        <param-value>"America/Los_Angeles"</param-value>
      </context-param>
    </web-app>

18. Developer support

The locale-determination logic for resource bundles, as described in Section 2.1.1 of this Functional Description, is exposed as a general convenience method so that it may be used by any tag handler implementation that needs to produce localized messages, e.g., exception messages that are intended directly for user consumption on an error page.

The convenience method, named getLocalizedMessage() and exposed by the org.apache.taglibs.jstl.extra.i18n.Locale class, looks up a given message key in the resource bundle with a given base name (or the default base name), whose locale is determined according to the locale-determination logic described in Section 2.1.1, and optionally performs parametric replacement on the result of the lookup before returning it.

getLocalizedMessage() comes in the following overloaded flavors:

    /**
     * Retrieves the localized message corresponding to the given key.
     *
     * The given key is looked up in the resource bundle whose base
     * name is retrieved from the javax.servlet.jsp.jstl.i18n.basename scoped
     * attribute and whose locale is determined according to the
     * algorithm described in Section 2.1.1 of this Functional Description.
     *
     * If the javax.servlet.jsp.jstl.i18n.basename attribute is not found
     * in any of the scopes, or no resource bundle with that base name exists,
     * or the given key is undefined in the resource bundle that was loaded as
     * a result of this call, the string "???<key>???" is returned,
     * where "<key>" is replaced with the given key
     *
     * @param pageContext the page in which the given key must be localized
     * @param key the message key to be looked up
     *
     * @return the localized message corresponding to the given key
     */
    public static String getLocalizedMessage(PageContext pageContext,
                                             String key);

    /**
     * Retrieves the localized message corresponding to the given key.
     *
     * The given key is looked up in the resource bundle with the given
     * base name whose locale is determined according to the
     * algorithm described in Section 2.1.1 of this Functional Description.
     *
     * If no resource bundle with the given base name exists,
     * or the given key is undefined in the resource bundle that was loaded as
     * a result of this call, the string "???<key>???" is returned,
     * where "<key>" is replaced with the given key
     *
     * @param pageContext the page in which the given key must be localized
     * @param key the message key to be looked up
     * @param basename the resource bundle base name
     *
     * @return the localized message corresponding to the given key
     */
    public static String getLocalizedMessage(PageContext pageContext,
                                             String key,
                                             String basename);

    /**
     * Retrieves the localized message corresponding to the given key and
     * performs parametric replacement using the arguments specified in the
     * <tt>args</tt> parameter.
     *
     * The given key is looked up in the resource bundle whose base
     * name is retrieved from the javax.servlet.jsp.jstl.i18n.basename scoped
     * attribute and whose locale is determined according to the
     * algorithm described in Section 2.1.1 of this Functional Description.
     *
     * Before being returned, the result of the lookup undergoes parametric
     * replacement, using the arguments specified in the <tt>args</tt>
     * parameter.
     *
     * If the javax.servlet.jsp.jstl.i18n.basename attribute is not found
     * in any of the scopes, or no resource bundle with that base name exists,
     * or the given key is undefined in the resource bundle that was loaded as
     * a result of this call, the string "???<key>???" is returned,
     * where "<key>" is replaced with the given key
     *
     * @param pageContext the page in which the given key must be localized
     * @param key the message key to be looked up
     * @param args the arguments for parametric replacement
     *
     * @return the localized message corresponding to the given key
     */
    public static String getLocalizedMessage(PageContext pageContext,
                                             String key,
                                             Object[] args);

    /**
     * Retrieves the localized message corresponding to the given key.
     *
     * The given key is looked up in the resource bundle with the given
     * base name whose locale is determined according to the
     * algorithm described in Section 2.1.1 of this Functional Description.
     *
     * Before being returned, the result of the lookup undergoes parametric
     * replacement, using the arguments specified in the <tt>args</tt>
     * parameter.
     *
     * If no resource bundle with the given base name exists,
     * or the given key is undefined in the resource bundle that was loaded as
     * a result of this call, the string "???<key>???" is returned,
     * where "<key>" is replaced with the given key
     *
     * @param pageContext the page in which the given key must be localized
     * @param key the message key to be looked up
     * @param args the arguments for parametric replacement
     * @param basename the resource bundle base name
     *
     * @return the localized message corresponding to the given key
     */
    public static String getLocalizedMessage(PageContext pageContext,
                                             String key,
                                             Object[] args,
                                             String basename);

19. Summary

I18N Tags
Element Sample usage
<locale>
value variant scope

Establishes the locale specified by the value attribute for the variant given by the variant attribute.

<fmt:locale value="en-US" variant="UNIX"/>
<timeZone>
value var scope

Establishes the time zone given by the value attribute.

<fmt:timeZone value="America/Los_Angeles">
  <fmt:formatDate type="time"/>
</fmt:timeZone>
<bundle>
basename prefix var scope

Loads the resource bundle whose base name is specified by the basename attribute, and optionally exposes it in the named scoped attribute.

<fmt:bundle basename="Greetings" var="greetingBundle"/>
<message>
key bundle messageArgs var scope

Fetches the localized message corresponding to the key specified by the key attribute from the resource bundle given by the bundle attribute, and performs parametric replacement on the retrieved message using the argument values supplied via the messageArgs attribute or  <messageArg> subtags.

<fmt:message key="Welcome" bundle="$greetingBundle"/>
<messageFormat>
value messageArgs var scope

Performs parametric replacement on the pattern specified by the value attribute using the argument values supplied via <messageArg> subtags.

<fmt:messageFormat value="$priceMsg">
  <fmt:messageArg value="$priceArg"/>
</fmt:messageFormat>
<messageArg>
value

Supplies the argument specified by the value attribute  (if present) or the tag body to its parent <message> action for parametric replacement.

<fmt:message key="Welcome" bundle="$greetingBundle"> 
  <fmt:messageArg value="$dateArg"/>
</fmt:message>
<formatNumber>
value type pattern parseLocale var scope

Formats the given numeric value as a number, currency, or percentage using the locale's predefined or the specified (customized) formatting pattern.

<fmt:formatNumber value="12345.67" parseLocale="de" type="currency"/>
<parseNumber>
value type pattern parseLocale var scope

Parses the given numeric string using the locale's default or the specified (customized) formatting pattern.

<fmt:parseNumber value="$num" var="parsed"/>
<formatDate>
value type dateStyle timeStyle pattern timeZone parseLocale var scope

Formats the given (or current) date using the locale's predefined or the specified (customized) formatting pattern.

<fmt:formatDate timeStyle="long" dateStyle="long"/>
<parseDate>
value type dateStyle timeStyle pattern timeZone parseLocale var scope

Parses the given date string using the locale's default or the specified (customized) formatting pattern.

<fmt:parseDate value="May 22, 2001 4:05:53 PM PDT" var="parsed"/>
<exception>
value bundle stackTrace

Displays the exception given by the value attribute (or the error page's exception if no value attribute is given) in its localized form.

<fmt:exception bundle="$errorMessages"/>
<requestEncoding>
value

Sets the request character encoding to the charset specified by the value attribute.

<fmt:requestEncoding value="Shift_JIS"/>