Localisation dans JSF, comment se souvenir de locale sélectionnée par session au lieu de 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 bean, je change la locale dans la vue actuelle comme suit:

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

le problème est que ua Locale est appliquée, mais seulement par requête/vue et pas pour la session. Une autre requête / vue dans la même session réinitialise la locale de nouveau à la valeur par défaut ru .

Comment appliquer la locale pour session?

40
demandé sur BalusC 2011-01-28 19:26:18

5 réponses

vous devez stocker la locale sélectionnée dans le cadre de la session et la mettre dans le viewroot en deux endroits: une fois par UIViewRoot#setLocale() immédiatement après avoir changé la locale (qui change la locale de la viewroot actuelle et se reflète ainsi dans le postback; cette partie n'est pas nécessaire lorsque vous effectuez une redirection après) et une fois dans l'attribut locale de la <f:view> (qui définit/conserve la locale dans la suivante requêtes/vues).

voici un exemple à quoi un tel 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 à:

<!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 c'est obligatoire comment les bots de recherche interprètent votre page. Sinon, il pourrait être marqué comme contenu dupliqué ce qui est mauvais pour le référencement.

Related:

77
répondu BalusC 2015-06-05 06:17:39

je vois que le problème est également avec .Propriétés Nom du fichier. Codes Java locaux (en minuscules) comme: en_gb Mais la locale créée automatiquement (par Netbeans) est une minuscule _uppercase, c'est-à-dire: messages_fr_gb.propriété Changer le nom en: messages_en_gb.propriété et il devrait fonctionner - si vous avez tout essayé

4
répondu Sebastian 2011-11-13 23:31:12

Cette composante f:vue n'est pas là votre JSF page ne fonctionnera pas et Il affiche uniquement défaut de langue anglaise.Fournir la valeur localae pour ce composant f: view alors il fonctionnera très bien. J'ai fait face au même problème maintenant son fonctionnement très bien.

3
répondu GIRI KUMAR PANEM 2016-04-30 06:37:17

une petite remarque à @BalusC grande solution. Si nous avons <f:viewAction> qui exécute une méthode dans le dos de haricot. La Locale disponible de l'appel à FacesContext.getCurrentInstance().getViewRoot().getLocale() à l'intérieur de cette méthode serait la locale qui est définie par le navigateur de l'utilisateur ou la locale d'application par défaut, pas la locale qui est définie sur session bean par sélection de l'utilisateur(bien sûr, ils peuvent correspondre si locale de navigateur égale cette locale que l'Utilisateur a sélectionnée).

je peux corriger, parce que peut-être j'ai fait quelque chose faux lors de la mise en œuvre de la solution fournie par @BalusC.

EDIT. après avoir joué avec JSF lifecycle , ce comportement avec locale n'est pas lié à <f:viewAction> , parce qu'il y a un comportement similaire aussi avec @PostContruct . <f:view locale="#{localeBean.locale}"> dans request (après que l'Utilisateur a sélectionné locale) est exécuté dans la phase de réponse de rendu. Les méthodes <f:viewAction> et @PostContruct sont exécutées en phase invoke application. C'est pourquoi la logique qui est exécuté dans cette méthode n'ont pas accès à de l'utilisateur paramètres régionaux sélectionnés.

Solution que nous utilisons lorsque nous avons besoin de localisation correcte est d'injecter(CDI) localeBean dans d'autres haricots de soutien qui contient <f:viewAction> et @PostContruct méthodes, puis Définir locale avec UIViewRoot#setLocale() de localeBean au début de ces méthodes.

1
répondu Znas Me 2016-12-28 17:38:13

si vous pouvez utiliser CDI et deltaspike ( module JSF ) dans votre environnement, vous pouvez ajouter ce qui suit à votre LocaleBean pour réinitialiser automatiquement la locale sur la vue courante:

@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
répondu Xavier Dury 2016-03-08 13:17:33