我在JSF页面上有一个<f:viewParam>
标记,它在转换和验证后将GET参数设置为相应的托管bean。
如果发生转换或验证错误,则会从资源包中提取相应的错误消息并显示在<p:messages>
上(也可能是<p:growl>
或<h:messages>
)。
该应用程序是多语言的。因此,当选择其他语言时,应以该语言显示消息,但它始终根据默认语言环境en
(英语)显示消息。
Test.xhtml:
<!DOCTYPE html>
<html lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:view locale="#{localeBean.locale}">
<f:metadata>
<f:viewParam name="id" converter="#{myConverter}" />
</f:metadata>
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:messages />
</h:body>
</f:view>
</html>
转换器:
@FacesConverter("myConverter")
public final class MyConverter implements Converter
{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
ResourceBundle bundle = context.getApplication()
.evaluateExpressionGet(context, "#{messages}", ResourceBundle.class);
String message = bundle.getString("id.conversion.error");
throw new ConverterException(
new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
throw new UnsupportedOperationException(); // Not relevant in this problem.
}
}
除<f:viewParam>
的消息外,没有问题。所有其他类型的消息都以用户选择的语言显示。
<f:viewParam>
有什么特别之处吗?
答案 0 :(得分:6)
我可以重现你的问题。 Mojarra 2.1.25和MyFaces 2.1.12都暴露了同样的问题。因此,我不确定这是否是JSF impl中的错误或JSF规范中的疏忽。到目前为止,事实证明,在输入呈现响应阶段之前,尚未为GET请求设置viewroot语言环境。转换器在验证阶段运行,远远早于渲染响应,这解释了为什么它得到了默认的语言环境。我必须稍后进行调查,如有必要,向Mojarra报告问题。
同时,解决这个问题的最佳方法是按以下方式获取包,而不是EL评估<resource-bundle><var>
:
String basename = "com.example.i18n.message"; // Exactly the same as <resource-bundle><base-name>
Locale locale = context.getApplication().evaluateExpressionGet(context, "#{localeBean.locale}", Locale.class);
ResourceBundle bundle = ResourceBundle.getBundle(basename, locale);
// ...
更新:我已根据此问题报告了issue 3021。我仍然无法理解规范在这一点上所说的内容,但我发现实现的行为不直观。
更新2 :Mojarra和MyFaces的家伙同意这一点。对于Mojarra来说,根据2.2.5(没有2.1.x backport还是?)已经fixed,对于MyFaces来说,根据2.0.19,2.1.13和2.2.0,它是fixed。