在selectOneMenu中使用枚举失败:“男性”必须可转换为枚举

时间:2013-02-15 10:44:25

标签: jsf enums selectonemenu

我正在开发一个小型的jsf项目,我到了一个状态,我必须在枚举类型中存储一个值,但无法弄清楚如何处理

所以我在这里发布我的问题的一个小描述:

这里是枚举类型:

 package com.enumeration;

 import java.io.Serializable;


 public enum Gender implements Serializable{

    Male('M'), Female('F');

    private char description;

   private Gender(char description) {
     this.description = description;
   }

   public char getDescription() {
     return description;
   }

}

xhtml页面:        

    <h:panelGrid columns="2">
                <h:outputLabel value="Nom:" for="nom" />
                <h:inputText id="nom" value="#{employee.newEmployee.nom}" title="Nom" />

                <h:outputLabel value="Gender:" for="gender" />
                <h:selectOneMenu value="#{employeeBean.newEmployee.gender}" id="gender">
                     <f:selectItem itemLabel="Male" itemValue="Male" />
                    <f:selectItem itemLabel="Female" itemValue="Female"/>
                </h:selectOneMenu>

            </h:panelGrid>
            <h:commandButton value="ajouter" action="index.xhtml" actionListener="#{employeeBean.ajouter}" />
        </h:form>

问题在于,当我尝试向数据库添加新行时,jsf抛出错误: j_idt7:性别:'男性'必须可转换为枚举。

我在网上做了一些搜索,但无法理解解决方案 请帮忙 谢谢

2 个答案:

答案 0 :(得分:8)

您的问题是<f:selectItem>指定了字符串,而<h:selectItem value="#{employeeBean.newEmployee.gender}">似乎返回了两个Gender枚举中的一个。

只要你将相同的值粘贴到两者中,枚举就是AFAIK直接可转换而无需转换器。

这是/ a模式:

<h:selectOneMenu value="#{employeeBean.newEmployee.gender}" id="gender">
    <f:selectItems value="#{enumValuesProvider.genders}"
                   var="gender"
                   itemValue="#{gender}"
                   itemLabel="#{gender.name()}" />
</h:selectOneMenu>

注意,我在这里使用<f:selectItems>。问题是,您不能直接从JSF页面获取值。您将需要一个专用的bean来完成这项工作:

@Named      // or @ManagedBean if you're not using CDI
@ViewScoped // or @RequestScoped
public EnumValuesProvider implements Serializable
{
    public Gender[] getGenders()
    {
        return Gender.values();
    }
}

这是在没有任何测试的情况下写下来的。没有保证。

答案 1 :(得分:0)

在我的实体中:

@Entity

public class MyClass {
@Column
@Convert(converter = MyEnumConverter.class)
@Enumerated(EnumType.ORDINAL)
private MyEnumType myEnumType;
//....getter and setter    }

在我的枚举中

public enum MyEnumType {
    AAAA,
    BBBB;
public String getLabel() {
    switch (this) {
        case AAAA:
            return "aaaa";
        case BBBB:
            return "bbbb";

    }
    return "NONE";
}
@Override
public String toString() {
    return getLabel();
}
}

另一个枚举:

public enum AnotherEnum {
      ...
}

在我的转换器中:(它不是一个FacesConvertor)。

@Converter
public class MyEnumConvertor implements AttributeConverter<MyEnumType, Byte> {
    @Override
    public Byte convertToDatabaseColumn(MyEnumType attribute) {
        switch (attribute) {
            case AAAA:
                return 0;
            case BBBB:
                return 1;
            default:
                throw new IllegalArgumentException("Unknown" + attribute);
        }
    }
    @Override
    public MyEnumType convertToEntityAttribute(Byte dbData) {
        switch (dbData) {
            case 0 :
                return EstatePossessionType.AAAA;
            case 1:
                return EstatePossessionType.BBBB;

            default:
                throw new IllegalArgumentException("Unknown" + dbData);
        }
    }
  }

在我的util类中:

public class MyUtilClass {
    public <T extends Enum> SelectItem[]     createSelectItemByEnumClass(Class<T> clazz) throws Exception {
        SelectItem[] selectItem = null;
        int i = 0;
        try {
          Object[] enumConstants = clazz.getEnumConstants();
            if (enumConstants != null) {
                selectItem = new SelectItem[enumConstants.length];
                for (Object object : enumConstants) {
                    selectItem[i++] = new SelectItem(object,     object.toString());
              }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return selectItem;
    }
}

在我的CDI-bean课程中:

public class MyCdiClass {
    MyEnumType selectByUser = null;
    public Class getSelectItemClass(){
        return MyEnumType.class;//<<--I'll tell jsf, I want create SelectItem from this class.Maybe I have more than one enum:).
    }
    public MyEnumType getSelectByUser() {
        return selectByUser;
    }
    public void setSelectByUser(MyEnumType selectByUser) {
        this.selectByUser = selectByUser;
    }
}

在我的jsf页面中:

<h:selectOneMenu value="#{handleEstateActionInEstate.selectByUser}">
    <f:selectItems value="#{myUtility.createSelectItemByEnumClass(myCdiBean.selectItemClass)}"/>
 </h:selectOneMenu>

我希望这些代码段有用。