【问题标题】:Change Localization In JSF Throughout The Session在整个会话期间更改 JSF 中的本地化
【发布时间】:2013-03-23 06:32:19
【问题描述】:

我有一个 Web 应用程序,它使用带有 PrimeFaces 的 JSF,并且有一个 JSF 允许用户动态更改语言环境。但是在用户转到另一个 JSF 后,语言环境会更改回默认值。 我查看了代码herehere,但仍然无法使用。

在我的资源目录中,我有 3 个属性文件。

Project
    - src/main/resources
        - <default package>
            - messages_en_US.properties
            - messages_zh_CN.properties
            - messages_zh_TW.properties

在我的faces-config.xml 中,我定义了语言环境

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

在允许用户更改语言环境的 JSF 中,它实际上是一个用户个人资料页面。 &lt;p:selectOneMenu /&gt; 项是从 Ennum 中读取的,并且在单击“保存”按钮时更改区域设置。

<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" />

UserControllerManagedBean中,代码如下:

@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

}

在 JSF 中,我尝试添加 &lt;f:view locale="#{loginController.locale}" /&gt;。但还是一样。在调试模式下,当转到新的 JSF 页面时,userLocale 的值始终是默认语言环境,而不是用户更改的语言环境。

LoginController 代码如下。在doLogin() 方法中,我将userLocale 对象设置为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 会话范围记住语言选择并设置视图区域设置以相应地更改视图。
  • 但是当在 UserController 中我使用 ManagedProperty 注释将值设置为来自 LoginController (@SessionScoped) 的属性时,它不应该工作吗?

标签: jsf localization


【解决方案1】:

您的语言环境未能保持的原因是您注入的语言环境属性在您注入时尚未使用新值更新。看,当您注入托管 bean 属性时,与托管 bean 本身一样

@ManagedProperty(value = "#{loginController.userLocale}")

而不是

 @ManagedProperty(value = "#{loginController}") 

您将获得静态值注入。即使在注入 bean 中的值已更新之后,您仍然只会得到一个在注入 bean 初始化时设置的陈旧值。所以你需要做的是注入整个LoginController,然后自己拉取值,这样你就会得到最新的值。

另见


与您的问题无关,您确实不应该将成员变量和注入放在类的底部。让你的代码不方便阅读

【讨论】:

  • 谢谢!我希望这被记录在某个地方,并且写博客的人写了关于@ManagedProperty 的说明注入属性和托管bean 之间的区别。这也是我之前提出的另一个问题的答案stackoverflow.com/questions/15755588/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 2015-03-08
  • 2013-01-27
相关资源
最近更新 更多