简体   繁体   English

h:selectOneMenu:验证错误

[英]h:selectOneMenu : validation error

I defined the following drop down box in my page: ... 我在页面中定义了以下下拉框:...

<td>
  <h:selectOneMenu id="bootenvironment1" value="#{detailModel.selectedBootenvironment1}"
                   disabled="#{detailModel.mode == detailModel.viewMode}">
    <f:selectItems value="#{detailModel.availableBootenvironments}"/>
  </h:selectOneMenu>
</td>

In my model I have: 在我的模型中,我有:

...
  private Map<String, Bootenvironment> availableBootenvironments;

  public DefinitionDetailModel()
  {
    super();
  }

  public String getSelectedBootenvironment1()
  {
    if (((Definition) getAfterObject()).getBootenvironment1() != null)
    {
      return ((Definition) getAfterObject()).getBootenvironment1().getEnvironmentName();
    }

    return "--Please select one--";
  }

  public void setSelectedBootenvironment1( String selectedBootenvironment )
  {
    ((Definition) getAfterObject()).setBootenvironment1(availableBootenvironments.get(selectedBootenvironment));
  }
  ...

And in the controller I set the availableBootenvironments map: 在控制器中我设置了availableBootenvironments地图:

private void fetchBootenvironments()
  {
    ...
    @SuppressWarnings( "unchecked" )
    List<Bootenvironment> bootenvironments = (List<Bootenvironment>) ...

    Map<String, Bootenvironment> availableBootenvironments = new HashMap<String, Bootenvironment>();

    availableBootenvironments.put("--Please select one--", null);

    for(Bootenvironment bootenvironment : bootenvironments)
    {
      availableBootenvironments.put(bootenvironment.getEnvironmentName(), bootenvironment);
    }

    ((DefinitionDetailModel) detailModel).setAvailableBootenvironments(availableBootenvironments);
  }

The problem is that when I click a button in the page (which is bound to an action), I get the error: 问题是,当我单击页面中的一个按钮(绑定到一个动作)时,我收到错误:

detailForm:bootenvironment1: Validation error: value is not valid. detailForm:bootenvironment1:验证错误:值无效。

I don't understand where the error is; 我不明白错误在哪里; the value for selectItems is a map with the object's name-field(so a string) as key and the object itself as value. selectItems是一个映射,其中对象的name-field(字符串)为键,对象本身为value。 Then the value for the default selected ( value="#{detailModel.selectedBootenvironment1}" ) is a string too as you can see in the getter/setter method of the model. 然后为默认选中(该 value="#{detailModel.selectedBootenvironment1}" )是一个字符串太,你可以在模型中的吸气剂/ setter方法见。

Another problem (maybe related to the previous one) is that when the page first loads, the default selected value should be --Please select one--- as the getBootenvironment1() returns null , but this does not happen: another one from the list is selected. 另一个问题(可能与前一个问题有关)是当页面首次加载时,默认选择的值应为 - 请选择一个---因为getBootenvironment1()返回null ,但这不会发生:另一个来自列表已被选中。

Can you please help me understanding what/where am I doing wrong? 你能帮我理解我做错了什么/我在哪里?

EDIT 编辑

I implemented the Converter as you said: 我按照你的说法实现了转换器:

@FacesConverter( forClass = Bootenvironment.class )
public class BootenvironmentConverter implements Converter
{

  @Override
  public String getAsString( FacesContext context, UIComponent component, Object modelValue ) throws ConverterException
  {
    return String.valueOf(((Bootenvironment) modelValue).getDbId());
  }

  @Override
  public Object getAsObject( FacesContext context, UIComponent component, String submittedValue ) throws ConverterException
  {
    List<Bootenvironment> bootenvironments = ... (get from DB where dbid=submittedValue)

    return bootenvironments.get(0);
  }

}

But now I have the following error: 但现在我有以下错误:

java.lang.ClassCastException: java.lang.String cannot be cast to ch.ethz.id.wai.bootrobot.bo.Bootenvironment java.lang.ClassCastException:java.lang.String无法强制转换为ch.ethz.id.wai.bootrobot.bo.Bootenvironment

You will get this error when the selected item value doesn't pass the equals() test on any of the available item values. 当所选项目值未通过任何可用项目值的equals()测试时,您将收到此错误。

And indeed, you've there a list of Bootenvironment item values, but you've bound the property to a String which indicates that you're relying on the Bootenvironment#toString() value being passed as submitted value and that you aren't using a normal JSF Converter at all. 实际上,你有一个Bootenvironment项值列表,但你已经将属性绑定到一个String ,表明你依赖于Bootenvironment#toString()值作为提交值传递而你不是完全使用普通的JSF Converter A String can never return true on an equals() test with an Bootenvironment object. 在使用Bootenvironment对象的equals()测试中, String永远不会返回true

You'd need to provide a Converter which converts between Bootenvironment and its unique String representation. 您需要提供一个Converter ,它在Bootenvironment及其唯一的String表示之间进行Converter Usually, the technical ID (such as the autogenerated PK from the database) is been used as the unique String representation. 通常,技术ID(例如来自数据库的自动生成的PK)被用作唯一的String表示。

@FacesConverter(forClass=Bootenvironment.class)
public class BootenvironmentConverter implements Converter {

    @Override
    public void getAsString(FacesContext context, UIComponent component, Object modelValue) throws ConverterException {
        // Write code to convert Bootenvironment to its unique String representation. E.g.
        return String.valueOf(((Bootenvironment) modelValue).getId());
    }

    @Override 
    public void getAsObject(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
        // Write code to convert unique String representation of Bootenvironment to concrete Bootenvironment. E.g.
        return someBootenvironmentService.find(Long.valueOf(submittedValue));
    }

}

Finally, after implementing the converter accordingly, you should be able to fix the selectedBootenvironment1 property to be a normal property without any mess in getter/setter: 最后,在相应地实现转换器之后,您应该能够将selectedBootenvironment1属性修复为普通属性,而不会在getter / setter中造成任何混乱:

private Bootenvironment selectedBootenvironment1;

public Bootenvironment getSelectedBootenvironment1() {
    return selectedBootenvironment1;
}

public void setSelectedBootenvironment1(Bootenvironment selectedBootenvironment1) {
    this.selectedBootenvironment1 = selectedBootenvironment1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM