Einfache GUI mit Java Server Faces
Oberflächenentwicklung

DeveloperIT-ProjekteSoftware

Mit Java Server Faces (JSF) bietet Sun ein Werkzeug zur schnellen Entwicklung grafischer Bedienoberflächen. Der Artikel unterstützt Sie beim Einstieg in diese Technik.

Java

Einfache GUI mit Java Server Faces

Vor knapp zehn Jahren begann der Siegeszug von Java. Damals sollte die Programmiersprache noch vor allem Web-Anwendungen im Frontend-Bereich zusätzliche Funktionalität verschaffen. Dieser Ansatz war jedoch nicht von großem Erfolg gekrönt. Trotzdem prägt Java seit Jahren die Entwicklungslandschaft, allerdings vorrangig bei der serverseitigen Programmierung.

Sun hat zusammen mit Java auch eine Plattform geschaffen, die eine Spezifikation zur Ausführung von Anwendungskomponenten festschreibt. Sie wird als Java 2 Plattform, Enterprise Edition (kurz: J2EE) bezeichnet. Innerhalb von J2EE sind Dienste und Komponenten definiert, auf deren Basis Sie verteilte, mehrschichtige Anwendungen entwickeln können.


Laufzeitumgebung

Einfache GUI mit Java Server Faces

J2EE-Komponenten benötigen zur Laufzeit einen J2EE-Applikationsserver, der verschiedene Aufgaben übernimmt, unter anderem:

– das Transaktionsmanagement
– die Kommunikation zwischen J2EE-Komponenten
– das Management der Komponenten innerhalb deren Lebenszyklus

Ein J2EE-Server benötigt verschiedene logische Komponenten zur Erledigung seiner Aufgaben. Diese werden auch als Container bezeichnet. Die aktuelle Spezifikation setzt Container für folgende Teilaufgaben voraus:

– Laufzeitumgebung für Enterprise Java Beans (EJB-Container)
– Laufzeitumgebung für Java Server Pages (JSP) und Servlets (Web-Container)

Außerdem ist noch ein Container für die JCA-Laufzeitumgebung (Java Connector Architecture) erforderlich.

Mit J2EE kommen neue APIs ins Spiel, die die Funktionalität der Standard-API der Java-Plattform erweitern, darunter auch die Java Server Faces (JSF). JSF von Sun haben es sich auf die Fahnen geschrieben, die Oberflächenentwicklung zu beschleunigen und zu vereinfachen. Java Server Faces sind ein Framework zur Entwicklung von grafischen Bedienoberflächen für Web-Anwendungen.


Was bietet JSF?

Einfache GUI mit Java Server Faces

Java stellt im Bereich serverseitige Programmierung den Quasi-Standard dar, auch wenn Microsoft mit ASP.NET eine lohnenswerte Alternative bietet. Im Bereich Oberflächenentwicklung hatten die Redmonder jedoch klar die Nase vorn. Die Visual-IDEs bieten eine einfache Möglichkeit, durch wiederverwendbare Komponenten schnell einen ersten Entwurf der Oberfläche einer Anwendung zu entwickeln. Hier setzen auch die Java Server Faces an und biete eine Auswahl an Komponenten, aus denen sich einfach und schnell eine passende Oberfläche zusammenstellen lässt. Sun hat beim Design von JSF darauf geachtet, dass der Datenaustausch zwischen der Oberfläche und der Anwendung so einfach wie möglich vonstatten geht.

Das Eventmodell kann flexibel auf Ereignisse reagieren und bietet eine einfache Verbindung zwischen Ereignissen, die vom Client ausgelöst wurden, und dem zugehörigen serverseitigen Code, mit dem die Anwendung reagieren soll.

Wenn Ihnen die vorhandenen Komponenten nicht ausreichen, können Sie selbstverständlich auch relativ einfach eigene entwickeln und diese in Ihre Anwendungen integrieren.


Saubere Grenzen

Einfache GUI mit Java Server Faces

JSF haben einen klaren Fokus: die alltäglichen Aufgaben einer Web-Applikation einfach und souverän zu lösen. Dazu gehören die Überprüfung von Eingaben, die Konvertierung von Daten, das Mappen von Parametern, Standard-Elemente zur Navigation und ein Werkzeug zur einfachen Internationalisierung der Applikation. Dabei setzt Sun auf eine klare Aufgaben- und Schichtentrennung und nutzt dazu das MVC-Modell (Model-View-Controller), wobei sich JSF auf die Präsentationsschicht konzentrieren. Der Controller innerhalb des Modells übernimmt die Steuerung des Verhaltens der Anwendung. Dies geschieht bei JSF durch die Verwendung von Services, die durch den Controller angesprochen werden. Über diese Services wird die eigentliche Funktionalität implementiert und auch der Datenaustausch und die Kommunikation mit dem Backend geregelt. Innerhalb von JSF wird der Controller meist durch ein zentrales Servlet repräsentiert, dessen Eigenschaften über eine Konfigurationsdatei gepflegt werden.

