JSF 中的本地化,如何记住每个会话而不是每个请求/视图选择的区域设置
faces-config.xml:
<application>
<locale-config>
<default-locale>ru</default-locale>
<supported-locale>ua</supported-locale>
</locale-config>
</application>
在 bean 操作方法中,我正在更改当前视图中的区域设置,如下所示:
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua"));
问题是应用了 ua 区域设置,但仅应用了该区域设置每个请求/视图而不是会话。同一会话中的另一个请求/视图会将区域设置重置回默认 ru
值。
如何应用会话区域设置?
faces-config.xml
:
<application>
<locale-config>
<default-locale>ru</default-locale>
<supported-locale>ua</supported-locale>
</locale-config>
</application>
In a bean action method, I'm changing the locale in the current view as follows:
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua"));
The problem is that ua
Locale is applied, but only per request/view and not for session. Another request/view within the same session resets the locale back to default ru
value.
How can I apply the locale for session?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您需要将选定的区域设置存储在会话范围中,并将其设置在 viewroot 的两个位置:一次通过
UIViewRoot#setLocale()
更改区域设置后立即执行(这会更改当前的区域设置) viewroot 并因此反映在回发中;之后执行重定向时,这部分是不必要的)并且一旦出现在
(设置/保留后续请求/视图中的区域设置)。下面是这样一个
LocaleBean
的示例:下面是视图的示例:
假设
#{text}
已在中配置faces-config.xml
如下:请注意,
并不是 JSF 运行所必需的,但它是搜索机器人如何解释您的页面所必需的。否则它可能会被标记为重复内容,这对搜索引擎优化不利。
另请参阅:
You need to store the selected locale in the session scope and set it in the viewroot in two places: once by
UIViewRoot#setLocale()
immediately after changing the locale (which changes the locale of the current viewroot and thus get reflected in the postback; this part is not necessary when you perform a redirect afterwards) and once in thelocale
attribute of the<f:view>
(which sets/retains the locale in the subsequent requests/views).Here's an example how such a
LocaleBean
should look like:And here's an example of the view should look like:
Which assumes that
#{text}
is already configured infaces-config.xml
as below:Note that
<html lang>
is not required for functioning of JSF, but it's mandatory how search bots interpret your page. Otherwise it would possibly be marked as duplicate content which is bad for SEO.See also:
我发现问题也出在 .properties 文件名上。
Java Locale us 代码(小写)如:en_gb
但自动创建的语言环境(由 Netbeans)是小写_大写,即:messages_en_GB.properties
将名称更改为:messages_en_gb.properties
它应该有效 - 如果你尝试了一切
I see that the problem is also with .properties file name.
Java Locale us codes (lowercase) like: en_gb
But automaticly created locale (by Netbeans) is lowercase_uppercase i.e.: messages_en_GB.properties
Change name to: messages_en_gb.properties
and it should work - if you tried everything
这个组件 f:view 不存在于您的 JSF 页面中,它将无法工作,并且它只会显示默认的英语。为此 f:view 组件提供 localae 值,然后它将正常工作。我遇到了同样的问题,现在工作正常。
This component f:view is not there your JSF page it will not work and It will shows only default english language.Provide the localae value for this f:view component then it will work fine. I faced the same problem now its working fine.
对 @BalusC 伟大解决方案的一点评论。如果我们有
,它会在支持 bean 中执行某些方法。在该方法内调用FacesContext.getCurrentInstance().getViewRoot().getLocale()
时可用的区域设置将是由用户浏览器或默认应用程序区域设置设置的区域设置,而不是在会话中设置的区域设置bean 由用户选择(当然,如果浏览器区域设置等于用户选择的区域设置,它们可以匹配)。我可以接受纠正,因为也许我在实现@BalusC 提供的解决方案时做错了一些事情。
编辑。使用JSF生命周期,这种区域设置行为与
无关,因为@PostContruct
也有类似的行为。请求中的
(用户选择区域设置后)在渲染响应阶段执行。
和@PostContruct
方法在调用应用程序阶段执行。这就是为什么在此方法中执行的逻辑无法访问用户选择的区域设置的原因。当我们需要正确的语言环境时,我们使用的解决方案是在包含
和@PostContruct
的其他支持 bean 中注入(CDI)localeBean
code> 方法,然后在这些方法的开头使用localeBean
中的UIViewRoot#setLocale()
设置语言环境。One small remark to @BalusC great solution. If we have
<f:viewAction>
which executes some method in backing bean. Locale available from call toFacesContext.getCurrentInstance().getViewRoot().getLocale()
inside that method would be locale that is set by user browser or default application locale, not that locale that is set on session bean by user selection(of course they can match if browser locale equals that locale that user selected).I can stand corrected, because maybe I did something wrong when implementing solution provided by @BalusC.
EDIT. After playing with JSF lifecycle, this behavior with locale is not related to
<f:viewAction>
, because there is similar behavior also with@PostContruct
.<f:view locale="#{localeBean.locale}">
in request(after user selected locale) is executed in render response phase.<f:viewAction>
and@PostContruct
methods are executed in invoke application phase. That is why logic that is executed in this method do not have access to user selected locale.Solution that we using when we need correct locale is to inject(CDI)
localeBean
in other backing bean that contains<f:viewAction>
and@PostContruct
methods, and then set locale withUIViewRoot#setLocale()
fromlocaleBean
in beginning of these methods.如果您可以在您的环境中使用 CDI 和 deltaspike(JSF 模块),您可以将以下内容添加到您的
LocaleBean
中以自动重置当前视图上的区域设置:If you can use CDI and deltaspike (JSF module) in your environment, you could add the following to your
LocaleBean
to automatically reset the locale on the current view: