在我的应用程序中,用户应该能够切换区域设置(用于在页面上呈现文本的语言)。大量教程都在使用 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/