Außerhalb meines Tutorials, und daher entsprechend komprimiert, möchte ich an dieser Stelle über aktuelle Erfahrungen mit JSF berichten.

In einer WebApplikation kann sich der Anwender für diverse Dienste (Features) registrieren. Nach dem Einloggen erscheint eine Übersichtsseite, die ggf. zu einzelnen Features Informationen bereit stellt. Dazu verfügt die Anwendung über eine Bean, die als SessionController die gewählten Features via Fabrik instanziiert. Jedes Feature soll nun bei Bedarf selber einen Teil (Part) der Übersichtsseite zur Verfügung stellen. Da ein Part beliebig viele Komponenten umfassen darf, sind diese jeweils als <ui:composition> in einer eigenen Datei abgelegt. Die Idee war nun, via SessionController eine dynamische Liste der Dateinamen zur Verfügung zu stellen. Diese Liste sollte nun in einer Schleife <ui:repeat> abgearbeitet werden und mittels <ui:include> die Dateien einbinden:

<ui:repeat value="#{sessionController.parts}" var="part">
  <ui:include src="#{part}"/>
</ui:repeat>

Im SessionController existiert ein passende Methode

public List<String> getParts(){
    return parts;
}

Parts wiederum wird beim Registrieren der Features mit den Dateinamen gefüllt. Die Ausgabe jedoch bestand aus – Nichts.

Also, zur Kontrolle eine Ausgabe der Dateinamen eingebaut.

<ui:repeat value="#{sessionController.parts}" var="part">
  <h:outputText value="#{part}" style="background-color: green"/>
  <ui:include src="#{part}"/>
</ui:repeat>

Und siehe da, die Dateinamen werden korrekt ausgegeben.

Nun diese Variante, Zugriff auf das erste Element der Liste:

<ui:repeat value="#{sessionController.parts}" var="part">
  <h:outputText value="#{part}" style="background-color: green"/>
  <ui:include src="#{sessionController.parts[0]}"/>
</ui:repeat>

Nun wird der Inhalt der ersten registrierten Datei dargestellt – und sooft wiederholt wie es Dateieinträge insgesamt gibt. Eine Analyse des Verhaltens ergab, dass getParts jedoch nur einmal aufgerufen wird. Es scheint so, als ob der Inhalt von src="…" bereits vor Aufruf der Schleife ausgewertet wird. Das erklärt auch, warum im ersten Fall nichts ausgegeben wurde: Vor Ausführung der Schleife ist part nicht definiert.

Nutzt man jedoch anstelle von <ui:repeat> das Konstrukt <c:forEach> aus der JSP-Library, so funktioniert das Einfügen einer variablen Anzahl von Dateien völlig problemlos.

<c:forEach items="#{sessionController.parts}" var="part">
      <ui:include src="#{part}"/>
  </c:forEach>

Ein Bug in der Facelets-Implementierung?