Loading...
 
  WYSIWYG-Editor der JBoss-Tools
 
  Struktur des Hello World-Projekts
 
  MyGourmet 1: Komponenten und ihre Darstellung
 
  Ein einfaches JSP-Beispiel
 
  Eclipse und JBoss-Tools mit geöffnetem Hello World-Projekt
 
  Die Seitendeklaration hello.xhtml
 
  Die Konfigurations-datei web.xml mit der Spezifikation eines FacesServlet sowie des zugehörigen Servlet-Mappings spezifiziert.
 
  Die Klasse Customer
 
  Die Datei showCustomer.xhtml
 
  Die Datei editCustomer.xhtml
 
  Das Model2-Prinzip als Spezialisierung der Model-View-Controller-Architektur
 
  Das Model-View-Controller-Prinzip
 
  Beispiel für eine einfache (jedoch keinesfalls vollständige) Hilfsklasse zum Schreiben von HTML-Code, eingebettet in Servlets
 
  Beispiel für ein einfaches Servlet. Hier wird die GET-Methode der HTTP-Anfrage behandelt.
 
  Anwendung im lokalen Repository
 
  Abhängigkeiten zunewline Sun Mojarra in der pom.xml
 
  Abhängigkeiten zunewline Apache MyFaces in der pom.xml

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 Rahmenwerken ist im Java-Bereich sicher Apache Struts, aber auch Apache Cocoon oder Apache Tapestry 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*/
}
Für komplexe HTML-Seiten war auch diese Vorgangsweise nicht optimal, und im Sinne der klassischen Theorie von These, Antithese und Synthese wurde diametral zu diesem Ansatz die JavaServer Pages -(JSP-)Technologie entwickelt JSP: . Ein Beispiel in dieser Sprache findet sich in Listing Ein einfaches JSP-Beispiel . Hier ist HTML die treibende Kraft und in die einzelnen Tags der HTML sind in sogenannten Scriptlets die Aufrufe der Java-Methoden zur Ausgabe der dynamischen Teile der HTML-Seite eingebunden. Dieser Ansatz erleichterte die Erstellung von komplexen HTML-Seiten mit viel eingebautem JavaScript-Code und einer hohen Anzahl an CSS-Auszeichnungen ungemein.
<@ page language="java" >
<html>
  <head>
    <title><=request.getParameter("name");></title>
  </head>
  <body>
    <=request.getParameter("text");>
  </body>
</html>
Alles, was "benutzt" werden kann, kann allerdings auch "missbraucht" werden, und genau dieser Fall trat für die JSP-Technologie ein. Die Entwickler begannen, immer mehr Code in die einzelnen JSP-Seiten aufzunehmen, bis erneut eine hochkomplexe Mischung aus HTML-Tags und Java-Code entstand; diese Mischung war genauso schlecht wartbar wie die in Servlet-Code eingebaute HTML-Generierung. Ein weiterer Kritikpunkt an der Verwendung von JSP war, dass der eingebaute Sourcecode erst zum Zeitpunkt des Anwendungsstarts im Applikationsserver kompiliert wurde, und viele Fehler, die normalerweise bei der Erstellung von Java-Klassen aus dem Sourcecode bereits beseitigt worden waren, erst zur Laufzeit auftraten. Die Bedeutung dieses Problems steigt selbstverständlich mit der Menge des in die JSP-Seite eingebundenen Sourcecodes.
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.
Abbildung:Das Model-View-Controller-Prinzip
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 Definition der Ansicht gibt es allerdings viele Möglichkeiten - bei Turbine dient hierzu Velocity, bei Cocoon ein XML-Dialekt, bei Struts und auch bei JSF in der Basisversion eine Seitendeklaration mit JavaServer Pages (JSPs).
Abbildung:Das Model2-Prinzip als Spezialisierung der Model-View-Controller-Architektur
Komponenten: Anfangs stand eben diese Trennung der einzelnen Schichten einer Applikation als höchste Priorität auf der Aufgabenliste der einzelnen Webframeworks und alle oben genannten großen Rahmenwerke in der Webentwicklung haben dieses Problem 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). Tabelle tab:jsf-versions-jsrs zeigt alle JSF-Versionen mit den jeweiligen JSRs und dem Zeitpunkt der Veröffentlichung.
VersionJSRVerö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
Version 1.2 war bis Mitte 2009 aktuell und hat viel zum Erfolg von JSF beigetragen. Mittlerweile stehen allerdings bereits JSF 2.0 und Java EE 6 in den Startlöchern und versprechen Großes. 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:
Nach der Vorstellung der Neuigkeiten von JSF 2.0 geht es im nächsten Abschnitt mit dem ersten Beispiel richtig los.

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.
Abbildung:Struktur des Hello World-Projekts
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 zunewline Sun Mojarra in der pom.xml zeigt die Abhängigkeiten für Sun Mojarra in Version 2.0.1. Die Bibliothek mit der Artifact-ID jsf-api beinhaltet die standardisierte API von JSF 2.0 und die Bibliothek mit der Artifact-ID jsf-impl die konkrete Implementierung von Sun Mojarra .
<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>
Als Alternative zu Sun Mojarra kann auch Apache MyFaces zum Einsatz kommen. Listing Abhängigkeiten zunewline Apache MyFaces in der pom.xml zeigt die Abhängigkeiten für Apache MyFaces in Version 2.0.0. 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.0</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.myfaces.core</groupId>
    <artifactId>myfaces-impl</artifactId>
    <version>2.0.0</version>
    <scope>compile</scope>
  </dependency>
