Lokalizacja w JSF, jak zapamiętać wybrane ustawienia regionalne na sesję zamiast na żądanie/widok

faces-config.xml:

<application>
    <locale-config>
        <default-locale>ru</default-locale>
        <supported-locale>ua</supported-locale>
    </locale-config>
</application> 

W metodzie działania bean zmieniam ustawienia regionalne w bieżącym widoku w następujący sposób:

FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua"));

Problem polega na tym, że ua Locale jest stosowane, ale tylko na żądanie/widok, a nie na sesję. Inne żądanie / widok w ramach tej samej sesji resetuje ustawienia regionalne z powrotem do domyślnej wartości ru.

Jak mogę zastosować ustawienia regionalne dla sesji?

Author: BalusC, 2011-01-28

5 answers

Należy zapisać wybrane ustawienia regionalne w zakresie sesji i ustawić je w viewroot w dwóch miejscach: raz przez UIViewRoot#setLocale() natychmiast po zmianie ustawień regionalnych (które zmieniają ustawienia regionalne bieżącego viewroot i tym samym zostają odzwierciedlone w postbacku; ta część nie jest konieczna, gdy wykonujesz przekierowanie) i raz w atrybucie locale<f:view> ( który ustawia / zachowuje ustawienia regionalne w kolejnych żądaniach / widokach).

Oto przykład jak taki LocaleBean powinno wyglądać tak:

package com.example.faces;

import java.util.Locale;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@SessionScoped
public class LocaleBean {

    private Locale locale;

    @PostConstruct
    public void init() {
        locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
    }

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void setLanguage(String language) {
        locale = new Locale(language);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

}

A oto przykład widoku powinien wyglądać następująco:

<!DOCTYPE html>
<html lang="#{localeBean.language}"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
<f:view locale="#{localeBean.locale}">
    <h:head>
        <title>JSF/Facelets i18n example</title>
    </h:head>
    <h:body>
        <h:form>
            <h:selectOneMenu value="#{localeBean.language}" onchange="submit()">
                <f:selectItem itemValue="en" itemLabel="English" />
                <f:selectItem itemValue="nl" itemLabel="Nederlands" />
                <f:selectItem itemValue="es" itemLabel="Español" />
            </h:selectOneMenu>
        </h:form>
        <p><h:outputText value="#{text['some.text']}" /></p>
    </h:body>
</f:view>
</html>

Zauważ, że <html lang> nie jest wymagane do działania JSF, ale jest obowiązkowe jak boty wyszukiwania interpretują Twoją stronę. W przeciwnym razie prawdopodobnie zostanie oznaczony jako DUPLIKAT treści, który jest zły dla SEO.

Powiązane:

 77
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-05 06:17:39

Widzę, że problem jest również z .właściwości nazwa pliku. Java Locale us codes (małe litery) jak: en_gb Ale automatycznie tworzone locale (przez Netbeans) to lowercase_uppercase czyli: messages_en_GB.właściwości Zmień nazwę na: messages_en_gb.właściwości i powinno działać-jeśli próbowałeś wszystkiego

 4
Author: Sebastian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-13 23:31:12

This component f: view is not there your JSF page it will not work and it will shows only default english language.Podaj wartość localae dla tego komponentu f:view, wtedy będzie działać poprawnie. Stanąłem w obliczu tego samego problemu, teraz działa dobrze.

 3
Author: GIRI KUMAR PANEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 06:37:17

Jedna mała uwaga do @BalusC świetne rozwiązanie. Jeśli mamy <f:viewAction>, która wykonuje jakąś metodę w backing bean. Locale dostępne od wywołania do FacesContext.getCurrentInstance().getViewRoot().getLocale() wewnątrz tej metody będzie locale, które jest ustawione przez przeglądarkę użytkownika lub domyślne ustawienia regionalne aplikacji, a nie locale, które jest ustawione na fasoli sesji Przez wybór użytkownika(oczywiście mogą się zgadzać, jeśli Ustawienia regionalne przeglądarki są równe ustawieniom przez użytkownika).

Mogę znieść poprawkę, bo może zrobiłem coś złego przy implementacji rozwiązania pod warunkiem autor: @ BalusC.

Edycja. po zabawie z JSF lifecycle , to zachowanie z locale nie jest związane z <f:viewAction>, ponieważ istnieje podobne zachowanie również z @PostContruct. <f:view locale="#{localeBean.locale}"> in request (po wybraniu ustawień regionalnych przez użytkownika) jest wykonywane w fazie renderowania odpowiedzi. <f:viewAction> i @PostContruct metody są wykonywane w fazie wywołania aplikacji. Dlatego logika, która jest wykonywana w tej metodzie, nie ma dostępu do wybranych ustawień regionalnych użytkownika.

Rozwiązanie, którego używamy, gdy potrzebujemy poprawnego locale jest inject (CDI) localeBean w innych metodach, które zawierają metody <f:viewAction> i @PostContruct, a następnie ustawić locale za pomocą UIViewRoot#setLocale() z localeBean na początku tych metod.

 1
Author: Znas Me,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-28 17:38:13

Jeśli możesz używać CDI i deltaspike (JSF module) w swoim środowisku, możesz dodać do LocaleBean, aby automatycznie zresetować ustawienia regionalne w bieżącym widoku:

@javax.enterprise.context.SessionScoped
public class LocaleBean implements Serializable {

    ...

    public void resetLocale(@Observes @BeforePhase(JsfPhaseId.RENDER_RESPONSE) PhaseEvent event) {
        event.getFacesContext().getViewRoot().setLocale(this.locale);
    }
}
 0
Author: Xavier Dury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 13:17:33