我正在构建一个 JSF 表单,其中包含 primefaces p:autoComplete 组件。 以下是我的 xhtml 页面的摘录,显示了有关 autoComplete 组件的相关信息。
<p:autoComplete
value="#{curAttribute.value}"
completeMethod="#{newBacking.lookupActivated}"
var="curEntry"
itemLabel="#{curEntry.classname}"
itemValue="#{curEntry.id}"
emptyMessage="Start typing..."/>
请注意 curAttribute
是 CosmoAttribute
的一个实例类,并且 CosmoAttribute.value
是一个字符串(当然,CosmoAttribute
具有其字段的所有 getter 和 setter)。
方法newBacking.lookupActivated()
返回 List<CosmoCard>
.
CosmoCard.classname
和CosmoCard.id
都是字符串。
我知道我正在使用 POJO,但由于我的所有值都是来自 POJO 的字符串字段,所以我认为我不需要转换器。无论如何,我的自动完成字段工作正常,但是当我选择一个项目时,出现以下异常:
SEVERE: Error Rendering View[/test.xhtml]
javax.el.PropertyNotFoundException: /test.xhtml @98,68 itemLabel="#{curEntry.id}": The class 'java.lang.String' does not have the property 'id'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at org.primefaces.component.autocomplete.AutoComplete.getItemLabel(AutoComplete.java:148)
.
.
Caused by: javax.el.PropertyNotFoundException: The class 'java.lang.String' does not have the property 'id'.
at javax.el.BeanELResolver.getBeanProperty(BeanELResolver.java:730)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:351)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
.
.
有人知道我做错了什么吗?您可以找到very similar question here ,但不幸的是没有得到答复。我愿意提供有关我的代码的更多详细信息。
更新:
实际上,一切正常:我在 p:autocomplete 的下拉列表中看到了正确的值。当我选择一个值时,支持 bean (newBacking) 中的数据会相应更新。我只是无法摆脱异常,但是,这对我的页面的执行没有任何影响。
我尊重标签的约束,即 value 属性和 itemValue 具有相同的类型(都是字符串)。唯一不太正常的是系统尝试将 List 转换为 List,我不知道为什么,也不知道何时,但是转换失败(以及随后的异常)不会对我的页面的行为。
更新:
这里是 very simplified version of the project 的链接(网 bean )。下面还列出了该项目的相关文件。
测试.xhtml
<h:body>
<h:form id="form">
<p:dataTable var="curAttribute" value="#{newBacking.card.attributes}">
<p:column >
THE CURSED FIELD <br /><br />
<p:autoComplete
value="#{curAttribute.value}"
completeMethod="#{newBacking.lookupActivated}"
var="curEntry"
itemLabel="#{curEntry.code}"
itemValue="#{curEntry.id}">
</p:autoComplete>
</p:column>
</p:dataTable>
</h:form>
newBacking.java
@Named()
@SessionScoped
public class NewBacking implements Serializable {
private CosmoCard card;
private String currentCardClassname = "";
@PostConstruct
public void init() {
Random randomGenerator = new Random();
card = new CosmoCard();
card.setId("ID" + randomGenerator.nextInt(1000));
CosmoAttribute myLA = new CosmoAttribute();
myLA.setLabel("LookupAttributeLabel");
myLA.setValue("LookupAttributeValue");
card.getAttributes().add(myLA);
}
public CosmoCard getCard() {
return card;
}
public String getCurrentCardClassname() {
return currentCardClassname;
}
public void setCurrentCardClassname(String currentCardClassname) {
this.currentCardClassname = currentCardClassname;
}
public List<CosmoCard> lookupActivated(String tgtQuery) {
Logger.getLogger(NewBacking.class.getName()).info("[NewBacking.lookupActivated()] Query: " + tgtQuery);
return CosmoCardList.generateCardList(10).getCards();
}
}
最佳答案
您的完整方法正在返回一个复杂类的实例,因此您需要一个转换器。如果没有转换器的存在,您的组件会认为它正在处理字符串,并在获取值和标签属性时尝试引用它。尝试使用它,看看它是否有效,但我强烈建议根据您的需要创建您自己的转换器:
@FacesConverter("anySelectConverter")
public class AnySelectConverter implements Converter{
private static Map<Object, String> entities = new ConcurrentHashMap<Object, String>();
@Override
public String getAsString(FacesContext context, UIComponent component, Object entity) {
// TODO : Fix
if(entity == null)
return "";
synchronized (entities) {
if (!entities.containsKey(entity)) {
String uuid = UUID.randomUUID().toString();
entities.put(entity, uuid);
return uuid;
} else {
return entities.get(entity);
}
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
for (Entry<Object, String> entry : entities.entrySet()) {
if (entry.getValue().equals(uuid)) {
return entry.getKey();
}
}
return null;
}
}
关于java - Primefaces p :autcomplete issues with String field in POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26757813/