使用NetBeans,我生成了Hibernate映射文件和一组POJO。我还从实体类(生成的POJO)生成了一组JSF页面。JSF生成的页面和实体selectOneMenu
现在,我试图添加一个下拉菜单,使我能够选择其中一个参与者。
<h:selectOneMenu value="#{measurementController.sensor}">
<f:selectItems value="#{sensorController.itemsAvailableSelectOne}" />
</h:selectOneMenu>
getItemsAvailableSelectOne()调用此方法:
public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
int size = selectOne ? entities.size() + 1 : entities.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (selectOne) {
items[0] = new SelectItem("", "---");
i++;
}
for (Object x : entities) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}
在measurementController类我有这样的:
private Sensor sensor;
public Sensor getSensor() {
return this.sensor;
}
public void setSensor(Sensor sensor) {
this.sensor = sensor;
}
无论我做什么,我得到Validation Error: Value is not valid
错误,当我选择的任何条目下拉式菜单。为什么?
我有一种感觉,我失去了一些非常明显的东西,但我无法看到它。
编辑:
挖掘低谷生成的代码,我发现一个现有的转换器类:
@FacesConverter(forClass=Sensor.class)
public static class SensorControllerConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
SensorController controller = (SensorController)facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "sensorController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Sensor) {
Sensor o = (Sensor) object;
return getStringKey(o.getIdSensor());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: "+SensorController.class.getName());
}
}
}
当我踏上槽这一切似乎做工精细的调试器的代码。首先调用getAsObject方法,将所选项目作为参数,返回值为Sensor对象。
然后调用返回null(存储在measurementController类中的当前值)的getSensor()方法。
最后,调用下拉菜单中的每个项目的getAsString()方法。我认为这是渲染响应阶段的一部分,与验证无关。
我不敢相信我已经浪费了三天的时间了!我怎么能这么愚蠢。我没有实现equals方法。更糟糕的是 - 在我看来,验证器必须比较两个Sensor实例,并且我实现了equals方法 - 通过引用而不是按值比较Integer。感谢一堆提示。 – skajfes 2010-09-23 20:24:23
不客气。你可以在[这个答案]中找到一些提示(http://stackoverflow.com/questions/3181339/right-way-to-implement-equals-contract/3181374#3181374)。 – BalusC 2010-09-23 20:34:17