何时在JSF中命名转换器

时间:2016-06-11 04:58:54

标签: jsf jsf-2 primefaces

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

@FacesConverter(forClass = DescriptorVO.class)
public class DescriptorVOConverter implements Converter { ... }

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

然而,我创建了一个使用p:SelectManyCheckbox的页面,但我无法知道为什么它不会调用我的转换器。然后我给了它一个名字,如下:

@FacesConverter(forClass = RoleVO.class, value = "roleVOConverter")
public class RoleVOConverter implements Converter { ... }

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

<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>

voi la ,它开始正确调用转换器。这向我提出了一个问题,即我何时应该命名我的转换器(通过value属性)并告诉他们转换器应该使用哪个类(具有forClass属性)就足够了。在使用PrimeFaces时,我从未必须使用任何转换器,仅适用于此特定SelectManyCheckbox组件。不同的组件对转换器有不同的必需品,或者我只是将转换器的概念弄错了?

1 个答案:

答案 0 :(得分:4)

value组件的UISelectMany引用类似java.util.Collection的通用List<Role>类型而非类似Role[]的数组时,可能会发生这种情况。这在javadoc of UISelectMany(强调我的)中指定:

  

使用以下算法获取Converter

     
      
  • 如果组件附加了Converter,请使用它。
  •   
  • 如果没有,请查找值ValueExpression(如果有)。 ValueExpression必须指向以下内容:

         
        
    • 基元数组(例如int[])。查找已注册的类Converter以获取此基本类型。
    •   
    • 一组对象(例如Integer[]String[])。查找已注册的基类Converter以获取基础元素类型。
    •   
    • A java.util.Collection。请勿转换值。
    •   
  •   
  • 如果由于某种原因无法找到Converter,请假设该类型为String数组。

  •   

原因是,泛型类型<Role>在运行时丢失,不能直接确定。如果java.util.Collection通过手动迭代<f:selectItem(s)>来检查实际类型并确定{{1},则可以使用MyFaces代替Mojarra。基于第一个非Converter值。

我在此创建了规范issue 1422以获得JSF规范并改进Mojarra。

另见: