Locale"

From Documentation
m
m
Line 3: Line 3:
 
__TOC__
 
__TOC__
  
 +
=Overview=
 
The locale used to process requests and events is, by default, determined by the browser's preferences (by use of the <tt>getLocale</tt> method of <tt>javax.servlet.ServletRequest</tt>). For example, <tt>DE</tt> is assumed if an user is using a DE-version browser (unless he changed the setting).
 
The locale used to process requests and events is, by default, determined by the browser's preferences (by use of the <tt>getLocale</tt> method of <tt>javax.servlet.ServletRequest</tt>). For example, <tt>DE</tt> is assumed if an user is using a DE-version browser (unless he changed the setting).
  
 
In this section, we'd like to discuss how to configure ZK to handle the locale differently. For example, you might want to use the same Locale for all users no matter how the browser is configured. Another example is that you might want to use the preferred locale that a user specified in his or her profile, if you maintain the user profiles in the server.
 
In this section, we'd like to discuss how to configure ZK to handle the locale differently. For example, you might want to use the same Locale for all users no matter how the browser is configured. Another example is that you might want to use the preferred locale that a user specified in his or her profile, if you maintain the user profiles in the server.
  
=== The Application Attribute: <tt>px_preferred_locale</tt> ===
+
=The decision sequence of locale=
[Since 3.6.3]
 
  
If you want to use the same locale for all users, you can specify the locale in the application attribute (<tt>WebApp</tt>, aka., <tt>ServletContext</tt>) called <tt>px_preferred_locale</tt>.
+
The locale is decided in the following sequence.
  
'''Tip''': To avoid typo, you can use the constant: <javadoc method="PREFERRED_LOCALE">org.zkoss.web.Attributes</javadoc>.
+
# It checks if an attribute called <code>org.zkoss.web.preferred.locale</code> defined in the HTTP session (or <javadoc type="interface">org.zkoss.zk.ui.Session</javadoc>). If so, use it.
 +
# It checks if an attribute called <code>org.zkoss.web.preferred.locale</code> defined in the Servlet context (or <javadoc type="interface">org.zkoss.zk.ui.Application</javadoc>). If so, use it.
 +
# It checks if a property called <code>org.zkoss.web.preferred.locale</code> defined in the library property (i.e., <javadoc>org.zkoss.lang.Library</javadoc>). If so, use it.
 +
# If none of them is found, it uses the locale defined in the Servlet request (i.e., <code>ServletRequest.getLocale()</code>).
  
For example, you can implement a <tt>WebAppInit</tt> listener as follows.
+
With this sequence in mind, you could configure ZK to use the correct locale based on the application requirements.
  
<source lang="java">
+
==Application-level Locale==
package foo;
 
public class MyAppInit implements org.zkoss.zk.ui.util.WebAppInit {
 
  public void init(WebApp wapp) {
 
    wapp.setAttribute(org.zkoss.web.Attributes.PREFERRED_LOCALE, Locale.DE);
 
  }
 
}
 
</source>
 
  
And, specify it in <tt>WEB-INF/zk.xml</tt>:
+
If you want to use the same locale for all users, you can specify the locale in the library property. For example, you could specify the following in <tt>WEB-INF/zk.xml</tt>:
  
 
<source lang="xml">
 
<source lang="xml">
<listener>
+
<library-property>
<listener-class>foo.MyAppInit</listener-class>
+
    <name>org.zkoss.web.preferred.locale</name>
</listener>
+
    <value>de</value>
 +
</library-property>
 
</source>
 
</source>
  
=== The Session Attribute: <tt>px_preferred_locale</tt> ===
+
Alternatively, if you prefer to specify it in Java, you could invoke <javadoc method="setProperty(java.lang.String, java.lang.String)">org.zkoss.lang.Library</javadoc>. Furthermore, to avoid typo, you could use <javadoc method="PREFERRED_LOCALE">org.zkoss.web.Attributes</javadoc> as follows.
 +
 
 +
<source lang="java">
 +
Library.setProperty(Attributes.PREFERRED_LOCALE, "de");
 +
</source>
  
Before checking the browser's preferences, ZK will check if a session attribute called <tt>px_preferred_locale</tt> is defined. If defined, ZK uses it as the default locale for the session instead of the browser's preferences. Thus, you can control the locale of a session by storing the preferred locale in this attribute.
+
== Per-use Locale ==
  
'''Tip''': To avoid typo, you can use the constant: <javadoc method="PREFERRED_LOCALE">org.zkoss.web.Attributes</javadoc>
+
Because ZK will check if a session attribute for the default locale, you could configure ZK to have per-user locale by specifying the attribute in a session.
  
 
For example, you can do this when a user logins.
 
