1 Einführung in JavaServer Faces
Vielfalt der Technologien: JavaServer Faces (JSF) ist eine moderne Technologie zur Entwicklung von Webanwendungen. Allerdings steht sie nicht allein auf weiter Flur - es gibt Dutzende als Open Source veröffentlichte und Hunderte proprietäre Frameworks für die Entwicklung von Webapplikationen alleine im Java-Bereich, andere Programmiersprachen außer Acht gelassen. Der Elefant unter diesen Frameworks im Java-Bereich ist sicher Apache Struts, aber auch Apache Cocoon, Apache Tapestry und Apache Wicket sind sehr erfolgreich. Die erste Frage ist also, warum sich solch eine Vielfalt von Frameworks entwickelt hat und weshalb die Notwendigkeit für die Spezifizierung der JavaServer-Faces -Technologie entstand - immerhin gibt es doch mit der Servlet- und JSP-Technologie schon eine solide Basis für die dynamische Erstellung von Webseiten. Die Beschreibung der geschichtlichen Entwicklung der Webprogrammierung wird hier zum Verständnis beitragen.1.1 Kurzgeschichte der Webentwicklung
HTML und HTTP: Alles begann mit der Übertragung der ersten Seite in Hypertext Markup Language (HTML) über das Hypertext Transfer Protocol (HTTP) im August 1991. Nur einige wenige Visionäre haben damals erahnt, welche Entwicklung das World Wide Web über die Jahre nehmen würde. Exponentielles Wachstum war dem World Wide Web in die Wiege gelegt worden - dies galt für die Verbreitung genauso wie für die technologische Entwicklung. Anfangs war HTML eine einfache Sprache, die nur zur Auszeichnung der Bedeutung von Textteilen geeignet war. Durch die vielfache Anwendung in den verschiedensten Bereichen wurde HTML immer mehr erweitert, und die Entwicklung hin zur Layoutsprache war unabwendbar. So entstand aus den wenigen Elementen der ersten HTML-Version ein undurchdringlicher Dschungel an verschiedensten Auszeichnungselementen für die unterschiedlichsten Zwecke. Ein Zustand, der geändert werden musste; als Ergänzung zur HTML wurde die Layoutsprache CSS (Cascading Style Sheets) geboren und HTML wieder zur Bedeutungsauszeichnung verwendet. Begleitend zu diesen statischen Sprachen wurde auch das dynamische Element durch die Verwendung der Programmiersprache JavaScript im Webbrowser immer wichtiger.Server: Zur selben Zeit war eine ähnliche Revolution der Sprachen und Skriptsprachen am Server im Gange - unzählige serverseitige Technologien kämpften um die Gunst der Webentwickler, Perl, Phyton, PHP, Ruby und natürlich Java sind nur einige Beispiele. Kein Wunder, dass durch diese hohe Anzahl an involvierten Technologien die Entwicklung von großen, hochdynamischen Webanwendungen immer komplexer wurde - die Entwickler mussten bei der Bewältigung dieser Komplexität unterstützt werden.
Servlets: Im Java-Bereich, und auf diesen wollen wir uns ab jetzt konzentrieren, war die Entwicklung der Servlet-Technologie 1997 der erste Schritt zur dynamischen Generierung von HTML-Seiten am Server. Im Wesentlichen beruht diese Technologie darauf, dass in den Java-Code Befehle eingebunden werden, die zur Erzeugung von HTML dienen. Praktisch bedeutet das den Aufruf der Funktion
println("<html>text</html>");
auf einem OutputStream wie in Listing
Beispiel für ein einfaches
Servlet. Hier wird die GET-Methode der HTTP-Anfrage behandelt. . Sie können sich sehr leicht vorstellen, dass diese
Erstellung von HTML aus ganz normalem Java-Code bei langen HTML-Passagen schwer
verständlich und unübersichtlich wird. In einem zweiten Schritt entstanden daher
Hilfsklassen, die das Schreiben von HTML-Tags durch den Aufruf gewisser Methoden
erleichterten. Die Erstellung von HTML beschränkte sich somit auf den Aufruf dieser
Methoden mit der Übergabe von Zeichenketten für die Werte in den einzelnen Tags wie
in Listing Beispiel für eine einfache (jedoch keinesfalls
vollständige) Hilfsklasse zum Schreiben von
HTML-Code, eingebettet in Servlets .public class BeispielServlet extends HttpServlet {
public void doGet (
HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException {
//Vom HTTP-Request kann der Entwickler sich die
//Parameter für die Verarbeitung der Anfrage holen
String name = req.getParameter("name");
String text = req.getParameter("text");
//Es wird HTML-Text an den Browser zurückgesendet
res.setContentType("text/html");
//Ein OutputStream macht es möglich, den
//eigentlichen Text zu senden.
ServletOutputStream out = res.getOutputStream();
//Einzelne Elemente des Texts werden versendet
out.println("<html><head><title>");
out.println(name);
out.println("</title></head><body>");
out.println(text);
out.println("</body>");
out.println("</html>");
out.flush();
}
}
public class ServletUtility {
HttpServletResponse res;
public ServletUtility(HttpServletResponse res) {
this.res = res;
}
public void startTagNoAttributes(String tagName) {
res.print("<");
res.print(tagName);
res.print(">");
}
public void startTag(String tagName) {
res.print("<");
res.print(tagName);
}
public void endTag(String tagName) {
res.print("</");
res.print(tagName);
res.print(">");
}
/*Hier fehlen Methoden zur Behandlung von Attributen,
eingeschlossenem Text etc. Ein sehr gutes Beispiel
für solch eine Hilfsklasse wird auch von
der JSF-Technologie verwendet:
dem javax.faces.context.ResponseWriter*/
}
<@ page language="java" >
<html>
<head>
<title><=request.getParameter("name");></title>
</head>
<body>
<=request.getParameter("text");>
</body>
</html>
Webframeworks: Zur Lösung dieses Problems traten Webframeworks auf den Plan. Der Entwickler wird bei Benutzung eines Frameworks dazu angehalten, möglichst große Teile der Layoutbeschreibung in einer Seitendeklarationssprache wie JSP zu erstellen und gleichzeitig möglichst wenig Funktionalität im Sinne von Anwendungslogik zwischen die Elemente der Seitendeklarationssprache einzufügen.
Model-View-Controller (MVC): Ein klarer Schnitt zwischen den Bereichen Modell, Ansicht und Steuerungslogik ist also notwendig - dieses Entwicklungsmuster wird auch Model-View-Controller-Muster (kurz MVC) genannt und ist in Abbildung Das Model-View-Controller-Prinzip dargestellt.
Model2 - MVC für das Web: Im Webbereich, und hier insbesondere in der Entwicklung mit Java, hat sich eine spezielle Form dieses Musters etabliert, die den Namen Model2 erhalten hat. Der Name Model2 wurde in der Spezifikation des JSP-Standards geprägt, und das Muster ist die Übertragung des MVC-Ansatzes in die Welt der Webentwicklung Ein ebenfalls in der JSP-Spezifikation geprägter Begriff ist das Model1-Entwurfsmuster. Der Unterschied zu Model2 ist hier, dass kein Servlet als Controller verwendet wird - stattdessen bleibt die Kontrolle über die Managed-Beans in der ausgeführten JSP-Datei.: . Diese Form ist dem zugrunde liegenden MVC-Muster sehr ähnlich, einzig die verschiedenen Ausprägungen von Model, View und Controller werden hier genauer definiert, wie in Abbildung Das Model2-Prinzip als Spezialisierung der Model-View-Controller-Architektur zu sehen ist. Für fast alle mit Java arbeitenden Webframeworks dient das Model2-Pattern als Grundlage der Architektur. Als Steuerungslogik (Controller) wird dabei ein Servlet verwendet und meist ist das Modell in Form von Java-Klassen, häufig als Beans oder POJOs (Plain Old Java Objects), ausgeführt. Für die Deklaration der Ansicht gibt es allerdings viele Möglichkeiten - bei Turbine dient hierzu Velocity, bei Cocoon ein XML-Dialekt und bei Struts und JSF vor Version 2.0 JavaServer Pages (JSPs). Ab Version 2.0 setzt JSF standardmäßig auf Facelets (XHTML) als Seitendeklarationssprache.
Komponenten: Anfangs stand eben diese Trennung der einzelnen Schichten einer Applikation als höchste Priorität auf der Aufgabenliste der einzelnen Webframeworks. Alle oben genannten Frameworks haben dieses Problem im Bereich der Webentwicklung auf ihre Art und Weise gelöst. Im Laufe der Zeit war diese Aufteilung nicht mehr die einzige Notwendigkeit in der Webentwicklung und andere Aufgabenbereiche traten in den Vordergrund. Das heute am meisten diskutierte Problem ist die Wiederverwendbarkeit von Komponenten in Webapplikationen und hier haben nicht alle Webframeworks eine Lösung gefunden. Insbesondere muss in diesem Bereich eine klare Trennung zwischen Struts als dem bisher größten Player am Markt und dem Standard JSF vorgenommen werden - Struts beherrscht diese Komponentenorientierung nicht, während JSF die Basis für eine komponentenorientierte Entwicklung bietet und einige Komponenten im Standard bereits mitbringt.
JSF als Standard: JavaServer Faces (JSF) als Technologie wurde darüber hinaus entwickelt, um die vielfältigen und weit auseinanderlaufenden Ansätze zur Entwicklung von Webanwendungen unter Java zu bündeln und in eine gemeinsame Richtung zu leiten. Für solch eine Bündelung ist eine zentrale Standardisierung der Funktionalität eines Webentwicklungsframeworks von Vorteil und genau diese Standardisierung wird im Rahmen des Java Community Process (JCP) durchgeführt.
Der Java Community Process definiert die Rahmenbedingungen für die Entwicklung von Spezifikationen zur Erweiterung und Verbesserung der Java-Plattform. Vorschläge für Spezifikationen werden dort in Form von Java Specification Requests (JSRs) mit einer fortlaufenden Nummer eingebracht. Die Arbeit an einem JSR wird von einer sogenannten Expert-Group durchgeführt. Jeder JSR durchläuft einen mehrstufigen Prozess, bis eine finale Version vorliegt.
Seit 2004 ist die Version 1.0 der JavaServer-Faces -Technologie (JSR-127) spezifiziert. Nur wenige Monate später wurde die fehlerbereinigte Version 1.1 dieses Standards nachgereicht. Im Jahr 2006 folgte Version 1.2 der JSF-Spezifikation (JSR-252) als Teil von Java EE 5 und 2009 endlich die Version 2.0 (JSR-314) als Teil von Java EE 6 . Im Juli 2010 wurde Version 2.0 Revision A nachgereicht, die eine Reihe von Fehlern und Unzulänglichkeiten in der Spezifikation behebt. Tabelle tab:jsf-versions-jsrs zeigt alle JSF-Versionen mit den jeweiligen JSRs und dem Zeitpunkt der Veröffentlichung.
| Version | JSR | Veröffentlichung |
| JSF 1.0 | JSR-127 | März 2004 |
| JSF 1.1 | JSR-127 | Mai 2004 |
| JSF 1.2 | JSR-252 | Mai 2006 |
| JSF 2.0 | JSR-314 | Juli 2009 |
| JSF 2.0 Rev A | JSR-314 | Juli 2010 |
Die Expert-Group hat bei der Entwicklung von JSF 2.0 sehr gute Arbeit geleistet. Sie hat viele neue Konzepte eingeführt, die das tägliche Arbeiten einfacher machen. Trotz vieler Änderungen hat sich an den grundlegenden Prinzipien von JSF nichts geändert. Auch JSF 2.0 führt die Ease-of-Development-Strategie der Java EE-Plattform konsequent weiter.
So viel zur geschichtlichen Entwicklung der Webentwicklungsframeworks. Nach einem kurzen Überblick über die Neuerungen von JSF 2.0 im nächsten Abschnitt geht es in Abschnitt [Sektion: MyGourmet 1: Einführung anhand eines Beispiels] mit einer kurzen Einführung in die JSF-Technologie weiter.
1.2 JSF 2.0 im Überblick
Zwischen der Veröffentlichung von JavaServer Faces 1.2 im Jahr 2006 und der Finalisierung von Version 2.0 liegen gut drei ereignisreiche Jahre. Das ist in einem schnelllebigen Bereich wie der Webentwicklung eine lange Zeit, in der viele neue Trends und Technologien das Licht der Welt erblickten. Besonders im JSF-Umfeld hat sich sehr viel getan. JSF hat Schwung aufgenommen und ist zu einer der wichtigsten Technologien in der Java-Webentwicklung geworden. Ein gewichtiger Teil dieses Erfolgs ist sicherlich auf die bereits in der Spezifikation festgeschriebene Erweiterbarkeit von JSF zurückzuführen. Neben dem Einsatz verschiedener Komponentenbibliotheken lassen sich sogar grundlegende Bestandteile des Basisframeworks einfach erweitern und austauschen.Mit der steigenden Popularität von JSF hat sich eine sehr aktive Community entwickelt. JSF ist nicht mehr nur ein Webframework, sondern ein ganzes Ökosystem aufeinander aufbauender und sich ergänzender Technologien. In zahlreichen Projekten wurden neue Komponentenbibliotheken, Bibliotheken zur Integration neuer Technologien oder Lösungen für Unzulänglichkeiten und nicht adressierte Bereiche in der Spezifikation entwickelt.
Die Expert-Group des JSR-314 hat beim Entwurf von JavaServer Faces 2.0 auch diese Community und die Entwickler nicht vergessen. Sie hat sich populäre Bibliotheken angesehen und ist auf in den letzten Jahren oft heftig diskutierte Probleme und Vorschläge aktiv eingegangen. Einige der neuen Features von JSF 2.0 sind in der einen oder anderen Form bereits in existierende Bibliotheken integriert. Durch die Standardisierung verbessert sich allerdings die Kompatibilität von Komponentenbibliotheken verschiedener Hersteller, was wiederum das Leben der Entwickler vereinfacht.
In diesem Abschnitt fassen wir kurz die neue Funktionalität von JSF 2.0 zusammen. Wenn Sie bereits mit einer JSF-Version vor 2.0 Erfahrungen gesammelt haben, können Sie hier gezielt nach Informationen suchen.
Hier eine Liste der wichtigsten Neuerungen mit Referenzen auf die entsprechenden Stellen im Buch:
- Facelets wurde in den Standard aufgenommen und ist jetzt die Sprache der Wahl für die Deklaration von Seiten. Abschnitt Sektion: Seitendeklarationssprachen enthält eine kurze Einführung in Seitendeklarationssprachen und erläutert den Unterschied zwischen JSP und Facelets. Abschnitt Sektion: Advanced Facelets zeigt dann weiterführende Informationen zu Facelets und in Abschnitt Sektion: Templating finden Sie eine Einführung in Templating.
- Eine der wichtigsten Neuerungen sind Kompositkomponenten. Sie erlauben das Erstellen von eigenen Komponenten, ohne eine Zeile Java-Code zu schreiben. Wie das funktioniert, wird in Abschnitt Sektion: Kompositkomponenten erläutert.
- Die Integration von Bean-Validation erlaubt eine vollständig metadatenbasierte Validierung. Informationen dazu finden Sie in Abschnitt Sektion: Bean-Validation nach JSR-303 .
- Ajax ist jetzt in den Standard integriert. Eine ausführliche Einführung finden Sie in Kapitel Kapitel: Ajax und JSF .
- Eine Reihe neuer Annotationen macht die Konfiguration von JSF-Anwendungen so einfach wie nie zuvor.
- Mit der Project-Stage kann die aktuelle Phase des Projekts im Entwicklungsprozess ermittelt werden. Wie Sie davon profitieren, zeigt Abschnitt Sektion: Project-Stage .
- In JSF 2.0 gibt es endlich einen standardisierten Weg, Ressourcen wie Skripte oder Stylesheets zu verwalten. Die Details dazu finden Sie in Abschnitt Sektion: Verwaltung von Ressourcen .
- System-Events bieten die Möglichkeit, auf spezielle Ereignisse im Lebenszylus zu reagieren.
- Die erweiterte Unterstützung von GET-Anfragen verbessert die Möglichkeit, Bookmarks zu setzen. Abschnitt Sektion: Bookmarks und GET-Anfragen in JSF liefert die Details.
- Mit impliziter und bedingter Navigation hat der Navigationsmechanismus zwei Erweiterungen erhalten, die einerseits die Navigation vereinfachen, sie andererseits aber auch flexibler machen. Näheres dazu finden Sie in Abschnitt Sektion: Navigation .
- Partial-State-Saving optimiert das Speichern des Zustands in Bezug auf Speicherverbrauch und Performance. Details dazu finden Sie in Abschnitt Sektion: Komponentenklasse schreiben .
- Mit dem View-Scope gibt es einen neuen Gültigkeitsbereich für Managed-Beans. Mehr dazu erfahren Sie in Abschnitt Sektion: Managed-Beans .
1.3 Das erste JSF-Beispiel
JSF ist ein Standard für ein Webentwicklungsframework. Für die Beschreibung der einzelnen Teile existiert in der Version 2.0 eine über 400 Seiten starke Spezifikation. Natürlich ist ein großer Teil davon für den Einstieg in die Webentwicklung mit JSF nicht notwendig, daher möchten wir an dieser Stelle nur einen kurzen Überblick über JSF geben. Und nichts ermöglicht einen besseren Einblick in eine Technologie, als ein kurzes Beispiel mit ebendieser zu erarbeiten.Wir werden für einen einfachen Start mit JSF bei unseren Beispielen auf das weitverbreitete Build-Werkzeug Apache Maven 2 zurückgreifen. Maven ist ein äußerst hilfreiches Mittel, um Java-basierte Projekte zu verwalten. Es kann vieles - unter anderem Applikationen verwalten, erstellen, verteilen, automatisch testen, Abhängigkeiten verwalten und Webseiten des Projekts erstellen. Neben einer standardisierten Beschreibung von Projekten im Project Object Model ( pom.xml ) und einem standardisierten Build-Prozess bietet Maven unter anderem noch eine automatische Auflösung von Abhängigkeiten zu anderen Projekten und Bibliotheken. Die Funktionalität lässt sich zusätzlich durch verschiedenste Plug-ins erweitern, von denen wir in weiterer Folge einige verwenden werden.
Wird mit Maven 2 gearbeitet, ist die Webapplikation auch aus der Kommandozeile heraus startbar - außer einem simplen Editor ist keine Entwicklungsumgebung notwendig. Leichter geht es allemal mit einer guten Entwicklungsumgebung wie Eclipse . Eclipse ist nicht nur ein hervorragendes Entwicklungswerkzeug für Java-Applikationen, es ist auch gleichzeitig eine Plattform, für die Myriaden von Komponenten, sogenannte Eclipse-Plug-ins existieren. Eclipse selbst bietet mit dem Projekt Web Tools Platform (WTP) bereits eine Basisunterstützung für die Entwicklung von JSF-Anwendungen an, die allerdings einige Ecken und Kanten aufweist. Wir werfen daher zusätzlich einen Blick auf die JBoss-Tools , eine bereits ausgereifte Sammlung von Plug-ins und Features.
Bevor die Arbeit an einem JSF-Projekt beginnen kann, muss es natürlich erst angelegt werden. Wie das funktioniert, zeigen wir Ihnen im nächsten Abschnitt. Den kompletten Quellcode des Hello World -Beispiels finden Sie unter http://jsfatwork.irian.at .
1.3.1 Erstellen eines JSF-Projekts
Das Erstellen eines Maven -Projekts läuft immer nach dem selben Schema ab. Im Projektverzeichnis wird neben der Beschreibung des Projekts in der Datei pom.xml noch das Verzeichnis src mit dem Unterverzeichnis main angelegt. Dort legen wir den Quellcode unseres Projekts in drei weiteren Unterverzeichnissen ab. Sämtliche Javaklassen kommen ins Unterverzeichnis java , alle Ressourcen wie .properties -Dateien kommen ins Unterverzeichnis resources und alle für die Webapplikation relevanten Dateien ins Unterverzeichnis webapp . Diese Struktur ist eine Konvention von Maven und sollte für alle Projekte eingehalten werden. In Abbildung Struktur des Hello World-Projekts sehen Sie die komplette Projektstruktur.Eine detaillierte Einführung in die grundlegenden Konzepte von Maven würde den Rahmen dieses Kapitels sprengen - aber keine Sorge, wir lassen Sie nicht im Regen stehen. In Anhang Kapitel: Eine kurze Einführung in Maven finden Sie allerhand Wissenswertes zu Maven inklusive einer Installationsanleitung. Dort zeigen wir Ihnen auch, wie Sie den Vorgang der Projekterstellung mit Maven automatisieren können.
Bevor wir uns den JSF-relevanten Inhalten zuwenden, werfen wir noch einen Blick auf die Beschreibung des Projekts in der Datei pom.xml . Die komplette Datei finden Sie im Quellcode der Anwendung, für uns ist momentan nur die Definition der Abhängigkeiten zu den Bibliotheken für JSF 2.0 interessant. Listing Abhängigkeiten zu Apache MyFaces in der pom.xml zeigt die Abhängigkeiten für Apache MyFaces in Version 2.0.4. Die Bibliothek mit der Artifact-ID myfaces-api beinhaltet die standardisierte API von JSF 2.0 und die Bibliothek mit der Artifact-ID myfaces-impl die konkrete Implementierung.
<dependencies>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>2.0.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>2.0.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
Deklaration der Ansicht: Jetzt kommen wir zum wichtigsten Teil unserer Anwendung: Wie es sich für eine Hello World -Anwendung gehört, wollen wir auf der Startseite unserer Anwendung den Text "Hello JSF 2.0-World" ausgeben. Dazu legen wir im Verzeichnis webapp die JSF-Seitendeklaration hello.xhtml an (siehe Listing Die Seitendeklaration hello.xhtml ).
<!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:h="http://java.sun.com/jsf/html">
<head>
<title>Hello World</title>
</head>
<body>
<h:outputText value="Hello JSF 2.0-World"/>
</body>
</html>
web.xml: Im zweiten Schritt erstellen wir die Webkonfigurationsdatei web.xml im /WEB-INF -Verzeichnis unserer Webanwendung Die Datei web.xml wird auch Deployment-Deskriptor der Webanwendung genannt.: so, dass auf die JSF-Technologie zugegriffen werden kann. Das geschieht durch die Einbindung des JSF-Servlets in Form einer Servlet-Definition und eines Servlet-Mappings, wie es Listing Die Konfigurationsdatei web.xmlmit der Spezifikation eines FacesServlet sowie des zugehörigen Servlet-Mappings. zeigt. Durch das angegebene servlet-mapping -Element werden sämtliche Anfragen mit der Endung .xhtml von genau diesem JSF-Servlet bearbeitet.
Über den Kontextparameter javax.faces.PROJECT_STAGE wird die Project-Stage auf Development gesetzt. Damit teilen wir JSF mit, dass wir uns aktuell in der Entwicklungsphase des Projekts befinden. Welche Auswirkungen das mit sich bringt, erfahren Sie in Abschnitt Sektion: Project-Stage .
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<description>JSF 2.0 - Hello World</description>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>
javax.faces.webapp.FacesServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>hello.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
Herzlichen Glückwunsch - Sie haben soeben Ihre erste Webanwendung mit JavaServer Faces verfasst! Im nächsten Abschnitt zeigen wir Ihnen, wie Sie die Anwendung direkt mit Maven starten können. Dieses Beispiel war selbstverständlich erst der Einstieg, wenn Sie also noch Fragen haben, laden wir Sie zum Weiterlesen ein.
1.3.2 Starten der Anwendung
Zum Starten der Hello World -Applikation kommt das Jetty-Maven-Plug-in zur Anwendung. Jetty ist ein Servlet-Container, der als Laufzeitumgebung für unsere JSF-Applikation dient und von der Konsole aus zu starten ist. Schnelles Prototyping für erste Versionen der Webapplikation kann hiermit perfekt zum Zug kommen. Der Befehl, um den Server zu starten, lautet:mvn clean jetty:run
Eingegeben werden muss dieser ebenfalls wieder in der Wurzel des Projektverzeichnisses.
Die benötigten Dateien werden durch Maven 2 erneut automatisch in das lokale
Repository geladen. Danach startet der Server und die Applikation kann in der Adresszeile
des Browsers wie folgt aufgerufen werden:http://localhost:8080/helloworld/
Der Build-Prozess des Projekts kann in weiterer Folge mit diesem Befehl neu angestoßen
werden:mvn install
Ein Unterordner target entsteht, in dem die kompilierten Klassen und das
.war -Archiv liegen. Die .war -Datei enthält auch alle zur Ausführung
der Webapplikation benötigten Bibliotheken, die Maven 2 über die Abhängigkeiten
in der pom.xml -Projektdatei eingefügt hat. Das Projekt wurde nun wie zuvor der
Archetype ins lokale Repository unter der Group-Id at.irian.jsfatwork und der Artifact-Id helloworld installiert. Abbildung Anwendung im lokalen Repository zeigt die Verzeichnisstruktur im lokalen Repository.1.3.3 Entwicklung mit Eclipse und JBoss-Tools
Die Fans hübscher Benutzerschnittstellen sind im letzten Abschnitt schwer enttäuscht worden - sie werden im folgenden Abschnitt wieder mit der JSF-Entwicklung versöhnt werden; die Kombination aus Eclipse und den JBoss-Tools ist nämlich eine ausgezeichnete Alternative zum Arbeiten auf der Kommandozeile.Natürlich können die Projektdateien mit jedem Texteditor bearbeitet werden - will man aber die Entwicklungsumgebung Eclipse (oder eines der Plug-ins) für die Arbeit an der Applikation verwenden, hilft der Aufruf des folgenden Befehls im Wurzelverzeichnis der Anwendung:
mvn eclipse:eclipse
Damit wird ein Standard-Java-Projekt angelegt, das in Eclipse importiert werden kann. Um
in der Entwicklungsumgebung auch die erweiterten Features für Webanwendungen nutzen zu
können, empfiehlt es sich allerdings, den Befehl wie folgt zu verwenden:mvn eclipse:eclipse -Dwtpversion=1.5
Maven 2 nimmt wirklich eine Menge an Arbeit ab! Die Projektdateien für
Eclipse wurden automatisch erstellt und das Projekt kann in Eclipse mit allen
benötigten Abhängigkeiten und Pfaden importiert werden. Eine ausführliche Anleitung,
um Eclipse und die JBoss-Tools für die Arbeit mit JSF einzurichten, findet sich
in Anhang Kapitel: Eclipse und JBoss-Tools .1.3.3.1 Arbeiten mit Eclipse und JBoss-Tools
Nach dem Starten des Programms befindet man sich in einer mit den JBoss-Tools-Optionen angereicherten Version von Eclipse (siehe Abbildung Eclipse und JBoss-Tools mit geöffnetem Hello World-Projekt ).Eclipse bietet in Verbindung mit den JBoss-Tools einen durchaus brauchbaren Assistenten zum Erstellen von JSF-Anwendungen an. Leider war zum Zeitpunkt der Drucklegung die Unterstützung von JSF 2.0 noch nicht integriert, aber bereits angekündigt. Sobald der Assistent das Erstellen von JSF 2.0-Projekten unterstützt, werden wir eine ausführliche Anleitung auf http://jsfatwork.irian.at zur Verfügung stellen.
Die JBoss-Tools stellen außerdem eine WYSIWYG-Ansicht und einen Editor für die einzelnen JSF-Seiten zur Verfügung. Mit diesem Editor ist es kinderleicht, JSF-Seiten selbst zu erstellen, Komponenten auf diesen Seiten einzubinden und diese mit Eigenschaften der Managed-Beans zu verbinden. Der Editor wird über einen Doppelklick auf eine JSF-Datei gestartet. Dadurch öffnet sich der JSF-Editor in der Quellcodeansicht und - im unteren Bereich der Bildschirmanzeige - der WYSIWYG-Editor. Von der Werkzeugleiste rechts im Bild können Komponenten in den oberen Teil (die Quelltextansicht) gezogen werden, die entstandenen Komponenten werden dann automatisch von der WYSIWYG-Ansicht dargestellt.
Als Beispiel werden wir in unserer XHTML-Datei mit dem Namen hello.xhtml eine neue Komponente einfügen. Durch einen Doppelklick auf die Datei öffnet sich der Editor. Wir öffnen (sofern sie noch nicht angezeigt ist) die Ansicht "JBoss Tools Palette" und wählen den Tab "JSF HTML" an. Auf diesem Tab selektieren wir das Element "outputText" und ziehen es in den roten Bereich in der WYSIWYG-Ansicht. Sobald wir die Maustaste loslassen, fragt eine Eingabeaufforderung den Wert dieser Komponente ab. Wir geben beispielsweise den Wert "Hello again!" ein und schließen die Eingabeaufforderung. In der WYSIWYG-Ansicht wird sofort die entsprechende Komponente dargestellt. Abbildung WYSIWYG-Editor der JBoss-Tools ) zeigt die WYSIWYG-Ansicht mit dem Dialog zum Initialisieren des Werts der Komponente.
Mit der von JBoss angebotenen Kombination an Entwicklungswerkzeugen lässt sich ausgezeichnet arbeiten; wenn Sie Spaß an der Sache hatten, können Sie zur Übung gleich noch einige Seiten hinzufügen.
1.3.3.2 Starten der Anwendung
Das Starten der erstellten Anwendung verläuft sehr einfach: Der integrierte Servlet-Container Tomcat kann durch das Betätigen der Start Tomcat... -Schaltfläche in der Symbolleiste von Eclipse gestartet werden - das Symbol ist ein grüner Pfeil. Alternativ dazu kann gleich rechts daneben auch ein Debug-Modus gestartet werden.Web Tools: Die JBoss-Tools bauen mit der Verteilung der Anwendung auf der Web Tools Platform von Eclipse auf - ein Projekt, das mittlerweile in den meisten Fällen stabil läuft. Manchmal kommt es jedoch immer noch zu unerklärlichen Fehlern in der JSF-Applikation. In solchen Fällen ist es oft hilfreich, den Verteilungsprozess neu in Gang zu setzen, um Probleme durch unvollständig oder gar nicht neu verteilte Dateien zu lösen.
Erledigt wird das durch die vollständige Entleerung des Deployment -Verzeichnisses. Dieses befindet sich unter:
[Projektname].deployables
Hilft auch diese Maßnahme nicht, bleibt in zweiter Instanz nur das Neustarten von Eclipse.
Abhilfe kann auch das Löschen und Neuerstellen des Server -Eintrags im
Servers -Tab schaffen.Sollte dadurch noch immer keine Besserung eintreten, kann als letzte Maßnahme das temporäre Verzeichnis der Web Tools Platform geleert werden. Dieses Verzeichnis finden Sie am einfachsten, wenn Sie in die Logmeldungen sehen, die beim Hochstarten Ihrer Webanwendung ausgegeben werden. Sie sollten dort eine Zeile ähnlich der folgenden finden:
INFO: ServletContext '[workspace_dir].metadata
.plugins\org.eclipse.wst.server.core\tmp0
webapps[context_name]' initialized.
Die Angabe führt Sie zu jenem Verzeichnis, in das die Zwischenspeicherung von temporären
Dateien Ihrer Webanwendung erfolgt.Nach diesem Abstecher in die Welt der Build-Werkzeuge und Entwicklungsumgebungen widmen wir den nächsten Abschnitt der ersten Version unseres MyGourmet -Beispiels.
1.4 MyGourmet 1: Einführung anhand eines Beispiels
Im Laufe des Buchs wird schrittweise eine kleine Beispielapplikation mit dem Namen MyGourmet aufgebaut. Die Anwendung soll einen Online-Bestellservice für lukullische Genüsse jeglicher Art darstellen. Der Fokus liegt dabei verständlicherweise weniger auf vollständiger Funktionalität oder perfektem Design, sondern auf der Vermittlung der Basiskonzepte von JavaServer Faces . Jeder Schritt erweitert MyGourmet um die im jeweiligen Kapitel vorgestellten Aspekte von JSF. Sie finden den Sourcecode für alle Beispiele dieses Buchs unter der Adresse http://jsfatwork.irian.at .Im ersten Schritt erweitern wir unser Hello World -Beispiel um ein einfaches Formular zur Eingabe der Daten eines Kunden. Es existiert ein Feld für die Eingabe des Vornamens und des Nachnamens und eine Absendeschaltfläche. Nach dem Betätigen der Schaltfläche werden die gerade eingegebenen Daten noch einmal dargestellt, und zwar in entsprechenden Ausgabefeldern mit einer zusätzlich eingeblendeten Erfolgsmeldung.
Zuerst sollten wir die Klassen unseres Datenmodells so fertigstellen, dass wir sie in der Webapplikation verwenden können. Das ist einfach - eine simple Java-Klasse Customer mit den zwei Klassenvariablen firstName und lastName und den dazugehörigen Zugriffsmethoden getFirstName() , setFirstName(String firstName) , getLastName() und setLastName(String lastName) reichen dazu aus. Die Klasse ist in Listing Die Klasse Customer dargestellt.
package at.irian.jsfatwork.gui.page;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class Customer {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Die Bean ist dabei einem zeitlich eingeschränkten und auf den Benutzer bezogenen Gültigkeitsbereich zugeordnet. Mit der ebenfalls in Version 2.0 eingeführten Annotation @SessionScoped weisen wir JSF an, die Managed-Bean einmal pro HTTP-Session neu zu erzeugen.
Deklaration der Ansicht: Jetzt kommen wir zum wichtigsten Teil unserer Anwendung: Irgendwo muss auf diese Managed-Bean zugegriffen werden, und das machen wir in einer Facelets-Seite Facelets ist seit JSF 2.0 Teil des Standards und JavaServer Pages vorzuziehen, mehr dazu in Abschnitt Sektion: Seitendeklarationssprachen .: . In MyGourmet 1 ist das die Seite editCustomer.xhtml zum Erfassen des Vor- und Nachnamen des Kunden. Das Grundgerüst der Seite ist wie schon beim Hello World -Beispiel ein HTML-Dokument mit eingebetteten JSF-Tags im body -Element.
Damit wir mit unserer Seite überhaupt Benutzereingaben verarbeiten können, brauchen wir ein Formular. JSF stellt dazu in der HTML-Tag-Bibliothek das Tag h:form zur Verfügung. Die Eingabefelder für den Vor- und den Nachnamen des Kunden werden mit dem Tag h:inputText innerhalb des Formulars in die Seite eingefügt. Damit Benutzer der Anwendung die Eingabefelder unterscheiden können, bekommen sie über das Tag h:outputLabel ein Label. Die Verbindung zwischen dem Label und dem Eingabefeld erfolgt, indem die ID des Eingabefelds in das for -Attribut von h:outputLabel eingetragen wird. Zum Ausrichten der einzelnen Elemente in einer tabellenförmigen Struktur kommt h:panelGrid zum Einsatz.
Interessant ist bei diesen Tags das value -Attribut der Eingabeelemente. Es beinhaltet eine Value-Expression , über die der Wert einer Komponente mit einer Managed-Bean und deren Eigenschaften verbunden werden kann. Das geschieht mit folgender Syntax: Nach einer Raute Ab JSF 1.2 darf auch ein "$"-Zeichen - wie in der früher definierten JSP Expression Language - verwendet werden.: folgt in geschwungenen Klammern der Name der Eigenschaft in der Form bean.eigenschaft . Allgemein ergibt das also einen Ausdruck in der Form #{managedBean.eigenschaft} - wie in Listing Die Datei editCustomer.xhtml mehrfach zu sehen.
Diese Applikation können wir bereits ausführen, wir werden eine Seite mit den von uns definierten Eingabefeldern sehen. Der nächste Schritt ist das Weiterleiten des Benutzers auf die Seite showCustomer.xhtml , was in unserem Fall durch eine Schaltfläche erfolgen soll. Wir fügen also eine Schaltfläche zu unserer XHTML-Seite hinzu. Das entsprechende JSF-Element heißt h:commandButton . Diese Schaltfläche versehen wir mit einem Attribut action , das den Wert /showCustomer.xhtml erhält, und einem Attribut value mit der im Browser darzustellenden Beschriftung Save . Ein Klick auf die Schaltfläche bewirkt, dass JSF den Benutzer auf die im Attribut action angegebene Seite weiterleitet.
Vor JSF 2.0 musste die Navigation noch verpflichtend in der Konfigurationsdatei faces-config.xml in Form von Navigationsregeln definiert werden. In JSF 2.0 kann dieser Schritt durch das direkte Angeben der Seite entfallen. Weiterführende Informationen zum Thema Navigation finden Sie in Abschnitt Sektion: Navigation .
Der komplette Sourcecode der Seite editCustomer.xhtml ist in Listing Die Datei editCustomer.xhtml zu finden.
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>MyGourmet - Edit Customer</title>
</head>
<body>
<h1><h:outputText value="MyGourmet"/></h1>
<h2><h:outputText value="Edit Customer"/></h2>
<h:form id="form">
<h:panelGrid id="grid" columns="2">
<h:outputLabel value="First Name:" for="firstName"/>
<h:inputText id="firstName"
value="#{customer.firstName}"/>
<h:outputLabel value="Last Name:" for="lastName"/>
<h:inputText id="lastName"
value="#{customer.lastName}"/>
</h:panelGrid>
<h:commandButton id="save" value="Save"
action="/showCustomer.xhtml"/>
</h:form>
</body>
</html>
Bevor wir auf die Seite showCustomer.xhtml (Listing Die Datei showCustomer.xhtml ) navigieren können, müssen wir sie zuerst erstellen. Die neue Seite soll ähnlich der ersten Seite aussehen, nur ersetzen jetzt h:outputText -Tags die h:inputText -Elemente und ein zusätzliches h:outputText -Tag gibt die Nachricht "Customer saved successfully!" aus.
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>MyGourmet - Show Customer</title>
</head>
<body>
<h1><h:outputText value="MyGourmet"/></h1>
<h2><h:outputText value="Show Customer"/></h2>
<h:panelGrid id="grid" columns="2">
<h:outputText value="First Name:"/>
<h:outputText value="#{customer.firstName}"/>
<h:outputText value="Last Name:"/>
<h:outputText value="#{customer.lastName}"/>
</h:panelGrid>
<h:outputText value="Customer saved successfully!"/>
</body>
</html>
<h:commandButton id="save"
action="#{customer.save}" value="Save"/>
Action-Methode:
Die referenzierte Methode darf
keinen Übergabeparameter haben, muss eine Zeichenkette zurückliefern und zudem
mit public deklariert werden. Die Methode wird beispielsweise einen
Datenbankzugriff ausführen und die Daten des Kunden speichern. Wir stellen diesen
Zugriff einfach als Kommentar dar. Schließlich liefert die Methode die Zeichenkette
zurück, die wir zuvor direkt in die action -Eigenschaft aufgenommen haben,
also /showCustomer.xhtml :public String save() {
return "/showCustomer.xhtml";
}
Wenn die Speicherung der Kundendaten nicht erfolgreich gewesen ist, sollte eine andere
Zeichenkette zurückgeliefert werden. Dadurch wird eine andere Navigation ausgelöst und
beispielsweise wieder die Seite /editCustomer.xhtml angezeigt.Im nächsten Kapitel erarbeiten wir gemeinsam die theoretischen Grundlagen zum Verständnis von JSF. Nach einem kurzen Einblick in die Aufgaben von JSF in Abschnitt Sektion: Aufgaben der JSF-Technologie und der Definition einiger grundlegender Begriffe in Abschnitt Sektion: JavaServer Faces in Schlagworten folgt ein zweiter Teil des Beispiels MyGourmet 1 in Abschnitt Sektion: MyGourmet 1: Schlagworte im Einsatz . Dort wird das Verständnis der zuvor definierten Grundbegriffe im Praxiseinsatz vertieft.