何时在 JSF 中命名转换器

Dou*_*tti 4 jsf primefaces jsf-2

我一直在我的 PrimeFaces SelectOneMenu 对象中使用转换器。如果我只告诉转换器指的是哪个类,它们就可以正常工作:

@FacesConverter(forClass = DescriptorVO.class)
public class DescriptorVOConverter implements Converter { ... }
Run Code Online (Sandbox Code Playgroud)

这样,我不必明确告诉 JSF 组件在用 class 对象填充时应该使用哪个转换器DescriptorVO

但是,我制作了一个使用 a 的页面,p:SelectManyCheckbox我终其一生都不知道为什么它没有调用我的转换器。然后我给它起了个名字,像这样:

@FacesConverter(forClass = RoleVO.class, value = "roleVOConverter")
public class RoleVOConverter implements Converter { ... }
Run Code Online (Sandbox Code Playgroud)

并将其作为组件的属性之一传递

<p:selectManyCheckbox id="cbx_roles" required="true" converter="roleVOConverter"
    requiredMessage="At least one role must be selected."
    value="#{userView.selectedRoles}" layout="responsive">
    <f:selectItems value="#{userView.roles}" var="role"
        itemLabel="#{role.title}" itemValue="#{role}" />
</p:selectManyCheckbox>
Run Code Online (Sandbox Code Playgroud)

VOI拉,它开始正确地调用该转换器。这向我提出了一个问题,即我应该何时命名我的转换器(通过value属性)以及何时告诉他们转换器应该与哪个类一起使用(通过forClass属性)就足够了。在使用 PrimeFaces 时,我从不需要为任何转换器命名,仅为这个特定SelectManyCheckbox组件命名。不同的组件是否对转换器有不同的要求,还是我只是弄错了转换器的概念?

Bal*_*usC 5

可能发生当value所述的UISelectMany组件引用的通用java.util.Collection型等List<Role>,而不是像阵列Role[]。这在(强调我的)的javadoc 中UISelectMany指定:

获取Converter使用以下算法:

  • 如果组件有附加的Converter,请使用它。

  • 如果没有,请寻找一个ValueExpressionfor 值(如果有)。在ValueExpression必须指向的东西是:

    • 原语数组(例如int[])。查找Converter此原始类型的注册 by-class 。
    • 对象数组(例如Integer[]String[])。Converter为底层元素类型查找注册的 by-class 。
    • 一个java.util.Collection。不要转换值。
  • 如果由于某种原因Converter无法找到 a,则假定类型为String数组。

原因是,泛型类型<Role>在运行时丢失并且不能直接确定。当您使用MyFaces而不是Mojarra 时,它会起作用,因为它会java.util.Collection通过手动迭代检查实际类型<f:selectItem(s)>Converter根据第一个非null值确定。

我为此创建了规范问题 1422,以便在 JSF 规范中获得它并改进 Mojarra。

也可以看看: