Recipe 12.3. Using an Application-Wide Locale
Problem
You want your web application to use the same locale settings for all users, regardless of their browser's language setting. You also want the JSTL tags to honor this application-wide locale.
Solution
Use a servlet Filter to set the Locale to the desired value (see Example 12-3). The Filter ensures that the Locale is set for all web requests, and not just those handled by Struts.
Example 12-3. Using a servlet filter to set the locale
package com.oreilly.strutsckbk.ch12;
import java.io.IOException; import java.util.Locale;
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.jsp.jstl.core.Config;
import org.apache.struts.Globals;
public class LocaleFilter implements Filter { // the locale code used to create the locale (e.g. en_US) private String localeCode; // indicates if the locale should always be set; // even if there is currently one in the session private boolean ignore = false;
public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; localeCode = filterConfig.getInitParameter("locale"); override = Boolean.valueOf(filterConfig.getInitParameter("ignore")). booleanValue( ); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // create the session if needed HttpSession session = req.getSession( );
Locale currentLocale = (Locale) session.getAttribute(Globals. LOCALE_KEY); if (currentLocale == null || ignore) { // create the new locale Locale locale = new Locale(localeCode);
// reset the Struts locale session.setAttribute(Globals.LOCALE_KEY, locale); // reset the JSTL locale Config.set(session, Config.FMT_LOCALE, locale); } chain.doFilter(request, response); } public void destroy( ) { // Nothing necessary }
private FilterConfig filterConfig; }
Declare the filter in your web.xml, as shown in Example 12-4.
Example 12-4. Locale filter configuration (partial)
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Struts Cookbook - Chapter 12 Examples</display-name> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>ApplicationResources</param-value> </context-param> <filter> <filter-name>LocaleFilter</filter-name> <filter-class> com.oreilly.strutsckbk.ch12.LocaleFilter </filter-class> <!-- Language and country --> <init-param> <param-name>locale</param-name> <param-value>en_US</param-value> </init-param> <!-- True to set locale even if already set in session --> <init-param> <param-name>ignore</param-name> <param-value>true</param-value> </init-param> </filter>
<filter-mapping> <filter-name>LocaleFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ...
Discussion
Usually, you want the user's Locale to reflect the browser's settings, as shown in Recipe 12.1. Some applications, however, need the opposite behavior. You want the application to reflect the same language and country regardless of how the client's browser, or the server's operating system, is configured. The servlet filter shown in the Solution provides this ability. The filter accepts two initialization parameters. The locale parameter defines the Locale to use by specifying a locale code (e.g., en_US) as its value. To use this filter, you must turn off locale processing in the Struts RequestProcessor using the controller element in the struts-config.xml file:
<controller locale="false"/>
The second parameter, the ignore parameter, indicates if the filter should ignore any Locale in session, always setting the locale even if one is present. You can set this value to false if you want to define a default locale but still allow a user to select and use a new locale (see Recipe 12.4).
Filters provide an excellent way to apply across-the-board behavior. Though you could override the processLocale method in a custom RequestProcessor, it would only affect requests to Struts actions. The Solution shown here will set the default locale for web requests to Struts actions, JSPs, and static HTML pages.
See Also
Servlet filters are a new addition to the Servlet API, being added in Version 2.3. Java Servlet Programming by Jason Hunter (O'Reilly) covers servlet filters in-depth.
Sun's Java site has a good article on the essentials of servlet filters found at http://java.sun.com/products/servlet/Filters.html.
|
No comments:
Post a Comment