当前位置: 首页 > 知识库问答 >
问题:

Primefaces p:POJO中字符串字段的autcomplete问题

韩淇
2023-03-14

我正在构建一个JSF表单,其中包含一个primefaces p:autoComplete组件。下面是我的xhtml页面的摘录,显示了有关自动完成组件的相关信息。

<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)。

新包装的方法。lookupActivated()返回一个列表

<代码>宇宙卡。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)
    .
    .

有人知道我做错了什么吗?您可以在这里找到一个非常相似的问题,但不幸的是它没有得到回答。我愿意提供有关我的代码的更多详细信息。

更新:

实际上,一切都很正常:我在p:autocomplete的下拉列表中看到了正确的值。当我选择一个值时,备份bean(newBacking)中的数据会相应地更新。我只是无法摆脱这个异常,然而,它对我的页面的执行没有任何影响。

我尊重标签的约束,即value属性和itemValue属于同一类型(两个字符串)。唯一不太好的是系统试图转换List中的List,我不知道为什么或何时,但转换失败(以及随后的异常)对我页面的行为没有任何影响。

更新:

这是该项目的一个非常简化的版本(netbean)的链接。该项目的相关文件也列在下面。

test.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();
   }

}

共有1个答案

郎魁
2023-03-14

您的完整方法是返回一个复杂类的实例,因此您需要一个转换器。如果没有转换器的存在,您的组件会认为它与字符串一起工作,并在获取值和标签属性时尝试引用它。尝试使用它,看看它是否有效,但我强烈建议根据您的需要创建您自己的转换器:

@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;
        }

    }
 类似资料:
  • 问题内容: 我有一个问题:是否可以通过将一个DATE字符串“ 2010-04-29”与以DATETIME(2010-04-29 10:00)存储的字符串进行比较来从MySQL数据库中进行选择? 我有一个过滤数据的日期选择器,我想按DATETIME字段查询表,如下所示: …,我想获得DATETIME值为“ 2010-04-29 10:00”的行。 有什么建议么?谢谢。 问题答案: 使用以下内容: 仅

  • 问题内容: 我在寻找一个struct的字符串字段遍历,所以我可以做一些清理/验证(与,等)。 现在,我有一个混乱的开关盒,它并没有真正的可扩展性,而且由于这并不是我的应用程序(Web表单)的热点,因此在这里利用杠杆作用似乎是一个不错的选择。 我对于如何实现此功能有点障碍,反射文档对我来说有点困惑(我一直在研究其他一些验证包,但是它们太笨重了,我正在使用大猩猩/模式已用于解组部分): 遍历该结构 对

  • 问题内容: 我有一个数据类型为char(20)的db表。我不允许将其更改为varchar。 我正在写一个映射到该表的JPA实体。我希望在我的实体类中表示此列的字符串字段始终包含调整后的值,而不是用数据库中存在的空格填充的20个字符的值。 我看不到任何简单的方法来做到这一点。(注释会震撼!)。此刻,我只是从我的getter()返回一个修整后的值,但这感觉像是一团糟。 谷歌搜索对此没有帮助。有任何想法

  • 问题内容: 我在SQL数据库中有一个字符串,表示一个URL。有些网址很短,有些很长。我真的不知道这是我可能遇到的最长的URL,所以为了安全起见,我会采用较大的值,例如256或512。 当我定义最大字符串长度时(例如,使用SQLAlchemy): 即使实际的字符串较短,这是否也会占用每一行的空间(存储空间)? 我假设这与实现细节有关。我正在使用postgreSQL,但对sqlite和mysql也很感

  • 我在映射中设置了一个日期字段,如下所示: 在我的应用程序中,字段group psAssignedDate最初设置为空字符串。分配组时,将生成unix时间戳并将其存储在字段中。我试图使用elasticsearch的批量更新功能来引入一组带有“AssignedDate”的文档,因为还没有分配组。不过,Elasticsearch不会对文档进行索引。这在日志文件中: 弹力搜索似乎支持JSON空值...我需

  • 我们试图在CLOB字段中应用子字符串funciton来修剪前4000个字符。我们得到以下错误信息。 下面是我们使用的查询: 错误报告: SQL错误:ORA-22835:缓冲区太小,CLOB无法进行字符转换或BLOB无法进行原始转换(实际:8000,最大值:4000) 22835。00000-“缓冲区太小,无法将CLOB转换为CHAR或BLOB转换为RAW(实际:%s,最大值:%s)” *原因:试图