Java SelectManyCheckbox中的JSF/Primefaces枚举转换器

Java SelectManyCheckbox中的JSF/Primefaces枚举转换器,java,jsf,primefaces,enums,converter,Java,Jsf,Primefaces,Enums,Converter,我正在努力寻找为什么这不起作用 我有一个选择框 <h:form> <p:selectManyCheckbox id="listCars" value="#{controller.listSelectedCarTypes}" converter="genericEnumConverter"> <f:selectItems value="#{controller.listCarTypeValues}" /> </p:selectManyCheckb

我正在努力寻找为什么这不起作用

我有一个选择框

<h:form>

<p:selectManyCheckbox id="listCars" value="#{controller.listSelectedCarTypes}" converter="genericEnumConverter">
    <f:selectItems value="#{controller.listCarTypeValues}" />
</p:selectManyCheckbox>

<p:commandButton value="Pesquisar" action="#{controller.filter}" process="@this, @form" update="panelResults" icon="ui-icon-search"/>

</h:form>
最后,这是我从另一个stackoverflow参考中得到的转换器

@FacesConverter(value="genericEnumConverter")
public class GenericEnumConverter implements Converter {

private static final String ATTRIBUTE_ENUM_TYPE = "GenericEnumConverter.enumType";

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    System.out.println("value: "+value);
    if (value instanceof Enum) {
        component.getAttributes().put(ATTRIBUTE_ENUM_TYPE, value.getClass());
        return ((Enum<?>) value).name();
    } else {
        throw new ConverterException(new FacesMessage("Value is not an enum: " + value.getClass()));
    }
}

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    Class<Enum> enumType = (Class<Enum>) component.getAttributes().get(ATTRIBUTE_ENUM_TYPE);
    try {
        System.out.println("enumType: "+enumType+ " value: "+value);
        System.out.println("CarType.valueOf(value): "+CarType.valueOf(value));
        System.out.println("Enum.valueOf(enumType, value): "+Enum.valueOf(enumType, value));
        return Enum.valueOf(enumType, value);
    } catch (IllegalArgumentException e) {
        throw new ConverterException(new FacesMessage("Value is not an enum of type: " + enumType));
    }
}

}
但是,当我提交表单并调用getAsObject时,它会对Enum.valueOfenumType,value抛出IllegalArgumentException

enumType: class my.project.enums.CarType$120 value: TRUCK
CarType.valueOf(value): Holy moly a Monster Truck
Value is not an enum of type: class my.project.enums.CarType$120
奇怪的是。。。此:CarType.valueOfvalue有效

但这是:Enum.valueOfenumType,value not

为了让selectManyCheckbox正常工作,我必须为我的枚举类型而不是泛型创建一个显式转换器


谁能给我解释一下吗?提前感谢。

这是Java的核心问题。枚举类CarType具有抽象方法,每个枚举值都是CarType子类的实例。见:

解决方案是将Enumvalue.getDeclaringClass而不是value.getClass设置为getAsString中的属性\u ENUM\u类型。。。方法


提示:我认为这是类的问题,因为我注意到类名my.project.enums.CarType$120中有一个数字。

它是普通jsf组件而不是primefaces组件工作的吗?如果您隔离这段代码并在一个带有“main”的类中使用它会怎么样?同样的错误?非主题提示:开始使用OmniFaces:和许多其他有用的工具,使用JSFHTMLH:selectManyCheckbox,同样的错误。。。同样的行为。。。我正在运行一个带有tomcat、hibernate、jsf和primefaces的web应用程序。因此,它与primefaces无关,但很可能是普通jsf或其他使用spring?的相关应用程序?。通常情况下,制作一个简单的JSFXHTML并删除PrimeFaces标记是一种常见的做法,因为标记用于问题所在的位置,而不是使用什么。离题:in process=@this,@form,@这是多余的dat,我忘了删除它,因为我是从另一个有f:setPropertyActionListener的按钮复制的。。。谢谢你的留言。。。我不会使用spring,我会尝试一个单独的jsf实验。。。谢谢
@FacesConverter(value="genericEnumConverter")
public class GenericEnumConverter implements Converter {

private static final String ATTRIBUTE_ENUM_TYPE = "GenericEnumConverter.enumType";

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    System.out.println("value: "+value);
    if (value instanceof Enum) {
        component.getAttributes().put(ATTRIBUTE_ENUM_TYPE, value.getClass());
        return ((Enum<?>) value).name();
    } else {
        throw new ConverterException(new FacesMessage("Value is not an enum: " + value.getClass()));
    }
}

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    Class<Enum> enumType = (Class<Enum>) component.getAttributes().get(ATTRIBUTE_ENUM_TYPE);
    try {
        System.out.println("enumType: "+enumType+ " value: "+value);
        System.out.println("CarType.valueOf(value): "+CarType.valueOf(value));
        System.out.println("Enum.valueOf(enumType, value): "+Enum.valueOf(enumType, value));
        return Enum.valueOf(enumType, value);
    } catch (IllegalArgumentException e) {
        throw new ConverterException(new FacesMessage("Value is not an enum of type: " + enumType));
    }
}

}
value: Cool but Hot Off the Road
value: Holy moly a Monster Truck
...
enumType: class my.project.enums.CarType$120 value: TRUCK
CarType.valueOf(value): Holy moly a Monster Truck
Value is not an enum of type: class my.project.enums.CarType$120