For example, you can do this when a user logins.
Line 46: Line 47:
 
     ...
 
     ...
 
     Locale preferredLocale = ...; //decide the locale (from, say, database)
 
     Locale preferredLocale = ...; //decide the locale (from, say, database)
     session.setAttribute(org.zkoss.web.Attributes.PREFERRED_LOCALE, preferredLocale);
+
     session.setAttribute(Attributes.PREFERRED_LOCALE, preferredLocale);
 
     ...
 
     ...
 
  }
 
  }
 
</source>
 
</source>
  
=== The Request Interceptor ===
+
= The Request Interceptor =
 
Deciding the locale after the user logins may be a bit late for some applications. For example, you might want to use the same Locale that was used in the previous session, before the user logins. For a Web application, it is usually done by use of cookies. With ZK, you can register a request interceptor and manipulates the cookies when the interceptor is called.
 
Deciding the locale after the user logins may be a bit late for some applications. For example, you might want to use the same Locale that was used in the previous session, before the user logins. For a Web application, it is usually done by use of cookies. With ZK, you can register a request interceptor and manipulates the cookies when the interceptor is called.
  

Revision as of 10:36, 1 October 2010

Overview

The locale used to process requests and events is, by default, determined by the browser's preferences (by use of the getLocale method of javax.servlet.ServletRequest). For example, DE is assumed if an user is using a DE-version browser (unless he changed the setting).

In this section, we'd like to discuss how to configure ZK to handle the locale differently. For example, you might want to use the same Locale for all users no matter how the browser is configured. Another example is that you might want to use the preferred locale that a user specified in his or her profile, if you maintain the user profiles in the server.

The decision sequence of locale

The locale is decided in the following sequence.

  1. It checks if an attribute called org.zkoss.web.preferred.locale defined in the HTTP session (or Session). If so, use it.
  2. It checks if an attribute called org.zkoss.web.preferred.locale defined in the Servlet context (or Application). If so, use it.
  3. It checks if a property called org.zkoss.web.preferred.locale defined in the library property (i.e., Library). If so, use it.
  4. If none of them is found, it uses the locale defined in the Servlet request (i.e., ServletRequest.getLocale()).

With this sequence in mind, you could configure ZK to use the correct locale based on the application requirements.

Application-level Locale

If you want to use the same locale for all users, you can specify the locale in the library property. For example, you could specify the following in WEB-INF/zk.xml:

<library-property>
    <name>org.zkoss.web.preferred.locale</name>
    <value>de</value>
</library-property>

Alternatively, if you prefer to specify it in Java, you could invoke Library.setProperty(String, String). Furthermore, to avoid typo, you could use Attributes.PREFERRED_LOCALE as follows.

Library.setProperty(Attributes.PREFERRED_LOCALE, "de");

Per-use Locale

Because ZK will check if a session attribute for the default locale, you could configure ZK to have per-user locale by specifying the attribute in a session.

For example, you can do this when a user logins.

 void login(String username, String password) {
     //check password
     ...
     Locale preferredLocale = ...; //decide the locale (from, say, database)
     session.setAttribute(Attributes.PREFERRED_LOCALE, preferredLocale);
     ...
 }

The Request Interceptor

Deciding the locale after the user logins may be a bit late for some applications. For example, you might want to use the same Locale that was used in the previous session, before the user logins. For a Web application, it is usually done by use of cookies. With ZK, you can register a request interceptor and manipulates the cookies when the interceptor is called.

A request interceptor is used to intercept each request processed by ZK Loader and ZK Update Engine. It must implements the RequestInterceptor interface. For example,

import java.util.Locale;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.zkoss.web.Attributes;


 public class MyLocaleProvider implements org.zkoss.zk.ui.util.RequestInterceptor {
     public void request(org.zkoss.zk.ui.Session sess,
     Object request, Object response) {
        final Cookie[] cookies = ((HttpServletRequest)request).getCookies();
         if (cookies != null) {
             for (int j = cookies.length; --j >= 0;) {
                if (cookies[j].getName().equals("my.locale")) {
                     //determine the locale
                    String val = cookies[j].getValue();
                     Locale locale = org.zkoss.util.Locales.getLocale(val);
                     sess.setAttribute(Attributes.PREFERRED_LOCALE, locale);
                     return;
                 }
             }
         }
     }
 }

To make it effective, you have to register it in WEB-INF/zk.xml as follows. Once registered, the request method is called each time ZK Loader or ZK Update Engine receives a request. Refer to Appendix B in the Developer's Reference for more information about configuration.

<listener>
    <listener-class>MyLocaleProvider</listener-class>
</listener>

Note: An instance of the interceptor is instantiated when it is registered. It is then shared among all requests in the same application. Thus, you have to make sure it can be accessed concurrently (i.e., thread-safe).

Note: The request method is called at very early stage, before the request parameters are parsed. Thus, it is recommended to access them in this method, unless you configured the locale and character encoding properly for the request.

Version History

Version Date Content
     



Last Update : 2010/10/01

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.