[英]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.