I have a web application, which uses JSF with PrimeFaces, and there is a JSF which allows users to change the locale dynamically. But the locale changes back to the default after the user goes to another JSF. I looked at the codes here, and here, but still couldn't get it to work.
In my resource directory, I have 3 property files.
Project
- src/main/resources
- <default package>
- messages_en_US.properties
- messages_zh_CN.properties
- messages_zh_TW.properties
In my faces-config.xml
I have the locales defined
<application>
<locale-config>
<default-locale>en_US</default-locale>
<supported-locale>zh_TW</supported-locale> <!-- generic traditional chinese -->
<supported-locale>zh_CN</supported-locale> <!-- generic simplified chinese -->
</locale-config>
<message-bundle>
messages
</message-bundle>
<resource-bundle>
<base-name>messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
In the JSF which allows users to change the locale, it is actually a user profile page. The <p:selectOneMenu />
items are read from an Ennum and the locale is changed upon clicking on the "Save" button.
<p:selectOneMenu id="defaultLanguage" value="#{userController.userLanguage}">
<f:selectItems value="#{userController.langcode}" var="lang" itemValue="#{lang.locale}"
itemLabel="#{lang.locale} - #{lang.desc}" />
</p:selectOneMenu>
...
<p:commandButton id="save" value="#{msg.save}" title="#{msg.save}" icon="ui-icon-disk"
styleClass="action-buttons" actionListener="#{userController.doSave}" update="@form" />
In the UserController
ManagedBean, the code are as follows:
@ManagedBean
@ViewScoped
public class UserController extends BaseController implements Serializable {
public void doSave(ActionEvent e) {
String lang;
String country = null;
String[] selectedLanguage = userLanguage.split("_");
lang = selectedLanguage[0];
if (selectedLanguage.length > 1) {
country = selectedLanguage[1];
setUserLocale(new Locale(lang, country));
}
else {
setUserLocale(new Locale(lang));
}
LOG.debug("userLanguage: {}; lang: {}", userLanguage, lang);
FacesContext.getCurrentInstance().getViewRoot().setLocale(userLocale); // sets the locale from the selected user language
Messages.addGlobalInfo(getMessage(msgInfoUpdated));
}
private LangCode userLangCode; // getter + setter
private LangCode[] langcode = LangCode.values(); // getter + setter
@ManagedProperty(value = "#{loginController.userLocale}")
private Locale userLocale; // getter + setter
}
In the JSF I tried to add the <f:view locale="#{loginController.locale}" />
. But still the same. In debug mode, when going to a new JSF page, the value of the userLocale
is always the default locale and not the one which the user changed.
The LoginController
code is as below. At the doLogin()
method, I set the userLocale
object with the locale from the Faces Context.
@ManagedBean
@SessionScoped
public class LoginController extends BaseController implements Serializable {
public String doLogin() {
String returnValue;
try {
currentUser = aduserFacade.validateUserLogin(username, password);
LOG.debug("Successful login: {}", currentUser.getUsrId());
// Set currentUser object into request session attribute
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
setUserSession();
userLocale = Faces.getLocale();
request.getSession().setAttribute("userSession", userSession);
returnValue = "main";
}
catch (Exception e) {
Messages.addGlobalError(getMessage(e.getMessage()));
LOG.error(e.toString(), e);
returnValue = null;
}
return returnValue;
}
private Locale userLocale; // getter + setter
}
UserController
session scoped to remember language choice and set view locale to change view accordingly. – skuntsel