<f:viewParam>的验证/转换错误不会本地化为<f:view locale>,而是默认语言环境

Tin*_*iny 7 validation jsf localization jsf-2 viewparams

<f:viewParam>在JSF页面上有一个标记,它在转换和验证后将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>
Run Code Online (Sandbox Code Playgroud)

转换器:

@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.
    }
}
Run Code Online (Sandbox Code Playgroud)

除了来自的消息<f:viewParam>,没有问题.所有其他类型的消息都以用户选择的语言显示.

有什么特别的<f:viewParam>吗?

Bal*_*usC 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);
// ...
Run Code Online (Sandbox Code Playgroud)

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


更新2:Mojarra和MyFaces的家伙同意这一点.对于钻嘴鱼科,它被固定为每2.2.5(没有2.1.x的反向移植了吗?)和MyFaces的它被固定为每2.0.19,2.1.13和2.2.0.