Primefaces autocomplete-widget immer Fehler: die Eigenschaft 'label' not found on type java.lang.String
Ich bin nicht erfolgreich "p:autocomplete" - widget zu arbeiten...
Mit der autocomplete-widget, wie hier gezeigt...
<p:autoComplete id="abc" dropdown="true" value="#{testBean.parmMap['inputval']}" completeMethod="#{testBean.testList}" var="items" itemLabel="#{items.label}" itemValue="#{items}" converter="#{itemConverter}" ></p:autoComplete>
Ich erhalte die folgende Fehlermeldung...
javax.el.PropertyNotFoundException: /index.xhtml @18,245 itemLabel="#{items.label}": Eigenschaft 'label' not found on type java.lang.String
Ich nicht in der Lage zu bekommen Vergangenheit diesen Fehler. Nicht sicher, wo das problem liegt
--Ich habe die meisten relevanten code unten gezeigt. Vielen Dank für jede Unterstützung, die Sie mir geben können!
Hier ist die gesamte facelets-Seite - index.xhtml...
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:util="http://java.sun.com/jsf/composite/util"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
<title>testprimeac</title>
<meta charset="utf-8" />
</h:head>
<h:body>
<h:form id="form1">
<p:autoComplete id="abc" dropdown="true" value="#{testBean.parmMap['inputval']}" completeMethod="#{testBean.testList}" var="items" itemLabel="#{items.label}" itemValue="#{items}" converter="#{itemConverter}" ></p:autoComplete>
</h:form>
</h:body>
</f:view>
</html>`
Hier ist die "Element" Klasse...
package aaa.bbb.ccc.war;
public class Item
{
private String label;
private String value;
public String getLabel()
{
return label;
}
public void setLabel(String label)
{
this.label = label;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}
Hier ist die ItemConverter Klasse...
package aaa.bbb.ccc.war;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
public class ItemConverter implements Converter
{
@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue)
{
if (submittedValue.trim().equals(""))
{
return null;
}
else
{
itemList = getItemList();
try
{
for (Item item : itemList)
{
if (item.getValue().equalsIgnoreCase(submittedValue))
{
return item;
}
}
}
catch (Exception e)
{
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid item object"));
}
}
return null;
}
@Override
public String getAsString(FacesContext facesContext, UIComponent component, Object value)
{
if (value == null || value.equals(""))
{
return "";
}
else
{
return String.valueOf(((Item) value).getValue());
}
}
private static List<Item> itemList;
private static List<Item> getItemList()
{
if (null == itemList)
{
refData = getRefData();
itemList = refData.getTestList();
}
return itemList;
}
private static RefData refData;
private static RefData getRefData()
{
refData = (RefData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("refData");
if (null == refData)
{
refData = new RefData();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", refData);
}
return refData;
}
}
Hier ist der TestBean Klasse...
package aaa.bbb.ccc.war;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("testBean")
@Scope("request")
public class TestBean implements Serializable
{
private RefData refData;
private LinkedHashMap<String, String> parmMap;
public TestBean()
{
}
public Map<String, String> getParmMap()
{
refData = getRefData();
return refData.getParmMap();
}
public void setParmMap(LinkedHashMap<String, String> m)
{
refData = getRefData();
refData.setParmMap(m);
storeRefData(refData);
}
public void setTestList(List<Item> list) throws Exception
{
try
{
refData = getRefData();
refData.setTestList(list);
storeRefData(refData);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public List<Item> getTestList()
{
refData = getRefData();
return refData.getTestList();
}
private static RefData getRefData()
{
RefData refData = (RefData) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("refData");
if (null == refData)
{
refData = new RefData();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", refData);
}
return refData;
}
private static void storeRefData(RefData r)
{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("refData", r);
}
}
Hier ist die RefData-Klasse (bezeichnet in der TestBean)...
package aaa.bbb.ccc.war;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
public class RefData implements Serializable
{
public RefData() //(String key)
{
}
private static final Map<String, String> listBoxEntryMap;
static
{
Map<String, String> m = new LinkedHashMap<String, String>();
m.put("aaavalue", "aaalabel");
m.put("bbbvalue", "aablabel");
m.put("cccvalue", "abblabel");
m.put("dddvalue", "bbblabel");
m.put("eeevalue", "bbclabel");
m.put("fffvalue", "bcclabel");
m.put("gggvalue", "ccclabel");
m.put("hhhvalue", "ccalabel");
m.put("iiivalue", "caalabel");
m.put("jjjvalue", "aaclabel");
m.put("kkkvalue", "acclabel");
m.put("lllvalue", "bbalabel");
m.put("mmmvalue", "baalabel");
listBoxEntryMap = Collections.unmodifiableMap(m);
}
private Map<String, String> parmMap;
public Map getParmMap()
{
if (null == this.parmMap)
{
this.parmMap = new LinkedHashMap<String, String>();
this.parmMap.put("inputval", "");
}
return this.parmMap;
}
public void setParmMap(Map m)
{
this.parmMap = m;
}
List<Item> testList = new ArrayList<Item>();
public void setTestList(List<Item> data) throws IOException
{
testList = data;
}
public List<Item> getTestList()
{
try
{
if (null == testList || testList.isEmpty())
{
testList = getListOfItems();
}
return testList; //(list);
}
catch (Exception ex)
{
java.util.logging.Logger.getLogger(RefData.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static List<Item> getListOfItems()
{
List<Item> list = null;
try
{
Map<String, String> map = listBoxEntryMap;
Iterator iter = map.keySet().iterator();
list = new ArrayList<Item>();
Item item = null;
while (iter.hasNext())
{
String key = (String) iter.next();
String val = (String) map.get(key);
item = new Item();
item.setLabel(key);
item.setValue(val);
list.add(item);
}
}
catch (Exception e)
{
System.out.println("Exception during query call..." + e.getMessage());
e.printStackTrace();
}
return list;
}
}
FWIW - Hier ist die pom.xml (die auch die primefaces-Abhängigkeit)...
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aaa.bbb.ccc</groupId>
<artifactId>testprimeac-war</artifactId>
<packaging>war</packaging>
<version>1</version>
<name>testprimeac-war</name>
<url>http://maven.apache.org</url>
<properties>
<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
<jsf-version>2.1.11</jsf-version>
</properties>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
<finalName>testprimeac-${project.version}</finalName>
</build>
</project>
- Sollte die complete-Methode nicht als argument der String? Ist die Methode überhaupt aufgerufen wird?
Du musst angemeldet sein, um einen Kommentar abzugeben.
+1 für die Behauptungen, die Sie in Ihrem ersten Absatz: Sie haben zu viel Informationen über hier und der Konverter ist überflüssig, da man die Bindung an eine grundlegende
String
geben.Den zwei Kernfragen, die ich hier sehen Sind
Ihrer Wahl nicht zu verwenden, eine Typ-sichere Sammlung in Ihrem Wert verbindlich. Mit einem einfachen
LinkedHashMap
zu halten, String Werte werden wahrscheinlich Probleme verursachen, wie Sie gespeichert werden, wie Objekte, ich denke nicht, dass der compiler ist dazu verpflichtet, alle autoboxing für dich hier.Ihre backing
completeMethod
Umsetzung ist im wesentlichen returninglkp ein speichern derString
Objekte. Dies ist, was bietet die variable fürvar
in der Auto-vervollständigen . Um das offensichtliche, Sie können nicht rufen SiegetLabel()
auf, dass.Können Sie entweder 2 Möglichkeiten
Ändern Sie Ihre Daten speichern, um eine typesafe
LinkedList
Streicher , Verlieren Sie den Konverter und Sie sollten in Ordnung sein. Ihrevar
werden plainitem
unditemLabel
unditemValue
sowohl#{item}
.Implementieren ein POJO zu Kapseln, das selection-Objekt, halten Sie den Konverter und dann sichern Sie Ihre Daten speichern, wird eine einfache Liste Ihrer POJO und auch Ihre Auswahl wird eine Instanz der POJO-statt eines String -
EDIT: Mit deinen Erklärungen, das problem ist ein Ergebnis der Unterschiede in der Art zurück durch die AutoVervollständigen-dropdown (Typ
item
) und dievalue
Bindung der AutoVervollständigen-auf der backing-bean (String
- Typ). Der zurückgegebene Typ von der dropdown-Auswahl muss der gleiche sein wie der Typ, den Sie verbindlich in der backing-bean.value
von der AutoVervollständigen-zu einem eigenständigen POJO in Ihrer backing-bean, als gegen das, was Sie zu tun versuchen, mit der Karte jetzt. Sie haben dieitemValue
Attribut ein POJO-Typ, versuchen, zu zwingen, es zu einerString
geben wird scheiternvalue
Bindung sollte vom gleichen Typ sein wie die#{items}
Attribut, d.h. wenn#{items}
auswertet, um eine Art vonString
,value
sollten gebunden werden, um eine Art vonString
. In Ihrem Fall jedoch#{items}
ist der Typitem
und sovalue
gebunden werden soll derselben Art