我正在使用PrimeFaces在JSF中创建一个项目,我遇到了<p:SelectOneMenu>
的问题,特别是将一个对象的选定值转换为String。我已经编写了必需的Converter类,实现了toString()
和equals()
方法,我认为非常正确。但是,在一个<h:messages />
组件中,它无休止地给了我:
j_idt7:j_idt92: Validation Error: Value is not valid
j_idt7:j_idt98: Validation Error: Value is not valid
我必须选择属于一个较大形式的值。然后,根据所选的所有者(właściciel)和公司(firma),我将它们添加到数据库中。
这是我的<p:SelectOneMenu>
(两次 - 两个菜单):
<p:selectOneMenu value="#{wniosek.selectedWl}" var="w">
<f:selectItem itemLabel="Wybierz" itemValue=""/>
<f:selectItems value="#{wniosek.listaWl}" var="wlasciciel"
itemLabel="#{wlasciciel.nazwisko}" itemValue="#{wlasciciel}" />
<p:column>
#{w.nazwisko}
</p:column>
<f:converter converterId="WlascicielConverter" />
</p:selectOneMenu>
<h:outputText value="Nazwa firmy: "/>
<p:selectOneMenu value="#{wniosek.selectedFi}" var="f">
<f:selectItem itemLabel="Wybierz" itemValue=""/>
<f:selectItems value="#{wniosek.listaFi}" var="firma"
itemLabel="#{firma.nazwa}" itemValue="#{firma}" />
<f:converter converterId="FirmaConverter" />
<p:column>
#{f.nazwa}
</p:column>
</p:selectOneMenu>
这是我所有者的<p:SelectOneMenu>
的转换器类(同样我已经完成了公司的一个):
public class WlascicielConverter implements Converter {
int i = 0;
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
try {
if (arg2 == null || arg2.isEmpty()) {
return null;
}
String owner = arg2;
return WlascicielBean.findAnOwner(owner);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
if(arg2 == null) return null;
Wlasciciel owner = new Wlasciciel();
if(arg2 instanceof Wlasciciel) {
owner = (Wlasciciel)arg2;
System.out.println(owner.getNazwisko());
String surname = owner.getNazwisko();
return (surname != null) ? String.valueOf(surname) : null;
} else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString());
}
}
equals()
方法:
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof Wlasciciel)) return false;
Wlasciciel wl = (Wlasciciel)obj;
if (this.id_w != wl.getId_w()) return false;
if (!this.nazwisko.equals(wl.getNazwisko())) return false;
if (!this.imie.equals(wl.getImie())) return false;
if (!this.ulica.equals(wl.getUlica())) return false;
if (this.nr != wl.getNr()) return false;
if (this.lokal != wl.getLokal()) return false;
if (this.id_n != wl.getId_n()) return false;
return true;
}
你能给我一些关于解决这个问题的提示吗?我已经阅读了很多关于JSF中的转换器的教程,尝试了很多方法来改进它,但它仍然不起作用。我不知道......问题可能在我的代码中的其他地方?因为它的长度我不会在这里粘贴(当然,如果有必要,我会这样做)。
答案 0 :(得分:7)
总的来说,我认为你是在正确的方式,即使非英语代码让你真的很难理解你在那里做了什么...
会发生什么:你收集了一些东西。您的Converter运行该集合并在每个对象上调用getAsString()
。在浏览器中选择了某些内容后,value
(返回值getAsString()
)将传输到转换器,并将调用getAsObject()
。这是一个完全新的对象,并不一定是之前的集合之一(除非您的Converter实际上访问该集合并从那里获取)。之后,JSF将采用它用于生成selectOneMenu的集合,并将每个项目与转换器返回的项目进行比较。
这可能由equals()
或hashCode()
发生,具体取决于所使用的集合。所以你需要同时覆盖它们(实际上你应该这样做)。
如果JSF找不到集合中与转换器返回的对象相匹配的任何对象(equals为true,或者hashCode相同),则得到Validation Error: Value is not valid
。
我希望稍微清理一下这个过程。我的猜测是你必须实施hashCode()
,或者你的equals()
方法是错误的。总体设置是正确的。您需要调试并检查为什么JSF无法在列表中找到对象。