7

<f:viewParam>在 JSF 页面上有一个标签,它在转换和验证后将 GET 参数设置为相应的托管 bean。

如果发生转换或验证错误,则会从资源包中获取适当的错误消息并显示在<p:messages>(也可能是<p:growl><h:messages>)上。

该应用程序是多语言的。Therefore when a different language is selected, a message should be displayed in that language but it always displays the message according to the default locale en(for English).

测试.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>吗?

4

1 回答 1

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);
// ...

更新:我已经根据这个问题报告了问题 3021 。在这一点上,我仍然无法理解规范所说的内容,但我发现实现的行为不直观。


更新 2:Mojarra 和 MyFaces 的人同意这一点。对于 Mojarra,它已按照 2.2.5 进行了修复(还没有 2.1.x 向后移植?),对于 MyFaces,它已按照 2.0.19、2.1.13 和 2.2.0进行了修复。

于 2013-08-28T19:29:59.363 回答