java - Primefaces p :autcomplete issues with String field in POJO

标签 java jsf primefaces autocomplete facelets

我正在构建一个 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..."/>

请注意 curAttributeCosmoAttribute 的一个实例类,并且 CosmoAttribute.value是一个字符串(当然,CosmoAttribute 具有其字段的所有 getter 和 setter)。

方法newBacking.lookupActivated()返回 List<CosmoCard> .

CosmoCard.classnameCosmoCard.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/

相关文章:

java - 如何解析 cvc-pattern-valid : Value '' is not facet-valid with respect to pattern problem

java - KAFKA 与现代内存内存数据网格 (IMDG) 相比

javascript - 禁用 p :calendar? 中的特定日期

javascript - 创建后向 (primefaces) jquery 日历添加选项

java - 如何在 JSF 2 中指定 body id 属性?

java - 使用 Primefaces 在文件系统上上传文件

java - 显示 3D 地形 Mapbox v10 Android

java - 如何以最简单的方式在同一个JSP页面中显示文本和图像?

ajax - a4j :commandButton and h:commandButton with a4j:ajax in it 之间的区别

jsf - 当使用惰性数据表时,另一个组件无法更新/第二个组件数据落后于一个请求