</dependencies>
Standardmäßig verwenden alle Beispiele Apache MyFaces . Wenn Sie zu Testzwecken die JSF-Implementierungen ändern wollen, müssen Sie dazu nicht die Datei pom.xml editieren. Alle MyGourmet -Beispiele definieren Profile für Apache MyFaces (ist standardmäßig aktiv) und für Sun Mojarra . Wie Sie diese Profile verwenden können, zeigt Anhang Kapitel:  Eine kurze Einführung in Maven .
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>
Das Grundgerüst dieser Seite ist ein gewöhnliches XHTML-Dokument mit einem im body -Element eingebetteten h:outputText -Tag zur Ausgabe unserer Meldung. Dieses von JSF zur Verfügung gestellte Tag gibt den im Attribut value angegebenen Text aus. Der Präfix h: ist dabei mit dem Namensraum http://java.sun.com/jsf/html verbunden und kennzeichnet die HTML-Tag-Bibliothek von JSF. Sie enthält neben dem Tag h:outputText noch eine Reihe weiterer Tags für Standard-JSF-Komponenten und ihre Darstellung als HTML-Ausgabe - doch dazu später mehr.
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 Konfigurations-datei web.xml mit der Spezifikation eines FacesServlet sowie des zugehörigen Servlet-Mappings spezifiziert. zeigt. Durch das angegebene servlet-mapping -Element werden sämtliche Anfragen mit der Endung .xhtml von genau diesem JSF-Servlet bearbeitet.
<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>
</web-app>
Zu guter letzt definieren wir noch die Seite hello.xhtml als Welcome-File der Anwendung. Damit ist gewährleistet, dass die Seite immer dann angezeigt wird, wenn ein Benutzer im Browser die URL der Anwendung ohne Angabe einer speziellen Seite eingibt.
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 Standardmäßig wird Jetty über mvn clean jetty:run gestartet. Mit JSF 2.0 werden aber in diesem Fall einige Annotationen nicht richtig verarbeitet.: :
mvn clean jetty:run-exploded
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.
Abbildung:Anwendung 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 ).
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.
Abbildung:WYSIWYG-Editor der JBoss-Tools
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;
  }
}
Managed-Bean: Der Zugriff auf das Datenmodell erfolgt in JSF über sogenannte Managed-Beans . In JSF versteht man darunter JavaBeans , die unter einem eindeutigen Namen in der Anwendung zur Verfügung stehen. Um eine Managed-Bean vom Typ Customer zu registrieren, genügt es in JSF 2.0, die Klasse mit @ManagedBean zu annotieren. Der Name, unter dem die Bean zur Verfügung steht, wird vom Klassennamen abgeleitet und lautet in unserem Fall customer .
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:commandButton id="save" value="Save"
          action="/showCustomer.xhtml"/>
    </h:panelGrid>
  </h:form>
</body>
</html>
Abbildung MyGourmet 1: Komponenten und ihre Darstellung zeigt die Darstellung der Seite im Browser und den Zusammenhang zu den JSF-Komponenten in der XHTML-Datei.
Abbildung:MyGourmet 1: Komponenten und ihre Darstellung
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>
Applikationslogik ausführen: Fertig! Die Applikation funktioniert bereits so wie gewünscht und leitet uns von der ersten Seite durch einen Klick auf die Schaltfläche weiter - auf der zweiten Seite werden die eingegebenen Daten angezeigt. In einer "realen" Applikation würden wir die Daten jetzt abspeichern, dazu müssen wir durch die von der Schaltfläche ausgelöste Aktion auf eine Methode der dahinterliegenden Managed-Beans zugreifen. Auch dieser Schritt ist unkompliziert, statt das Attribut action direkt auf eine Zeichenkette zu setzen, verwenden wir eine Method-Expression , die auf eine Methode in der dahinterliegenden Managed-Bean referenziert. Mit der gleichen Syntax, mit der wir vorher auf eine Variable in der Managed-Bean customer zugegriffen haben, können wir jetzt auch eine Methode referenzieren. Der geänderte Code der Schaltfläche sieht folgendermaßen aus:
<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@Work . Dort wird das Verständnis der zuvor definierten Grundbegriffe im Praxiseinsatz vertieft.