Die Komponente Model übernimmt die Datenhaltung, die Speicherung des Zustands eines Objekts und auch die Datenanbindung. Sie wird in der Regel über ein Java-Bean realisiert.

Die Darstellung der Oberfläche ist die Aufgabe der View-Seite. Die einzelnen Komponenten sind hierarchisch in einer Baumstruktur angeordnet. Hier finden Sie alle Elemente wieder, die auch auf der Seite enthalten sind, wie Eingabefelder oder Schaltflächen. Der Komponentenbaum ist zustandsbehaftet. Die einzelnen Komponenten können Sie mit einer ID versehen und darüber ansprechen. Die Speicherung der Werte kann entweder auf Seiten des Clients oder des Servers erfolgen.

Für die meisten Eigenschaften einer Komponente steht auch die Funktion des Value-Binding zur Verfügung. Damit können Sie den Speicherort des Werts festlegen. Normalerweise wird der Wert lokal gespeichert, um beispielsweise bei Fehlern in der Konvertierung noch einmal auf den Ursprung zurückgreifen zu können. Durch Value-Binding lässt sich der Wert auch noch direkt im Modell speichern und auslesen. Der folgende Ausdruck stellt beispielsweise die Verbindung zwischen der Ausgabe und dem Schlüssel customer mit der Eigenschaft name her.

Neben der Verknüpfung von Komponenten mit Werten können mit Method-Binding-Komponenten auch Methoden zugewiesen werden. Dies ist genau dann hilfreich, wenn Sie beispielsweise das Anklicken einer Schaltfläche mit dem Auslösen eines Programms verbinden möchten:


Formularverarbeitung

Einfache GUI mit Java Server Faces

Sind alle Komponenten mit den jeweiligen Werten oder Methoden verbunden, fällt der nächste Blick auf den Lebenszyklus einer Anfrage. Hierbei werden im Wesentlichen sechs Phasen durchlaufen, die unterschiedliche Aufgabenstellungen für die involvierten Komponenten bedeuten.

Normalerweise erfolgt eine sequenzielle Abarbeitung aller Phasen. Allerdings kann es in bestimmten Phasen zu definierten Fehlern kommen, die die Verarbeitung verkürzen und gegebenenfalls eine Fehlerabwicklung nach sich ziehen. Die sechs Phasen im Detail:

Restore View. In dieser Phase wird der Komponentenbaum für die angeforderte Ressource erzeugt. Existiert bereits ein Komponentenbaum, so wird dieser für den aktuellen Benutzer wieder hergestellt.

Apply Request Values. In der zweiten Phase soll für jede Komponente der aktuelle Status abgefragt werden. Entweder kommt die Komponente aus dem FaceContext-Objekt, oder sie wurde alternativ zuvor erstellt.
Besitzt eine Komponente nicht die Fähigkeit des Event-Handlings, beschränkt sich die minimale Funktionalität in dieser Phase auf die Typkonvertierung.
Ist die Anfrage mit einem Kommando verknüpft, so wird in dieser Phase durch die zugehörige Komponente ein Action-Event erzeugt, das später die dazugehörigen serverseitigen Funktionen steuern soll.

Process Validations. Die Fehlerüberprüfung findet in der dritten Phase des Lebenszyklus statt. Die Werte der Komponente müssen sich einer Überprüfung unterziehen. Dies findet entweder basierend auf einem Regelwerk statt, das durch den Entwickler vorgegeben wird, oder durch standardisierte Validierungsregeln.
Fällt eine Komponente bei der Fehlerprüfung durch, so wird eine Fehlermeldung generiert und die Komponente als invalid gekennzeichnet.
Die Verarbeitung wird in der letzten Phase fortgesetzt, die Seite erneut gerendert und eine Fehlermeldung ausgegeben.

Update Model Values. Erreicht eine Komponente diesen Zustand, so sind alle Prüfungen erfolgreich gewesen. Die Komponente gilt damit als syntaktisch und semantisch korrekt.
Es findet eine Übertragung der Werte aus den Eingabefeldern auf Basis der Value-Bindings in das angebundene Modell statt. In dieser Phase können noch einmal Konvertierungsfehler auftreten, da die Request-Parameter immer Strings sind und die Objektvariablen einem beliebigen Java-Objekt entsprechen können. Als Konsequenz eines Konvertierungsfehlers wird die Phase 5 übersprungen und die Verarbeitung mit einer Fehlermeldung in Phase 6 fortgesetzt.

Invoke Applications. Beim Eintritt in die fünfte Phase ist das Datenmodell auf dem aktuellen Stand und die Geschäftslogik kann ausgeführt werden. Ist eine Komponente mit einem Event verknüpft, so wird dieses durch das Framework in dieser Phase ausgelöst und durch den Applikations-spezifischen Handler abgewickelt.
In der fünften Phase findet auch die Entscheidung statt, welcher View nach der erfolgreichen Ausführung der Geschäftslogik in der letzten Phase angezeigt werden soll.

