1

I have form with user profile settings. One of these settings is the default language of the site. When user change the default language setting i want to change locale of current session. Method for handling the form:

@ManagedBean(name="userEditBean")
@RequestScoped
public class UserEditBean {


    @ManagedProperty(value = LanguageBean.INJECTION_NAME)
    private LanguageBean languageMB;

    private AdminUsersEditForm editForm = new AdminUsersEditForm();


    public String changeDefaultLanguage() {
        editForm.getUser().setDefaultLanguage(editForm.getLocaleCode());
        adminUserEditService.update(editForm.getUser());
        languageMB.changeLocale(editForm.getLocaleCode());
        FacesContext context = FacesContext.getCurrentInstance();  
        context.addMessage(null, new FacesMessage(languageMB.translate("user.edit.languageChanged")));
        return "/pages/protected/user/edit.xhtml?faces-redirect=true";
    }

And the changeLocale:

@ManagedBean(name="languageMB")
@SessionScoped
public class LanguageBean implements Serializable {
    public void changeLocale(String newLocaleValue) {
            //loop country map to compare the locale code
            for (Map.Entry<String, Object> entry : countries.entrySet()) {
                if(entry.getValue().toString().equals(newLocaleValue)){
                    FacesContext.getCurrentInstance()
                            .getViewRoot().setLocale((Locale)entry.getValue());
                }
            }
        }

Language in DB is changed, but site remain in old locale. When i call changeLocale from eventListener for changing site language it works, so where is the problem. Thank you.

Update: I have done some debugging and the problem is in ViewHandlingStrategy#createView() on the line:

if (ctx.getViewRoot() != null) {
    locale = ctx.getViewRoot().getLocale();

ctx.getViewRoot() apparently returns null and locale is not set grom getViewRoot(). But i have no idea, where my viewRoot "lost"

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
DominikM
  • 1,042
  • 3
  • 16
  • 32
  • To avoid the obvious, you've like a ``, right? See also e.g. http://stackoverflow.com/questions/4830588/jsf-locale-is-set-per-request-not-for-session/4830669#4830669 – BalusC Oct 17 '12 at 14:31
  • I had . I chaged it to which returns Locale instance, but no difference. – DominikM Oct 17 '12 at 14:40

1 Answers1

3

I suppose your locale bean is a @SessionScoped bean right?

If that's the case, you should also:

  • Set the locale in your root template or in all your pages in case you don't use templating:

    <f:view contentType="text/html" locale="#{yourLocaleBean.locale}">
        <h:head>
            <!-- headers here -->
        </h:head>
        <h:body>
            <!-- content here -->
        </h:body>
    </f:view>
    

I hope it helps.

rbento
  • 9,919
  • 3
  • 61
  • 61
  • 1
    `LanguageBean` has indeed the `@SessionScoped` annotation. The update of `@all` is unnecessary as the action outcome performs a redirect. Using an `actionListener` instead of `action` makes no sense (that's just a different way of invoking a method, not a potential solution to the concrete problem, see also http://stackoverflow.com/questions/3909267/differences-between-action-and-actionlistener/3909382#3909382 ). – BalusC Oct 17 '12 at 14:29
  • @BalusC Thanks, for some odd reason the code for setting the locale wasn't showing. I've fixed my answer. – rbento Oct 17 '12 at 14:37