AdSense Mobile Ad

Showing posts with label jstl. Show all posts
Showing posts with label jstl. Show all posts

Tuesday, December 1, 2009

Selecting the locale for an user with JSTL

In another post, I introduced the basic internationalization capabilities built in JSTL. The algorithm used to choose a suitable locale for an user is a good default choice: without any effort, your web application will show up in the correct locale.

But what if you wanted to let the user choose the locale?

Well, the JSTL Specification lets you establish a locale and a scope: such as page, request, session, application. The first sketch I'd come up with would be something like creating a servlet to enforce the programmatic configuration.

Language selector servlet

This is a servlet service method prototype:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    final String lang = request.getParameter("lang");
    if (isSupported(lang)) {
        Config.set(request.getSession(), Config.FMT_LOCALE, lang);
    }

    request.getRequestDispatcher("/").forward(request, response);
}

The important call here is Config.set(...): you're telling JSTL to use the specified locale (as a String) and save it in the session scope. This servlet accepts the lang parameter and, if present, uses it to determine if it represents a supported locale (isSupported implementation is omitted). If it is, it uses it as described above. At the end of it all, forwards the user at the web welcome page (if any).

Refinements

The servlet described above is the first step towards a complete user customization and is just an example of how you can use the JSTL's Config class. Desirable improvements might be:
  • Saving the user servlet in its profile (if the user has been authenticated) so that future sessions will automatically use the user-specified locale.
  • Using a servlet filter instead of a servlet to automatically intercept the lang parameter and leave the web navigation unaffected.





Internationalization using JSTL

The Java EE 5 platform is a powerful enterprise-level server development platform which in my opinion is very productive including to develop small web modules, provided you've got a suitable Application Server or Servlet Container to run it.

As far as it concerns web development and authoring, Java EE 5 has got some great APIs such as servlet's, JSP's and JSF's. The JavaServer Pages Specification (JSR 245) includes JSTL (JavaServer Pages Standard Tag Library, JSR 052), which are JSP standard tag extensions that include internationalization features.

Creating a Resource Bundle

The first thing you ought to do when internationalizing your application is creating resource bundles. Resource bundles are Java Properties file, organized for locales, whose aim is separating string literal according to the locale they're meant for.

Let's suppose you want to use three locales in your application:
  • en_US
  • it_IT
  • es_ES

Create for Java Properties files, one per locale and one as a fallback. The naming scheme is [bundle-name]_[locale].properties, so that you'll end up with:

bundle_en_US.properties
bundle_it_IT.properties
bundle_es_ES.properties

Some advances Java IDE, such as NetBeans, let you manage properties files with visual tools and perform basic operations, such as adding a locale or filling up the properties, with a fancy GUI.

Filling the Resource Bundles Up

Filling up properties files is pretty easy: such files contain records with this basic structure:

key=value

In this case you would translate every key value for the correct locale.

Using a Bundle from a JavaServer Page with a JSTL tag

JSTL lets you easily use resource bundles in a JSP. The first thing you've got to do is declaring that you're going to use the JSTL's fmt tag library:

<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

The next thing is telling the library which bundle you're going to use. Let's suppose you're going to use com.domain.YourBundle:

<fmt:setBundle basename="com.domain.YourBundle" />

The last thing is using the retrieved values where you need them:

<fmt:message key="your.key" />

Determining the user locale

Maybe you're wondering how JSTL determines which is the user locale. JSTL, by default, determines the user locale by examining the headers sent by the browser and applying a best match algorithm. If your preferred language settings show (in this order)
  1. English
  2. Spanish
  3. Italian

the resulting application will show up in English. The JSTL Specification will give you further details about how to establish a default locale for a web application using JSTL.

In another post, I'll show you how I resolved the problem of locale switching for a given user in an application of ours.

Further Readings