Locale"

From Documentation
m (remove empty version history (via JWB))
 
(17 intermediate revisions by 6 users not shown)
Line 4: Line 4:
  
 
=Overview=
 
=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 <code>javax.servlet.ServletRequest.getLocale()</code>). For example, <code>DE</code> is assumed if a user is using a DE-version browser (unless they 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 introduce how to configure ZK to handle the locale differently. For example, you can configure ZK to use the same Locale for all users no matter how the browser is configured. Another example is that you can configure ZK to use the preferred locale that a user specifies in his or her profile if you maintain the user profiles in the server.
  
=The decision sequence of locale=
+
= Current Locale =
  
The locale is decided in the following sequence.
+
[https://www.zkoss.org/javadoc/latest/zk/org/zkoss/util/Locales.html#getCurrent-- Locales.getCurrent()] returns the current locale that ZK detected in the below precedence.
 +
 
 +
=The Decision Sequence of Locale=
 +
 
 +
ZK determines the current locale in the following sequence:
  
 
# 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 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 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.
 
# 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>).
+
# If none of them is found, it uses the locale defined in the Servlet request (i.e., <code>ServletRequest.getLocale()</code>). This is determined by [https://support.google.com/chrome/answer/173424?hl=en&co=GENIE.Platform%3DDesktop the browser language setting].
  
 
With this sequence in mind, you could configure ZK to use the correct locale based on the application requirements.
 
With this sequence in mind, you could configure ZK to use the correct locale based on the application requirements.
  
==Application-level locale==
+
==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 <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 <code>WEB-INF/zk.xml</code>:
  
 
<source lang="xml">
 
<source lang="xml">
Line 30: Line 34:
 
</source>
 
</source>
  
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.
+
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 typos, you could use <javadoc method="PREFERRED_LOCALE">org.zkoss.web.Attributes</javadoc> as follows.
  
 
<source lang="java">
 
<source lang="java">
Line 36: Line 40:
 
</source>
 
</source>
  
== Per-user locale ==
+
== Per-user 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.
+
Because ZK will check if there is a session attribute for the default locale, you could configure ZK to have a 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.
  
 
<source lang="java" >
 
<source lang="java" >
 +
import org.zkoss.web.Attributes;
 +
...
 +
 
  void login(String username, String password) {
 
  void login(String username, String password) {
 
     //check password
 
     //check password
Line 86: Line 93:
 
To make it effective, you have to register it in WEB-INF/zk.xml as a listener. Once registered, the request method is called each time ZK receives a request.
 
To make it effective, you have to register it in WEB-INF/zk.xml as a listener. Once registered, the request method is called each time ZK receives a request.
  
<source lang="java" >
+
<syntaxhighlight lang="xml" >
 
<listener>
 
<listener>
 
     <listener-class>MyLocaleProvider</listener-class>
 
     <listener-class>MyLocaleProvider</listener-class>
 
</listener>
 
</listener>
</source>
+
</syntaxhighlight>
  
 
'''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''': 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 <tt>request</tt> 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.
+
'''Note''': The <code>request</code> 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.
  
 
=Change Locale at Run-time=
 
=Change Locale at Run-time=
Line 117: Line 124:
 
==Change without Reloading==
 
==Change without Reloading==
  
=Version History=
+
If you prefer to keep the current desktop, you have to ask the browser to reload the messages, and change the default locale used by the current thread if you're going to access any component and functionality that depends on it. The reloading of messages can be done by invoking <javadoc method="reloadMessages(java.util.Locale)">org.zkoss.zk.ui.util.Clients</javadoc>, while the setting of the default locale can be done by the use of <javadoc method="setThreadLocal(java.util.Locale)">org.zkoss.util.Locales</javadoc>
Last Update : {{REVISIONYEAR}}/{{REVISIONMONTH}}/{{REVISIONDAY}}
+
 
{| border='1px' | width="100%"
+
For example,
! Version !! Date !! Content
+
 
|-
+
<source lang="java">
| &nbsp;
+
session.setAttribute(Attributes.PREFERRED_LOCALE, locale);
| &nbsp;
+
Clients.reloadMessages(locale);
| &nbsp;
+
Locales.setThreadLocal(locale);
|}
+
</source>
 +
 
 +
 
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 04:35, 5 February 2024

Overview

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

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

Current Locale

Locales.getCurrent() returns the current locale that ZK detected in the below precedence.

The Decision Sequence of Locale

ZK determines the current locale 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()). This is determined by the browser language setting.

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 typos, you could use Attributes.PREFERRED_LOCALE as follows.

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

Per-user Locale

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

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

import org.zkoss.web.Attributes;
...

 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 storing the information in a cookie. It can be done by registering a request interceptor, and then manipulating the cookies when the interceptor is called.

A request interceptor is used to intercept each request being processed. It must implement 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 a listener. Once registered, the request method is called each time ZK receives a request.

<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.

Change Locale at Run-time

When changing the locale dynamically at the run-time (i.e., under an AU request), it is important to notice:

  1. The Locale-dependent messages have been sent to the client, and they have to be reloaded.
  2. The current thread's default locale has to be changed since Locale-dependent components and functionality depend on it.

Reload with sendRedirect

The simplest way to solve the issues is to ask the browser to reload the whole page by use of Executions.sendRedirect(String).

For example,

session.setAttribute(Attributes.PREFERRED_LOCALE, locale);
Executions.sendRedirect(null); //reload the same page

Notice that Executions.sendRedirect(String) will cause the client to reload the page, so any updates to the current desktop will be lost.

Change without Reloading

If you prefer to keep the current desktop, you have to ask the browser to reload the messages, and change the default locale used by the current thread if you're going to access any component and functionality that depends on it. The reloading of messages can be done by invoking Clients.reloadMessages(Locale), while the setting of the default locale can be done by the use of Locales.setThreadLocal(Locale)

For example,

session.setAttribute(Attributes.PREFERRED_LOCALE, locale);
Clients.reloadMessages(locale);
Locales.setThreadLocal(locale);




Last Update : 2024/02/05

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