ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button
JavaServer Pages, 2nd Edition

JSTL 1.0: What JSP Applications Need, Part 2

by Hans Bergsten, author of JavaServer Pages, 2nd Edition
09/11/2002

Part 1 of this series gave you an overview of JSTL -- the new specification of commonly-needed JSP tag libraries -- and showed you how to use the core JSTL actions. In this article, I'll dig a bit deeper and discuss how JSTL can help you with internationalization and database access. The bulk of the article does not require any Java programming knowledge, but the sections that deal with how servlets and other Java classes interact with the JSTL actions do. If you're not a Java programmer, you can just skip those sections.

Internationalization and Formatting

Large Web sites often need to please visitors from all over the world, and serving up content in just one language doesn't cut it. To develop a Web site that provides a choice of languages, you have two options:

  • Write one set of pages for each language.
  • Write one shared set of pages that pull in content in different languages from external sources.

Often you end up with a mixture of these techniques, using separate pages for mostly static, large amounts of content and shared pages when the amount of content is small but dynamic (e.g., a page with a few fixed labels displayed in different languages and all other data coming from a database).

Preparing an application for multiple languages is called internationalization (commonly abbreviated as i18n) and making content available for a specific language is called localization (or l10n). To do this right, you need to consider other things besides the language. How dates and numbers are formatted differ between countries, and even within countries. Colors, images, and other nontextual content may also need to be adapted to the customs of a certain region. The term locale refers to a set of rules and content suitable for a specific region or culture.

Locale-Sensitive Date and Number Formatting

JSTL includes a set of actions to simplify internationalization, primarily when shared pages are used for multiple languages. Let's first look at how to properly format dates and numbers. This example formats the current date and a number based on the rules for a default locale.

<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<html>
<body>
  <h1>Formatting with the default locale</h1>
  <jsp:useBean id="now" class="java.util.Date" />
  Date: <fmt:formatDate value="${now}" dateStyle="full" />
  Number: <fmt:formatNumber value="${now.time}" />
</body>
</html>

The first line is the taglib directive for the JSTL library that contains the i18n and formatting actions. The default prefix, used here, is fmt. To get a value to format, I then create a java.util.Date object that represents the current date and time, and save it as a variable named now.

In This Series

JSTL 1.0: Standardizing JSP, Part 1 -- JSTL offers a set of standardized JSP custom actions to handle common tasks. This article, the first in a series, provides an overview and shows how to use the most common tags.

JSTL 1.0: What JSP Applications Need, Part 3 -- In the final installment in this series on JSTL Hans Bergsten, author of JavaServer Pages, 2nd Edition, shows you how to leverage the JSTL classes when developing your own custom actions.

We're now prepared to do some locale-sensitive formatting. The JSTL <fmt:formatDate> action formats the now variable value, assigned to the value attribute value using the type of EL expression you learned about in the previous article in this series. The dateStyle attribute tells the action how to format the date.

You can use any of the values default, short, medium, long, or full for the dateStyle attribute. Exactly what type of formatting these values represent varies depending on the locale. For the English locale, full results in a string like Thursday, August 29, 2002. In this example, I have only formatted the date part, but you can include the time part as well (or format just the time part), and define customized formatting rules for both the date and time instead of the locale-dependent styles:

<fmt:formatDate value="${now}" type="both" 
pattern="EEEE, dd MMMM yyyy, HH:mm" />

The pattern attribute takes a custom formatting pattern of the same type as the java.text.SimpleDateFormat class. The pattern used here results in Thursday, 29 August 2002, 17:29 with the English locale when I write this. The <fmt:formatNumber> action supports similar attributes to specify how to format a number using locale-dependent styles for a regular number, currency value, or a percentage, as well as using customized patterns of different kinds. You can learn more about all of the formatting options in the JSTL specification or in my JavaServer Pages, 2nd Edition book.

JavaServer Pages

Related Reading

JavaServer Pages
By Hans Bergsten

Using JSTL to Select the Locale

Back to the main question: how is the locale for formatting the date and the number determined? If you use the JSTL actions exactly as in this example, doing nothing else, the formatting locale is determined by comparing the locales specified in a request header named Accept-Language with the locales supported by the Java runtime environment.

The header, if present, contains one or more locale specifications (in the form of a language code and possibly a country code), with information about their relative priority. The user uses browser configurations to define which locale specifications to send. The request locales are compared in priority order with the ones offered by the Java runtime, and the best match is selected.

If no match is found, the formatting action looks for the so-called fallback-locale configuration setting. A configuration setting is a value set either by a context parameter in the application's web.xml file or by a JSTL action or Java code in one of the JSP scopes. To set the fallback locale in the web.xml file, include these elements:

<context-param>
<param-name>
  javax.servlet.jsp.jstl.fmt.fallbackLocale
</param-name>
<param-value>
  de
</param-value>
</context-param>

With this setting, the German locale (specified by the de language code as the parameter value) is used if none of the locales specified by the request are supported by the Java runtime.

JSTL also lets you set a hardcoded default locale for the application that you can then override when needed. This gives you full control over which locale is used, instead of relying on the whims of the visitor's browser configuration. The default locale is also a configuration setting. It can be specified with a context parameter in the web.xml like this:

<context-param>
<param-name>
  javax.servlet.jsp.jstl.fmt.locale
</param-name>
<param-value>
  en
</param-value>
</context-param>

This setting establishes English as the default locale for the application, resulting in the previous JSP page example always formatting the date and the number according to the English rules.

To override the default locale configuration setting, you can use the <fmt:setLocale> action. It sets the default locale within a specific JSP scope. Here's an example that sets the default locale for the page scope, based on a cookie that keeps track of the locale a user selected during a previous visit:

<h1>Formatting with a locale set by setLocale</h1>
<c:if test="${!empty cookie.preferredLocale}">
<fmt:setLocale value="${cookie.preferredLocale.value}" />
</c:if>
<jsp:useBean id="now" class="java.util.Date" />
Date: <fmt:formatDate value="${now}" dateStyle="full" />
Number: <fmt:formatNumber value="${now.time}" />

Here I first use the JSTL <c:if> action to test if a cookie named preferredLocale is received with the request. If so, the <fmt:setLocale> action overrides the locale for the current page by setting the locale configuration variable in the page scope. If you want to, you can set the locale for another scope using the scope attribute. Finally, the date and the number are formatted according to the rules for the locale specified by the cookie, or the default locale, if the cookie isn't present.

In addition to formatting actions, JSTL includes actions for interpreting (parsing) dates and numbers in a locale-sensitive way: <fmt:parseDate> and <fmt:parseNumber>. These actions support pretty much the same attributes as their formatting counterparts, and can be used to convert dates and numeric input into their native form before they are further processed. I'll show you an example of this later in this article.

Pages: 1, 2, 3, 4

Next Pagearrow