web-dev-qa-db-fra.com

Localisation dans JSF, comment mémoriser les paramètres régionaux sélectionnés par session plutôt que par requête/vue

faces-config.xml:

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

Dans une méthode d'action de bean, je change les paramètres régionaux dans la vue actuelle comme suit:

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

Le problème est que ua Locale est appliqué, mais uniquement par requête/vue et non par session. Une autre demande/vue au sein de la même session réinitialise les paramètres régionaux sur la valeur par défaut ru.

Comment puis-je appliquer les paramètres régionaux pour la session?

42
sergionni

Vous devez stocker les paramètres régionaux sélectionnés dans l'étendue de la session et les définir dans la racine de la vue à deux endroits: une fois par UIViewRoot#setLocale() immédiatement après avoir modifié les paramètres régionaux (ce qui modifie les paramètres régionaux de la racine de la vue en cours et est donc reflété dans la publication; cette partie n'est pas nécessaire lorsque vous effectuez ensuite une redirection) et une fois dans l'attribut locale du <f:view> (qui définit/conserve les paramètres régionaux dans les demandes/vues suivantes).

Voici un exemple de ce à quoi un LocaleBean devrait ressembler:

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);
    }

}

Et voici un exemple de la vue devrait ressembler à ceci:

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

Notez que <html lang> n'est pas requis pour le fonctionnement de JSF, mais il est impératif que les robots de recherche interprètent votre page. Sinon, le contenu serait dupliqué, ce qui serait mauvais pour le référencement.

En relation:

80
BalusC

Je vois que le problème concerne également le nom de fichier .properties . Les codes d’utilisation régionaux japonais (minuscules) tels que: en_gb : messages_en_gb.properties .__ et cela devrait marcher - si vous avez tout essayé

4
Sebastian

Ce composant f: view n’existe pas. Votre page JSF ne fonctionnera pas et n’indiquera que la langue anglaise par défaut. Indiquez la valeur locale de ce composant f: view, puis tout fonctionnera correctement. J'ai fait face au même problème maintenant que ça fonctionne bien.

3
GIRI KUMAR PANEM

Une petite remarque à @BalusC, une excellente solution. Si nous avons <f:viewAction> qui exécute une méthode dans le bean de sauvegarde. Les paramètres régionaux disponibles à partir de l'appel de FacesContext.getCurrentInstance().getViewRoot().getLocale() à l'intérieur de cette méthode sont les paramètres régionaux définis par le navigateur de l'utilisateur ou les paramètres régionaux par défaut de l'application, et non les paramètres régionaux définis dans le bean session par la sélection de l'utilisateur. ). 

Je peux rester corrigé, car j'ai peut-être commis une erreur lors de la mise en œuvre de la solution fournie par @BalusC.

MODIFIER. Après avoir joué avec JSF Lifecycle , ce comportement avec les paramètres régionaux n'est pas lié à <f:viewAction>, car il existe un comportement similaire également avec @PostContruct. <f:view locale="#{localeBean.locale}"> dans la demande (après la localisation sélectionnée par l'utilisateur) est exécutée pendant la phase de réponse au rendu. Les méthodes <f:viewAction> et @PostContruct sont exécutées lors de la phase d'application de l'appel. C'est pourquoi la logique exécutée dans cette méthode n'a pas accès aux paramètres régionaux sélectionnés par l'utilisateur.

La solution que nous utilisons lorsque nous avons besoin de paramètres régionaux corrects consiste à injecter (CDI) localeBean dans un autre bean de support contenant les méthodes <f:viewAction> et @PostContruct, puis à définir les paramètres régionaux avec UIViewRoot#setLocale() de localeBean au début de ces méthodes.

1
Znas Me

Si vous pouvez utiliser CDI et deltaspike ( module JSF ) dans votre environnement, vous pouvez ajouter ce qui suit à votre LocaleBean pour réinitialiser automatiquement les paramètres régionaux de la vue actuelle:

@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
Xavier Dury