JSF与Enum'验证错误:值无效'

时间:2010-03-30 21:27:48

标签: jsf

我有一个枚举,其代码是这样的 -

public enum COSOptionType {

    NOTAPPLICABLE,
    OPTIONAL,
    MANDATORY;

    private String[] label = { "Not Applicable", "Optional", "Mandatory"};

    @Override
    public String toString() {

        return label[this.ordinal()];
    }

    public static COSOptionType getCOSOption(String value) {
        int ivalue = Integer.parseInt(value);
        switch(ivalue) {
        case 0:
            return NOTAPPLICABLE;
        case 1: 
            return OPTIONAL;
        case 2:
            return MANDATORY;
         default:
                throw new RuntimeException("Should not get this far ever!");
        }
    }

}

我有转换器来转换枚举类型

public class COSEnumConverter implements Converter {

    public Object getAsObject(FacesContext context, UIComponent comp, String value) {

        return COSOptionType.getCOSOption(value);
    }

    public String getAsString(FacesContext context, UIComponent comp, Object obj) {
        if (obj instanceof String) {
            return (String) obj;
        }
        COSOptionType type = (COSOptionType) obj;
        int index = type.ordinal();
        return ""+index;
    }

}

视图如下所示

 <h:selectOneMenu value="#{controller.type}" id="smoking">                                           
   <f:selectItems value="#{jnyController.choices}" />
 </h:selectOneMenu>

以下是创建选择的代码

private List<SelectItem> createChoicies() {
    List<SelectItem> list = new ArrayList<SelectItem>();
    for (COSOptionType cos : COSOptionType.values()) {
        SelectItem item = new SelectItem();
        item.setLabel(cos.toString());
        item.setValue("" + cos.ordinal());
        list.add(item);
    }
    return list;
}

我不明白为什么会一直抛出“验证错误”?我可以调试并看到转换器工作正常。

NOTE: I am using JSF 1.1

2 个答案:

答案 0 :(得分:6)

根本原因是转换器返回了一个完整的COSOptionType对象而不是"" + cos.ordinal()中的字符串getAsObject(),因此在现有选项中根本不会出现。

无论如何,这种方法过于复杂,尤其是枚举和转换器。我建议您重新考虑以下方法:

Option

package com.example;

public enum Option {

    NOTAPPLICABLE("Not Applicable"),
    OPTIONAL("Optional"),
    MANDATORY("Mandatory");

    private String label;

    private Option(String label) {
        this.label = label;
    }

    public String getLabel() {
        return label;
    }

}

Bean

package com.example;

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

public class Bean {

    private List<SelectItem> options = new ArrayList<SelectItem>();
    private Option option;

    public Bean() {
        for (Option option : Option.values()) {
            options.add(new SelectItem(option, option.getLabel()));
        }
    }

    public void submit() {
        System.out.println(option);
    }

    public List<SelectItem> getOptions() {
        return options;
    }

    public Option getOption() {
        return option;
    }

    public void setOption(Option option) {
        this.option = option;
    }

}

OptionConverter

package com.example;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class OptionConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return Option.valueOf(value);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return ((Option) value).name();
    }

}

faces-config.xml

<managed-bean>
    <managed-bean-name>bean</managed-bean-name>
    <managed-bean-class>com.example.Bean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<converter>
    <converter-class>com.example.OptionConverter</converter-class>
    <converter-for-class>com.example.Option</converter-for-class>
</converter>

JSF页面的相关部分:

<h:form>
    <h:selectOneMenu value="#{bean.option}">                                           
        <f:selectItems value="#{bean.options}" />
    </h:selectOneMenu>
    <h:commandButton value="submit" action="#{bean.submit}" />
    <h:messages />
</h:form>

无需为被认为是邪恶的Enum#ordinal()而烦恼。

如果您使用的是内置通用EnumConverter附带的JSF 1.2或更新版本,则OptionConverter完全是多余的,可以安全删除。

答案 1 :(得分:4)

尝试使用item.setValue(cos)代替item.setValue("" + cos.ordinal())