【问题标题】:selectOneMenu default value issue using converter使用转换器的 selectOneMenu 默认值问题
【发布时间】:2013-12-04 13:44:42
【问题描述】:

我使用<p:selectOneMenu>如下:

<p:selectOneMenu id="choixProgramme" converter="#{programmeConverter}"
value="#{programmeController.selectedProgramme}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{programmeController.listProgrammes}"
    var="programme" itemLabel="#{programme.codeProgImmobilier}"
    itemValue="#{programme}" />
<p:ajax update="dataTableBien" />

我想显示Select One 消息,但我收到此错误:

java.lang.String cannot be cast to xx.xxxxx.xxxx.xxxx.dto.ProgrammeDto

我尝试了this solution,但我仍然遇到同样的问题。

已编辑

我将noSelectionOption 添加到我的&lt;f:selectItem&gt;:

但我在getAsObject() 中有一个对话问题。

 java.lang.NumberFormatException: For input string: "Select One"

已编辑

我的转换器:

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
    if (arg2 == null || arg2.isEmpty()) {
        return null;
    }

    String programme = arg2;
    Long value = Long.valueOf(programme);
    ProgrammeDto result = new ProgrammeDto();
    result = programmeService.findById(value);
    return result;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {

    if (arg2 == null) {
        return "";
    }
    if(arg2 instanceof ProgrammeDto) {
        if (((ProgrammeDto) arg2).getIdProgramme() == null) {
            return "";
        }
    }

            ProgrammeDto programme = new ProgrammeDto();

    if(arg2 instanceof ProgrammeDto) {

        programme = (ProgrammeDto) arg2;
        String codeProgramme = programme.getIdProgramme().toString();
        return (codeProgramme != null) ? String.valueOf(codeProgramme) : null;
    } else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString());

}

我怎样才能做到这一点?

【问题讨论】:

    标签: jsf-2 primefaces converter


    【解决方案1】:

    您正在指定一个空字符串的项目值,并且您很可能在转换器的getAsString() 中包含以下内容:

    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        return ((ProgrammeDto) modelValue).getId();
    }
    

    但是,空字符串永远不能表示为有效的ProgrammeDto 引用。

    使用 #{null} 的项目值而不是空字符串:

    <f:selectItem itemLabel="Select One" itemValue="#{null}" />
    

    或将noSelectionOption 属性设置为true:

    <f:selectItem itemLabel="Select One" noSelectionOption="true" />
    

    转换器的getAsString() 现在可能会抛出NullPointerException 而不是ClassCastException,但如何解决这个问题应该很明显。只需在转换并获取所需字段之前检查它是否不为空。

    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        return (modelValue != null) ? ((ProgrammeDto) modelValue).getId() : null;
    }
    

    另见:


    更新:根据您更新的问题,PrimeFaces 似乎没有考虑 noSelectionOption 并将标签视为项目值。在这种情况下,您需要明确指定 #{null} 的项目值:

    <f:selectItem itemLabel="Select One" itemValue="#{null}" noSelectionOption="true" />
    

    如果提交的值可解析为Long,则检查getAsObject():

    if (arg2 == null || !arg2.matches("[0-9]+")) {
        return null;
    }
    

    【讨论】:

    • 我仍然有同样的问题,我认为问题是 PrimeFaces 像你说的那样将标签视为项目值。但如果你能看到我的第二次更新,我认为这不是最好的解决方案,但它确实有效。
    • 如果你只使用itemValue="#{null}"呢?
    • 它也返回标签而不是值!
    • PrimeFaces 不太好。我会继续检查提交的值是否可解析为Long,如更新的答案所示。
    猜你喜欢
    • 2014-03-21
    • 2012-08-25
    • 2011-01-30
    • 1970-01-01
    • 2011-05-31
    • 2014-09-03
    • 2015-03-07
    • 1970-01-01
    • 2012-10-04
    相关资源
    最近更新 更多