Jakarta Faces
# Jakarta Faces

Jakarta Faces (JSF; früher Jakarta Server Faces, davor JavaServer Faces) ist ein Framework-Standard zur Entwicklung von grafischen Benutzeroberflächen für Webanwendungen. Basierend auf Servlets und JSP-Technik, gehört JSF zu den Webtechnologien der Jakarta EE. Mit Hilfe von JSF kann der Entwickler auf einfache Art und Weise Komponenten für Benutzerschnittstellen in Webseiten einbinden und die Navigation definieren. Voraussetzungen für die Entwicklung von JSF-Content sind das JDK, ein Servlet-Container (z. B. Apache Tomcat) und Grundlagenverständnis von HTTP und der Programmiersprache Java. Zur Vereinfachung der Entwicklung kann eine Integrierte Entwicklungsumgebung verwendet werden.

## Komponenten

Um Redundanzen im Code zu vermindern und die Wiederverwendbarkeit des UI Codes über mehrere Projekte zu verbessern, können Komponenten erstellt und verwendet werden. JSF-Komponenten unterliegen einer hierarchischen Struktur. Ähnlich der Java-Swing-API gibt es in JSF Container-Komponenten, die Komponenten enthalten können. Um die Anwendung besser zu strukturieren, wird strikt zwischen Modell, Präsentation und Steuerung getrennt, wie es das Model-View-Controller-Konzept vorsieht.

Ein zentrales Konzept von Jakarta Server Faces ist die View. Dabei handelt es sich um eine Baumstruktur aus JSF-Komponenten. Eine solche Struktur kommt genau einmal pro Aufruf vor, bei Verwendung von JavaServer Pages (JSP) also einmal pro Seite. Die View wird am Anfang des JSF-Lebenszyklus aufgebaut, direkt nach Eintreffen der Anforderung vom Client. In der letzten Phase des Lebenszyklus werden die Komponenten der Views mit der Wurzel beginnend rekursiv aufgerufen, um die Antwort, beispielsweise eine HTML-Seite, zu erzeugen. Die Controller-Komponente, welche Benutzereingaben steuert, kann in JSF über eigene Komponenten oder mit einem sogenannten Handler implementiert werden. Diese sind meist mit Java geschrieben. Die eigentliche Logik der Applikation findet im Model statt. Bei JSF sind die Model-Komponenten sogenannte JavaBeans (Java-Klassen), die vom Container verwaltet werden. JSF-Web-Anwendungen besitzen in der Regel keinen nennenswerten HTML-Code. Der HTML-Code wird erst im Quellcode der generierten Seite sichtbar. JSF-Komponenten besitzen eigene Renderer. Diese Renderer wandeln die mit JSF geschriebenen Seiten in HTML-Code um, so dass jeder HTML-Web-Browser die Seite darstellen kann. Eigene Renderer können für andere Ausgabeformate geschrieben werden.

## Lebenszyklus

Die Spezifikation der Jakarta Server Faces definiert einen sogenannten Lebenszyklus, den eine JSF-Anwendung mit jedem Aufruf erneut durchläuft. Dieser Lebenszyklus ist in sechs Phasen aufgeteilt.

* Restore View („Sicht wiederherstellen“) wählt anhand der eingehenden Anforderung eine Sicht (View) aus und baut den dazu passenden Komponentenbaum auf.
* Apply Request Values („Anforderungsparameter anwenden“) extrahiert Parameter aus der Anforderung (üblicherweise ein HTTP-Post-Request) und weist sie den passenden JSF-Komponenten zu, beispielsweise Eingabefeldern.
* Process Validations („Validierung ausführen“) überprüft die Gültigkeit der zuvor ermittelten Eingaben. Dazu werden eigene Konverter- und Validator-Objekte verwendet, die den Komponenten in der View-Definition zugewiesen wurden.
* Update Model Values („Modell aktualisieren“) weist den Modellobjekten die zuvor ermittelten Werte zu.
* Invoke Application („Anwendung aufrufen“) ruft durch die Anwendung definierte Methoden auf, beispielsweise wenn ein Button betätigt wurde.
* Render Response („Antwort wiedergeben“) erzeugt schließlich die Antwort auf die ursprüngliche Anfrage, beispielsweise eine HTML-Seite. Hierzu werden sogenannte Renderer aufgerufen, die den View-Komponenten zugeordnet sind.