Render Response. Das Ergebnis der vorherigen fünf Schritte landet als Outcome in der letzten Phase. Mit diesem Outcome lässt sich auf Basis der Navigationsregeln der nächste zu erstellende View ermitteln.
In den vorigen Phasen wurde auch von Konvertierungsfehlern direkt in die letzte Phase des Lebenszyklus gesprungen. In diesen Fällen wird immer der View angezeigt, der den Request erzeugt hat. Da dies die aufrufende Seite war, kann einfach eine Fehlermeldung mit einer näheren Erklärung, welche Eingaben zu korrigieren sind, auf dieser Seite ausgegeben werden.
In der letzten Phase des Lebenszyklus findet auch die Speicherung des Komponentenbaums statt, der zum neuen View gehört.


Das Event-Handling

Einfache GUI mit Java Server Faces

Wie Sie bereits im Lebenszyklus einer Anfrage gesehen haben, fällt dem Event-Handling eine zentrale Rolle zu. Erfahrene Java Entwickler finden sehr schnell Ähnlichkeiten zwischen den Event-Handling-Prozeduren von JSF und Swing.

Das Event-Handling unter JSF wird mit Event-Listenern realisiert. Zur Abarbeitung eines Events müssen Sie vorab einen Event-Listener implementieren. JSF unterscheidet zwischen zwei Arten von Events:

Action Events. Dieses Event steht jeder Komponente zur Verfügung. Die Verbindung zwischen Komponente und Listener wird über ein Attribut der Komponente gesteuert.

ValueChangedEvent. Ein solches Event-Objekt speichert sowohl den alten als auch den neuen Wert des Objekts. Bei JSF besteht keine permanente Verbindung zwischen Client und Server. Kommt also ein solches Event zum Einsatz, muss immer das Formular abgeschickt werden.


Das erste Beispiel

Einfache GUI mit Java Server Faces

An einem ersten Beispiel erfahren Sie, wie schnell Sie mit JSF zu Ihrer ersten eigenen Anwendung kommen. Da die Autoren hier nur die Funktionalität schildern wollen, ist die Funktion einfach gehalten und gibt lediglich das Quadrat der eingegebenen Zahl aus. Bevor es mit der Programmierung losgeht, müssen Sie noch die Einstellungen in den Konfigurationsdateien vornehmen. Die Datei web.xml ist eine der zentralen Dateien einer JSF-Anwendung und regelt alle Anfragen, die mit der Web-Anwendung zu tun haben. Hier wird also auch das Servlet für die Anwendung sowie dessen Mapping hinterlegt.



Faces Servlet
javax.faces.webapp.FacesServlet
1


Faces Servlet
/faces/*

Die zweite zentrale Datei ist faces-config.xml. Darin findet vorrangig die Konfiguration der Navigation und der verwendeten Java-Beans statt.



SessionBean1
webapplication2.SessionBean1
managed-bean-scope>session

Sie finden die beiden Dateien bei einem neuen Projekt über eine Entwicklungsumgebung immer im Verzeichnis WEB-INF.


Die Beans-Datei

Einfache GUI mit Java Server Faces

Alle Daten dieser Anwendung sind in einer Java-Bean-Klasse gespeichert. Die Klasse ist eine normale Java-Klasse und enthält die üblichen Set- und Get-Methoden. Im Beispiel sind dies also Methoden zur Berechnung des Quadrats und zur Rückgabe des Seitenwerts und des berechneten Werts.


public int getArea() {
return length*length;
}
public int getLength() {
return length;
}
public void setArea(int i) {
area = i;
}
public void setLength(int i) {
length = i;
}


Die JSF-Dateien

Einfache GUI mit Java Server Faces

Nun fehlen nur noch die beiden JSF-Dateien: eine zur Eingabe der Daten und eine zur Darstellung des Ergebnisses. Die Beschreibung der Seite ist eine Mischung aus HTML und Taglibs. Die Texte und Überschriften sind weiterhin HTML-Tags, die Oberfläche wird aber mit Taglibs beschrieben.

Vor der Verwendung müssen Sie die Bibliotheken einbinden. Dies geschieht am Anfang einer JSP-Seite, die auch für JSF-Elemente eingesetzt wird.


<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

Die HTML-Parameter unterscheiden sich im Beispiel nicht von einer Standard-HTML-Seite. Nur im Body-Bereich kommen neue Tags hinzu, die den View und die darin enthaltenen Elemente beschreiben.



...


...

Damit ist die Eingabeseite fertig. Nach der Berechnung wird der ermittelte Wert an die Ausgabeseite übergeben, die zuvor in der Datei faces-config.xml festgelegt wurde.

Sie können die Ausgabe natürlich auch auf der Eingabeseite machen und das Ausgabetextfeld dort platzieren. Damit liegen Sie dank der Web-2.0- und Ajax-Begeisterung voll im Trend.


Alle Dateien und Listings zum Workshop finden Sie auf der Heft-CD und unter listings.internet-pro.de.