2012-05-23 2 views
6

Ich habe folgende zwei einfache POJOs:Kein Zugriff auf verschachtelte Eigenschaft in Managed Bean innerhalb p: Spalten

class Person { 
    String name 
    Address address; 
    //and of course the getter/setter for the attributes 
} 

class Address { 
    String city; 
    //also getter/setter for this attribute 
} 

Und ein Backing Bean:

@ManagedBean 
@RequestScoped 
class PersonController { 

    private List persons; 
    private List<String> columns = Arrays.toList("name", "address.city"); 
    //of course getter/setter 
} 

Jetzt möchte ich eine Datatable erstellen.

<p:dataTable var="person" value="#{personController.persons}" columnIndexVar="index"> 
    <p:columns var="column" value="#{personController.columns}"> 
     <h:outputText value="#{person[column]}"/> 
    <p:columms> 
</p:dataTable> 

Als ich dies ausführen bekomme ich eine ServletException:

Die Klasse Person hat nicht die Eigenschaft 'address.city'.

Aber wenn ein Versuch, die Eigenschaft Stadt wie dies in p zuzugreifen: Spalten:

<h:outputText value="#{person.address.city}"/> 

ist in Ordnung Alles.

Warum kann ich nicht auf eine verschachtelte Eigenschaft wie diese #{person['address.city']} zugreifen? Und wie kann ich darauf innerhalb p:columns zugreifen?

+0

Das '' Tag existiert nicht. Übergeneralisieren Sie nicht das PrimeFaces '' Tag? – BalusC

+0

Ja. Tut mir leid, ich werde es ändern. –

Antwort

8

Geschachtelte Bean-Eigenschaften in einem geschweiften Notationszeichenfolgenausdruck wie #{person['address.city']} werden standardmäßig nicht unterstützt. Sie benötigen grundsätzlich eine #{person['address']['city']}.

Sie benötigen eine benutzerdefinierte ELResolver hier. Am einfachsten ist es, die bestehende BeanELResolver zu erweitern.

Hier ist ein Kick-off Beispiel:

public class ExtendedBeanELResolver extends BeanELResolver { 

    @Override 
    public Object getValue(ELContext context, Object base, Object property) 
     throws NullPointerException, PropertyNotFoundException, ELException 
    { 
     if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) { 
      return null; 
     } 

     String propertyString = property.toString(); 

     if (propertyString.contains(".")) { 
      Object value = base; 

      for (String propertyPart : propertyString.split("\\.")) { 
       value = super.getValue(context, value, propertyPart); 
      } 

      return value; 
     } 
     else { 
      return super.getValue(context, base, property); 
     } 
    } 

} 

, um sie zu erhalten zu laufen, registrieren, wie in faces-config.xml folgt:

<application> 
    <el-resolver>com.example.ExtendedBeanELResolver</el-resolver> 
</application> 
+0

Danke für Ihre schnelle Antwort. Ich werde es versuchen! –

+0

Es funktioniert gut. Danke vielmals. –

+0

Gern geschehen. – BalusC

1

Neben @BalusC Antwort, die ich einen Scheck für PrimeResourceHandler hinzufügen musste . Andernfalls sind alle Auflösungen von # {resource ...} wie # {resource ['primefaces: spacer/dot_clear.gif']} in der Datei 'primefaces.css' fehlgeschlagen, und der Ausgabestream der analysierten CSS-Datei wird beschädigt.

public class ExtendedBeanELResolver extends BeanELResolver { 

    private static final String PRIMEFACES_RESOURCE_PREFIX = "primefaces:"; 

    @Override 
    public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, 
      PropertyNotFoundException, ELException { 
     if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map 
       || base instanceof Collection || base instanceof PrimeResourceHandler) { 
      return null; 
     } 

     String propertyString = property.toString(); 

     if (!propertyString.startsWith(PRIMEFACES_RESOURCE_PREFIX) && propertyString.contains(".")) { 
      Object value = base; 

      for (String propertyPart : propertyString.split("\\.")) { 
       value = super.getValue(context, value, propertyPart); 
      } 

      return value; 
     } else { 
      return super.getValue(context, base, property); 
     } 
    } 
}