Treten Fehler auf oder soll als Antwort beispielsweise eine HTML-Seite aufgerufen werden, die keine JSF-Komponenten enthält, so können einzelne Phasen übersprungen werden.

## Implementierungen

Die JSF-Spezifikation wird von einer Reihe Frameworks implementiert. Diese werden meist in JEE-Containern mitgeliefert und lassen sich oft nur unter Schwierigkeiten austauschen. Dazu gehören beispielsweise:

* Mojarra, die Referenzimplementierung von Jakarta Server Faces im Rahmen des GlassFish-Java-Anwendungsservers
* Apache MyFaces, die Implementierung von der Apache Software Foundation

### Komponentenframeworks

Komponentenframeworks erweitern JSF-Implementierungen. Mit ihnen können beispielsweise JavaScript und Ajax einfacher generiert werden.

* ICEfaces, Opensource-Framework von ICEsoft; basierend auf dem Woodstock GUI-Komponentenframework.
* PrimeFaces
* BootsFaces
* Mojarra Scales
* J4Fry
* xulfaces
* jQuery4jsf
* MyFaces Trinidad von der Apache Software Foundation
* MyFaces Tobago von der Apache Software Foundation
* MyFaces Tomahawk von der Apache Software Foundation
* Oracle ADFs Komponentenbibliothek, ein kommerzielles Java-Framework für Java-Enterprise-Applikationen (hat einige Kernfunktionalitäten mit Apache MyFaces Trinidad gemeinsam)
* RichFaces inkl. Ajax4jsf von Red Hat (ehemals Exadel) [Entwicklung im Juni 2016 eingestellt]

Verschiedene Unternehmen bieten auch grafische Entwicklungswerkzeuge für JSF an.

## Standardisierung

Die JSF-Spezifikation wurde im Rahmen des Java Community Process (JSR 127) von einer Reihe bekannter Unternehmen entwickelt und am 27. Mai 2004 in der Version 1.1 verabschiedet. Am 11. Mai 2006 wurde die Version 1.2 (JSR 252) veröffentlicht. Die aktuelle Version der Referenzimplementierung Mojarra 1.2_15 erschien am 24. September 2010.

Die Version 2.0 (JSR 314) brachte insbesondere Ajax-Unterstützung mit sich. Sie ist seit Dezember 2009 erhältlich und kann auf der Oracle-Homepage heruntergeladen werden. Eine Implementierung sowie ein Tutorial und weitere Dokumentation stehen im Mojarra Project zur Ansicht und zum Download bereit, die derzeitige Version der Mojarra Referenzimplementierung lautet 2.0.8. Bei JSF 2.1 handelt es sich um einen Wartungsrelease von Version 2.0, freigegeben wurde die Spezifikation am 21. November 2010, die aktuelle Version der Mojarra Referenzimplementierung lautet 2.1.6. Die Version JSF 2.2 wurde am 15. April 2013 freigegeben. Sie enthält insbesondere folgende Neuerungen: Unterstützungen für HTML5 wie beispielsweise das Durchreichen von neuen HTML5 Attributen beziehungsweise Custom Data Attributen, Erweiterte Flow Unterstützung durch einen eigenen Contexts and Dependency Injection Scope (@FlowScoped) ergänzend zum bereits existierenden ConversationScope (@ConversationScoped), Zustandslose Views durch Setzen des Attributes transient="true", sowie Resource Library Contracts, ein erster Ansatz um Ressourcen für wählbares Aussehen zur Verfügung zu stellen.

Jakarta Server Faces umfasst

* Eine Tag-Bibliothek zur Einbindung der JSF-Oberflächenkomponenten in JavaServer Pages oder in einem Facelet,
* eine Java-API zur Kontrolle von Bedienelementen der Benutzerschnittstelle. Dies schließt auch die Behandlung von Ereignissen, die Validierung der Eingabe, Navigation und Unterstützung für Internationalisierung mit ein.
* Eine eigene Expression Language (EL), welche als Grundlage die JSP-Technik hat. In JSF werden EL-Ausdrücke in folgender Schreibweise geschrieben: #{1+2}, #{PI/2}, #{handler.attribut}

