jsf - 如何更改 JSF 2.0 中的语言环境?

标签 jsf jsf-2

在我的应用程序中,用户应该能够切换区域设置(用于在页面上呈现文本的语言)。大量教程都在使用 FacesContext.getCurrentInstance().getViewRoot().setLocale()。例如:http://www.mkyong.com/jsf2/jsf-2-internationalization-example/ 。但是,这在 JSF 2.0 中不起作用(它在 1.2 中起作用)。语言永远不会转换。没有错误或任何东西。相同的代码在 JSF 1.2 中运行良好。

正确且明确的方法是什么?我拼凑了一个解决方案,但不确定这是否是正确的。这很好用。用户单击英语或法语后,语言会切换。这是代码片段,可以给您一些想法。

@ManagedBean(name = "switcher")
@SessionScoped
public class LanguageSwitcher {
    Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    public String switchLocale(String lang) {
        locale = new Locale(lang);

        return FacesContext.getCurrentInstance().getViewRoot().getViewId() +
            "?faces-redirect=true";
    }
    //getLocale() etc. omitted for brevity
}

XHTML:

<f:view locale="#{switcher.locale}">
    <h:outputText value="#{msg.greeting}" />
    <h:commandLink value="English" action="#{switcher.switchLocale('en')}" />
    <h:commandLink value="French" action="#{switcher.switchLocale('fr')}" />
</f:view>

为了给您提供更多信息,这是配置文件。

<application>
    <locale-config>
        <supported-locale>en</supported-locale>
        <supported-locale>fr</supported-locale>
    </locale-config>
    <resource-bundle>
        <base-name>com.resources.Messages</base-name>
        <var>msg</var>
    </resource-bundle>
</application>

再一次,这有效。但是,我没有通过以任何方式调用任何 API 来更改 JSF 本身的语言环境。这让我有一种毛骨悚然的感觉。这是更改用户区域设置的正确方法吗?

最佳答案

好吧,冒着回答我自己的问题的风险,我想总结一下我发现的所有不同方法。

基本方法是我已经在做的。也就是说,在 session 范围内有一个托管 bean,它返回用户的区域设置。此语言环境需要在每个 XHTML 中使用 <f:view locale="..."> 。我从 BalusC 的一篇文章中学到了这项技术,所以在此表示感谢。

现在,关注的是 f:view 元素的使用。这需要在每一页中重复,如果错误地省略,则可能是缺陷的根源。我找到了解决这个问题的几种方法。

方法#1:创建 Facelet 模板并在其中添加 f:view 元素。单独的模板用户页面不必担心添加此元素。

方法#2 使用阶段监听器。 @meriton 已在此处发布了解决方案。谢谢你。

方法 #3 使用自定义 View 处理程序,该处理程序扩展 MultiViewHandler 并从calculateLocale() 方法返回用户的区域设置。这在《Beginning JSF 2 APIs and JBoss Seam》一书中进行了描述,作者:Kent Ka Iok Tong。这是书中的一个稍微修改过的示例:

public class MyViewHandler extends MultiViewHandler {
    public Locale calculateLocale(FacesContext context) {
        HttpSession session = (HttpSession) context.getExternalContext()
            .getSession(false);
        if (session != null) {
            //Return the locale saved by the managed bean earlier
            Locale locale = (Locale) session.getAttribute("locale");
            if (locale != null) {
                return locale;
            }
        }
       return super.calculateLocale(context);
    }
}

然后在 faces 配置中注册它。

<application>
    <view-handler>com.package.MyViewHandler</view-handler>
<!-- Other stuff ... -->
</application>

这比阶段监听器更优雅一些。不幸的是,MultiViewHandler 是 com.sun.faces.application.view 包中的内部非 API 类。这会带来一些 future 的风险。

使用方法 #2 或方法 #3,页面中不需要 f:view 元素。

关于jsf - 如何更改 JSF 2.0 中的语言环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12078520/

相关文章:

jsf-2 - richfaces 4,a4j 中的重新渲染属性 :commandButton and a4j:ajax is gone

jsf-2 - 在托管 Bean 中使用 Bean

JSF 2 本地化(托管 bean)

java - 无法弄清楚如何解决 javax.persistence.PersistenceException

jsf-2 - :param to composite components

jsf - 识别和解决javax.el.PropertyNotFoundException:目标不可访问

java - 使用 f :ajax to wait for data to finish processing, 然后更新

jsf-2 - 多个 ui :includes 的缓慢

java - 在 Web 应用程序中更新数据库中的特定记录

security - 排除 web.xml 中的 css 和图像资源 安全约束