Der Hauptunterschied zur JSP-EL liegt nicht nur an dem vorangestellten #, sondern auch in der Sprache selbst. Die JavaServer Pages-Expression Language ist dynamischer als die JSF-Expression Language (JSF-EL). Die JSF-EL ist zustandsbehafteter (statischer), vergleichbar mit den Java-Swing-Komponenten. Die Expression Language von JSF hat eine bidirektionale Wertebindung, d. h., sie kann Properties (Eigenschaften einer Bean) lesen (z. B. Initialisierung) und schreiben (z. B. Werte an Property binden). Folgende Tabelle zeigt Ausdrucksarten der Expression Language von JSF:

| Expression Language Ausdruck | Beispiel |
| - | - |
| Wertebindung | #{handler.name} – name ist eine Eigenschaft der handler-Bean |
| Methodenbindung | #{handler.actionMethode} – actionMethode ist eine Methode der handler-Bean |
| Arithmetisch / Logisch | #{5+8}, #{65/5}, #{99>90}, #{!(5>6)||(8<4)} |

Bei der Entwicklung von JSF-Seiten sollte auf die Kombination von JSP- und JSF-Ausdrücken verzichtet werden, da das zu Problemen führen kann.

## Managed Bean Mechanismus

Der Managed Bean Mechanismus erlaubt es, POJOs mit einem bestimmten Gültigkeitsbereich (englisch scope) und Initialwerten für sogenannte Managed Properties (auch im Spezialfall, dass das Bean vom Typ java.util.List oder java.util.Map ist), zu versehen. Dies kann entweder in der XML-Konfiguration der JSF-Applikation oder ab JSF 2.0 (min. Java Version 1.5) als zusätzliche Option mit Annotations direkt im Bean konfiguriert werden. Managed Beans können mit der Hilfe von EL-Ausdrücken direkt (z. B. in Facelets) verwendet werden.

### Gültigkeitsbereiche von Managed Beans (engl. scope)

Der Gültigkeitsbereich einer Bean legt fest, wie lange eine Bean existiert und unter welchen Umständen sie als existent angesehen wird. Wie bereits erwähnt, können Managed Beans mit Managed Properties in andere Managed Beans injiziert werden. Dabei ist zu beachten, dass die injizierte Bean einen größeren Gültigkeitsbereich hat als die Bean, in die sie injiziert wird. Der Grund dafür ist, dass die injizierte Bean andernfalls potenziell kurzlebiger ist als die Bean, in welche sie injiziert wird.

Folgende Tabelle zeigt alle Gültigkeitsbereiche in der aktuellen JSF-Version (2.1) sortiert nach der Größe des Gültigkeitsbereichs mit dem kurzlebigsten Scope zu oberst.

| Wert XML <managed-bean-scope> | Annotation | Gültigkeitsbereich |
| - | - | - |
| request | @RequestScoped | gültig, solange der aktuelle Request behandelt wird |
| view | @ViewScoped | gültig, solange die aktuelle View gültig ist |
| session | @SessionScoped | gültig für eine Session |
| application | @ApplicationScoped | gültig für die Applikation |
| none | @NoneScoped | gültig wie die Bean, in welche sie injiziert wurde |

## JSF-Standard Tags (nicht vollständig)

| Tag-Name | Beschreibung |
| - | - |
| <f:view> | Erzeugt Instanz der Klasse javax.faces.component.UIViewRoot. Alle enthaltenen Komponenten werden Child-Komponenten der View. |
| <h:form> | Bindet Eingabekomponenten in ein Formular. Sendet POST-Request per HTTP. |
| <h:panelGrid> | In HTML <table>-Tag. Anzahl der Spalten bestimmt das columns-Attribut |
| <f:facet> | Definiert eine Facette als Kindelement eines Containers (z. B. Überschrift für eine Tabelle) |
| <h:outputText> | Normaler HTML-Text |
| <h:outputLabel> | In HTML <label>-Tag. Kennzeichnung eines Eingabefeldes |
| <h:panelGroup> | Container, der mehrere JSF-Tags zu einem Tag zusammenfügt |
| <h:inputText> | In HTML <input>-Tag mit type="text", value-Attribut bezieht sich auf die Komponenten (z. B. EL-Ausdruck) |
| <h:inputSecret> | In HTML <input>-Tag mit type="password" |
| <h:commandButton> | Button in HTML. <input>-Tag mit type-Attribut (submit, reset, image). Standardmäßig: submit. Sendet Formular ab und löst ActionEvent aus (über Bean-Methode). |
| <h:message> | Gibt die erste Fehlermeldung für die im for-Attribut angegebenen Komponenten aus. ErrorStyle-Attribut kann als CSS-Fehler-Darstellung genutzt werden. |
