Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer...

26
Kapitel 3 Der Anwendungsprototyp Ein Arbeitsbuch f¨ ur die Praxis darf JavaServer Faces nicht durch eine (unzu- sammenh¨ angende) Aneinanderreihung von Beschreibungen einzelner Sprachei- genschaften und Konzepte einf¨ uhren, sondern muss anhand einer realistischen Aufgabe die gebotenen JSF-Mittel zu deren L¨ osung einsetzen. In diesem Kapi- tel werden wir f¨ ur die imagin¨ are JSF-Bank die Anwendung Online-Banking als Prototyp entwickeln, die in stark simplifizierter Art Teile eines realen Online- Bankings nachbildet. Ziel ist die Erstellung einer kompletten“ Anwendung, die bereits m¨ oglichst viele Teile der JSF-Spezifikation verwendet, ohne f¨ ur den JSF-Anf¨ anger zu komplex zu werden. Nach einer ausf¨ uhrlichen Darstellung von JavaServer Faces im n¨ achsten Kapitel und einer Vorstellung der in Java- Server Faces verf¨ ugbaren UI-Komponenten in Kapitel 5 wird der Protoyp in Kapitel 6 dann umfassend ¨ uberarbeitet. 3.1 Anwendungsf¨ alle Unser Ziel ist die Entwicklung einer kompletten Anwendung, die allerdings noch nachvollziehbar und damit nicht zu komplex sein soll. Um dies zu er- reichen, m¨ ussen wir uns in der Funktionalit¨ at beschr¨ anken. Der Prototyp soll unf einfache Anwendungsf¨ alle umfassen, die wir kurz beschreiben. Anmeldung Ein Benutzer meldet sich mit Kundennummer und Kennwort an. Eine er- folgreiche Anmeldung ist Voraussetzung f¨ ur die weiteren Anwendungsf¨ alle.

Transcript of Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer...

Page 1: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

Kapitel 3

Der Anwendungsprototyp

Ein Arbeitsbuch fur die Praxis darf JavaServer Faces nicht durch eine (unzu-sammenhangende) Aneinanderreihung von Beschreibungen einzelner Sprachei-genschaften und Konzepte einfuhren, sondern muss anhand einer realistischenAufgabe die gebotenen JSF-Mittel zu deren Losung einsetzen. In diesem Kapi-tel werden wir fur die imaginare JSF-Bank die Anwendung Online-Banking alsPrototyp entwickeln, die in stark simplifizierter Art Teile eines realen Online-Bankings nachbildet. Ziel ist die Erstellung einer ”kompletten“ Anwendung,die bereits moglichst viele Teile der JSF-Spezifikation verwendet, ohne fur denJSF-Anfanger zu komplex zu werden. Nach einer ausfuhrlichen Darstellungvon JavaServer Faces im nachsten Kapitel und einer Vorstellung der in Java-Server Faces verfugbaren UI-Komponenten in Kapitel 5 wird der Protoyp inKapitel 6 dann umfassend uberarbeitet.

3.1 Anwendungsfalle

Unser Ziel ist die Entwicklung einer kompletten Anwendung, die allerdingsnoch nachvollziehbar und damit nicht zu komplex sein soll. Um dies zu er-reichen, mussen wir uns in der Funktionalitat beschranken. Der Prototyp sollfunf einfache Anwendungsfalle umfassen, die wir kurz beschreiben.

AnmeldungEin Benutzer meldet sich mit Kundennummer und Kennwort an. Eine er-folgreiche Anmeldung ist Voraussetzung fur die weiteren Anwendungsfalle.

Page 2: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

22 3 Der Anwendungsprototyp

Pflege der StammdatenIm Falle eines Umzugs, einer Heirat mit Namensanderung etc. soll derKunde seine Stammdaten selbst aktualisieren konnen.

Uberweisung durchfuhrenDas eigentliche Bankgeschaft: Uberweisung eines bestimmten Betrages voneinem eigenen Konto auf ein beliebiges anderes Konto.

Anzeige der UmsatzeFur ein auszuwahlendes Konto werden alle Umsatze angezeigt.

Anzeige der Kurzinformationen zu allen KontenDie Kontostande aller Konten werden angezeigt.

3.2 Technische Architektur

JavaServer Faces wird man in Zukunft sicher haufig als GUI-Komponentevon Java-EE-Anwendungen einsetzen. Die Business-Objekte einer Java-EE-Anwendung werden in der Regel mit Enterprise-JavaBeans implementiert. Ja-vaServer Faces sind aber nicht an die Verwendung von EJBs gebunden, sondernkonnen mit beliebigen Java-Objekten, insbesondere auch mit POJOs (PlainOld Java Objects), verwendet werden. Unser Projekt Online-Banking wird mitPOJOs entwickelt. Diese werden mit Hilfe eines Object-Relational-Mappers(OR-Mapper) auf eine relationale Datenbank abgebildet. Es ergibt sich einetechnische Architektur, die strukturell in Abbildung 3.1 dargestellt ist. Java-

Browser

HTTPPersistenz

JSF POJO

Servlet−Container

DB

HTTPS

View

ControllerModell

Business−

Abbildung 3.1: Architektur des Prototyps

Server Faces realisieren die Kommunikation mit dem Browser. Der Prototypverwendet als Protokoll HTTP. Eine reale Online-Banking-Anwendung wur-de HTTPS verwenden. Das Business-Modell ist mit einfachen Java-Klassen

Page 3: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.3 Das Business-Modell 23

realisiert, die uber eine Persistenzschicht auf Tabellen einer relationalen Da-tenbank abgebildet werden. In diesem Kapitel gehen wir auf Probleme desOR-Mappings nicht detaillierter ein, sondern verweisen auf Abschnitt 6.4.JavaServer Faces werden durch Servlets, genauer durch ein Servlet, realisiert.Fur den Betrieb einer JSF-Anwendung benotigt man daher einen Servlet-Container. Wir verwenden hier Tomcat, den Servlet-Container der ApacheSoftware Foundation. Tomcat ist die offizielle Referenzimplementierung derServlet-Spezifikation, weit verbreitet und zudem unentgeltlich sowohl privatals auch kommerziell verwendbar. Als Persistenzschicht kommt Hibernate zumEinsatz. Als Datenbankmanagementsystem verwenden wir das in Java ge-schriebene und somit auf praktisch jedem Rechner lauffahige HSQLDB . Eskann so konfiguriert werden, dass es nach dem Deployment der Web-Anwen-dung sofort lauft, so dass aufwandige Installationen, Konfigurationen und ins-besondere Datenimporte unnotig sind.

3.3 Das Business-Modell

Das Business-Modell des Online-Bankings ist ebenfalls stark simplifiziert. Le-ser, die bereits ahnliche Systeme erstellt haben, mogen dies verzeihen. FurLehr- und Lerninhalte zum Thema JavaServer Faces reicht das einfache Busi-ness-Modell aber aus. Das Modell enthalt Kunden, Konten und ein Transak-tionslog. Bei den Konten wird zwischen Giro- und Sparkonten unterschieden.Das entsprechende UML-Klassendiagramm ist in Abbildung 3.2 auf der nach-sten Seite dargestellt.Im Folgenden gehen wir davon aus, dass die funf Business-Klassen wie darge-stellt als JavaBeans existieren. Die Attribute jeder Klasse besitzen entspre-chende Getter und Setter, und die Assoziationen sind als Methoden Kun-de.getKonten(), Konto.getKunde() sowie Konto.getTransaktionen() undTransaktionslog.getKonto() verfugbar.

3.4 Realisierung

Die funf Anwendungsfalle aus Abschnitt 3.1 realisieren wir mit funf JSF-Seiten.Dies muss nicht immer so sein, wird aber oft zutreffen. Anwendungsfalle, diekomplexe Workflows umfassen, werden in der Regel uber mehrere JSF-Seitendefiniert.Dieses Kapitel dient als Demonstration einer funktional einfachen, aber kom-pletten Anwendung. Es werden daher nicht alle Einzelheiten im Detail er-

Page 4: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

24 3 Der Anwendungsprototyp

1 0..*

transaktionen

1 1..*

konto

Kunde

-vorname:String-nachname:String-geburtsdatum:Date-geschlecht:Character-strasse:String-plz:String-ort:String

Konto

-kontostand:BigDecimal

Transaktionslog

-betrag:BigDecimal-art:Character-datum:Date-text:String

Girokonto

-ueberziehungskredit:BigDecimal-zinssatzKredit:BigDecimal-zinssatzGuthaben:BigDecimal

Sparkonto

-zinssatz:BigDecimal

Abbildung 3.2: UML-Klassendiagramm fur den Prototyp

lautert. Eine detailierte Gesamtdarstellung der Moglichkeiten von JavaServerFaces finden Sie in Kapitel 4, eine Gesamtdarstellung der JSF-Tags im An-hang A.

3.4.1 Die Anmeldung

Fur die Anmeldung wird die Kundennummer und das Kennwort benotigt. Ge-nugen beide den Authentifizierungsregeln, so wird der Benutzer in die eigent-liche Anwendung weitergeleitet, sonst ist eine Meldung uber die missgluckteAnmeldung anzuzeigen. Listing 3.1 zeigt die JSF-Seite login.jsp fur die An-meldung.

Listing 3.1: Die Seite login.jsp

1 <%@ page session="false" contentType="text/html;charset=utf-8"%>

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

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

45 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional //EN">

6 <html>

7 <%@include file="include/head.inc"%>

8 <body>

9 <f:view >

10 <h:form id="form" style="margin: 100px;">

11 <h:panelGrid columns="2" styleClass="borderTable"

Page 5: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 25

12 headerClass="panelHeading">

13 <f:facet name="header">

14 <h:outputText value="Anmeldung Online-Banking" />

15 </f:facet >

16 <h:outputLabel for="kundennummer" value="Kundennummer:" />

17 <h:inputText id="kundennummer"

18 value="#{ kundenHandler.kundennummer}" />

19 <h:outputLabel for="kennwort" value="Kennwort:" />

20 <h:inputSecret id="kennwort"

21 value="#{ kundenHandler.kennwort}" />

22 <h:commandButton action="#{ kundenHandler.login}"

23 value="Anmelden" />

24 <h:panelGroup />

25 </h:panelGrid >

26 </h:form >

27 </f:view >

28 </body>

29 </html>

In den Zeilen 2 und 3 werden die beiden JSF-Tag-Bibliotheken bekannt ge-macht. Tag-Bibliotheken sind eine Spracheigenschaft der JavaServer Pages(JSP), die fur JavaServer Faces als Default-Implementierung verwendet wer-den. Die beiden Prafixe, in diesem Fall h und f, sind beliebig wahlbar, mansollte jedoch der ublichen Konvention folgen und diese beiden Buchstabenwahlen. Die erste JSF-Komponente ist <f:view>. Diese ist ein Container,das heißt, sie kann andere Komponenten enthalten. Jede JSF-Seite muss alsWurzel eine View enthalten, die alle anderen JSF-Komponenten enthalt. Dienachste Komponente ist <h:form>. Diese wird nach dem Rendern in HTMLzu einem HTML-Formular. Die Komponente <h:panelGrid> ist ebenfalls einContainer und ordnet ihre eingebetteten Komponenten in Tabellenform an.Dazu wird lediglich die Anzahl der Spalten spezifiziert, die Definition einzel-ner Zeilen ist nicht moglich. Ein Panel-Grid enthalt optional eine Uberschrift,die mit der <f:facet>-Komponente und Attribut name="header" in Zeile13 festgelegt wird. Die weiteren, zum Teil mehrfach verwendeten Komponen-ten sind <h:outputText>, <h:outputLabel> und <h:inputText>, die eineTextausgabe, ein Label und ein Eingabefeld erzeugen. Die <h:inputSecret>-Komponente ist eine Eingabekomponente, die den eingegebenen Text jedochnicht anzeigt und daher in der Regel zur Passworteingabe verwendet wird.Schließlich erzeugt <h:commandButton> eine Schaltflache, deren Betatigungzum Aufruf einer Action-Methode fuhrt. Die <h:panelGroup>-Komponentewird verwendet, um mehrere Komponenten zusammenzufassen. Hier wird sieals Platzhalter verwendet, um in der letzten Zeile der Tabelle die zweite Spaltezu fullen.

Page 6: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

26 3 Der Anwendungsprototyp

Auch ohne detaillierte Kenntnis der einzelnen Komponenten ist diese JSF-Seiterecht gut verstandlich, und die aus ihr entstehende HTML-Seite kann bereitserahnt werden. Die entsprechende Darstellung im Browser ist in Abbildung 3.3dargestellt.

Abbildung 3.3: Browserdarstellung von login.jsp

Interessant ist nun, wie die JSF-Seite mit dem Java-Handler fur diese Seiteverbunden wird. Aus der JSF-Seite geht hervor, dass eine JavaBean kunden-Handler mit den Properties kundennummer und kennwort sowie der Action-Methode login verwendet wird. Die Bean ist eine Instanz der in Listing 3.2dargestellten Klasse KundenHandler. Diese Art Bean wird in der Originallite-ratur auch Backing-Bean genannt.

Listing 3.2: Die Managed-Bean KundenHandler

/**

* Nach einem erfolgreichen Login merkt sich die

* KundenHandler -Instanz den Kunden.

*/

public class KundenHandler {

private String kundennummer;

private String kennwort;

private Kunde kunde; // Der Kunde , global fuer Session

private List konten; // Konten dieses Kunden

private List kontenItems; // Zur Anzeige in Auswahlmenues

public String login () {

Page 7: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 27

// in der Version 1.0 ein wenig vereinfacht

if (kundennummer.equals("0815")

&& kennwort.equals("geheim")) {

kunde = new KundeDAO (). getKundeById (1111);

konten = new ArrayList(kunde.getKonten ());

return "success";

} else {

return "failure";

}

}

public List getKontenItems () {

if (this.kontenItems == null) {

List kontenItems = new ArrayList ();

for (Iterator i = konten.iterator (); i.hasNext ();) {

Konto tmp = (Konto) i.next ();

kontenItems.add(

new SelectItem(tmp , KontoConverter.getAsString(tmp )));

}

this.kontenItems = kontenItems;

}

return this.kontenItems;

}

// ab hier nur einfache Getter und Setter

}

Fur den Anmeldevorgang sind nur die Properties kennwort, kundennummerund kunde mit den nicht dargestellten Gettern und Settern sowie die Methodelogin() interessant. Die beiden erstgenannten Properties sind durch JSF-EL-Ausdrucke an die beiden <h:inputText>-Komponenten gebunden. Mankonnte auch sagen, dass die beiden Komponenten an die Properties gebun-den sind. Da die Bindung aber bidirektional ist, ist beides richtig. Wenn dielogin-Methode aufgerufen wird, stehen in den beiden Properties bereits diekorrekten Werte des HTML-Formulars. In der Bedingung der If-Verzweigungkann daher getestet werden, ob die Kundennummer 0815 und das Kennwortgeheim ist. Dieser sehr einfache Fall ist dem einfuhrenden Charakter dieser Au-thentifizierung geschuldet. In Kapitel 6 wird die Authentifizierung nach dem inder Servlet-Spezifikation festgelegten Verfahren vorgenommen. Falls die Ein-gaben von Kundennummer und Kennwort die verlangten Werte haben, wirdden Variablen kunde und konten ein Wert zugewiesen und die Methode miteinem Return-Wert von "success" beendet. Wenn nicht, gibt die Methode"failure" zuruck. Die Variable kunde bekommt ein Kundenobjekt zugewie-sen, das der Klasse Kunde des Klassendiagramms aus Abbildung 3.2 entspricht.

Page 8: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

28 3 Der Anwendungsprototyp

Wir wollen uns an dieser Stelle auf den Umgang mit JavaServer Faces konzen-trieren, so dass wir auf die Klasse KundeDAO nicht naher eingehen. Wir ver-weisen auf Abschnitt 6.4, in dem das so genannte Data-Access-Object-Pattern(DAO) eingehend erlautert wird.Die Methode login() hat einen Ruckgabewert vom Typ String. Eigentlichwurde man fur eine Methode, die durch die Betatigung eines Knopfes aufge-rufen wird, eher void oder boolean erwarten. Der Grund fur die Verwendungvon String ist, dass Action-Methoden vom Laufzeitsystem zur Navigationverwendet werden. Im einfuhrenden Tic-Tac-Toe-Spiel haben wir hiervon kei-nen Gebrauch gemacht und immer dieselbe Seite angezeigt. Hier soll jedochabhangig vom Ausgang des Anmeldeversuchs der Benutzer entweder in dieeigentliche Anwendung geleitet werden oder eine Seite mit der entsprechen-den Information uber die missgluckte Anwendung angezeigt bekommen. DieKonstante "success" zeigt den gegluckten, failure den missgluckten Anmel-deversuch an.Wo wird nun der zuruckgegebene String verwendet? JavaServer Faces reali-siert die Navigation uber eine deklarative Beschreibung, die vom so genanntenNavigation-Handler interpretiert wird. Basis sind (unter anderem) die vonAction-Methoden zuruckgegebenen Werte. Die Beschreibung selbst geschiehtin der Konfigurationsdatei faces-config.xml, in der auch die Managed-Beansdeklariert werden. Der entsprechende Ausschnitt der Konfigurationsdatei furdie Navigation der Login-Seite ist in Listing 3.3 dargestellt.

Listing 3.3: Navigationsteil der Konfigurationsdatei faces-config.xml

<navigation-rule >

<description >Das Login </description >

<from-view-id >/pages/login.jsp</from-view-id >

<navigation-case >

<from-outcome >success </from-outcome >

<to-view-id >/pages/kontenuebersicht.jsp</to-view-id >

</navigation-case >

<navigation-case >

<from-outcome >failure </from-outcome >

<to-view-id >/pages/login.jsp</to-view-id >

</navigation-case >

</navigation-rule >

Ohne im Detail die einzelnen Elemente zu erlautern (dies geschieht in Ab-schnitt 4.6), sind mit <from-view-id>, <from-outcome> und <to-view-id>schnell die Elemente identifiziert, die fur eine gegebene Seite und den Ruckga-

Page 9: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 29

bewert einer Action-Methode die neue aktuelle Seite bestimmen. Im vorliegen-den Fall wird durch einen Ruckgabewert "success" zur Seite kontenueber-sicht.jsp verzweigt, bei einem Ruckgabewert von failure wird die Seitelogin.jsp erneut angezeigt. Das erneute Darstellen derselben Seite ist derDefault-Fall der Navigation, so dass die Angabe entfallen konnte.Als letzter Teil bleibt noch die Deklaration der Managed-Bean kundenHandler.Die Deklaration einer Managed-Bean erfolgt, wie wir bereits beim Tic-Tac-Toe-Spiel gesehen haben, in derselben Konfigurationsdatei. Der entsprechendeAusschnitt ist in Listing 3.4 dargestellt. Wichtig ist der auf session gesetzteScope. Jede Session hat daher ihr eigenes KundenHandler-Bean.

Listing 3.4: Die Managed-Bean kundenHandler

<managed-bean >

<managed-bean-name >kundenHandler </managed-bean-name >

<managed-bean-class >

de.jsfpraxis.bank.handler.KundenHandler

</managed-bean-class >

<managed-bean-scope >session </managed-bean-scope >

</managed-bean >

3.4.2 Validierung der Anmeldedaten

Die Kundennummer und das Kennwort werden durch die Methode login()semantisch validiert. Eine syntaktische, zum Teil sogar ebenfalls semantischeValidierung kann aber auch durch die JSP-Implementierung selbst vorgenom-men werden und somit viele Routineprufungen uberflussig machen.Im Falle der Anmeldedaten sind sowohl Kundennummer als auch KennwortPflichtangaben, das heißt, ein leeres Eingabefeld fur diese beiden Daten istals Fehlerfall zu werten. Im Augenblick gibt die login-Methode den String"failure" zuruck, und die Navigationsregel besagt, dass dann noch einmaldie Login-Seite angezeigt wird, allerdings ohne weitere Information fur denBenutzer. Eine entsprechende Fehlermeldung ware hier angebracht.JavaServer Faces verfugt als einfachste Form der Validierung uber den Testauf eine zwingend notwendige Eingabe, aber auch uber eine Reihe komplexererTests. Der Test auf eine notwendige Eingabe wird durch das boolesche Attributrequired deklariert. Die Verwendung des Attributes mit dem Wert true fuhrtaber lediglich dazu, dass die weitere Bearbeitung der Seite unterbleibt und dieMethode login erst gar nicht aufgerufen wird. Details uber die einzelnen Be-arbeitungsschritte einer JSF-Requests werden in Abschnitt 4.1 erlautert. Um

Page 10: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

30 3 Der Anwendungsprototyp

eine Meldung an den Benutzer zu erzeugen, wird die Meldungs-Komponenteverwendet. Diese existiert in zwei Formen: <h:message> und <h:messages>.Die erste Form erzeugt eine Meldung fur eine bestimmte Komponente, diezweite erzeugt Meldungen fur alle Komponenten einer JSF-Seite. Wir verwen-den die erste Form. Fur die Zuordnung zu einer Eingabekomponente wird dasfor-Attribut verwendet.Um das zweispaltige Layout der Anmeldung nicht zu zerstoren, mussen dieMeldungen und die Eingaben zusammengefasst werden. Hier kommt das Tag<h:panelGroup> zum Einsatz. Listing 3.5 zeigt den Ausschnitt aus der uber-arbeiteten Login-Seite.

Listing 3.5: Login-Seite mit Fehlermeldung

1 <h:outputLabel for="kundennummer" value="Kundennummer:" />

2 <h:panelGroup >

3 <h:inputText id="kundennummer" required="true"

4 value="#{ kundenHandler.kundennummer}" />

5 <h:message for="kundennummer" />

6 </h:panelGroup >

7 <h:outputLabel for="kennwort" value="Kennwort:" />

8 <h:panelGroup >

9 <h:inputSecret id="kennwort" required="true"

10 value="#{ kundenHandler.kennwort}" />

11 <h:message for="kennwort" />

12 </h:panelGroup >

Bleibt bei der uberarbeiteten Seite eines der beiden Eingabefelder leer, wirddie entsprechende Fehlermeldung fur die Message-Komponente erzeugt. Ab-bildung 3.4 zeigt die Darstellung im Browser, wenn beide Felder bei der Beta-tigung der Schaltflache leer sind.Der Fehlertext wird in englischer Sprache dargestellt, was nicht sonderlichbefriedigend ist. Weil Java von Haus aus bereits viele Moglichkeiten der Loka-lisierung mitbringt, bauen JavaServer Faces hierauf auf und erlauben es, mitrelativ wenig Aufwand Anwendungen zu lokalisieren. Eine Moglichkeit ist dieVerwendung des locale-Attributs im <f:view>-Tag:

<f:view locale="Locale.GERMAN">

Alternativen fur die Lokalisierung auf Anwendungs- und nicht auf Seitenebenewerden in Abschnitt 4.7 dargestellt.Nach dieser Anderung wird die Seite bei fehlenden Eingaben wie in Abbil-dung 3.5 dargestellt.

Page 11: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 31

Abbildung 3.4: Originalfehlermeldungen

Abbildung 3.5: Fehlermeldungen mit deutscher Lokalisierung

Wahrend der Entwicklung einer JSF-Seite empfehlen wir die Ver-wendung des Tags <h:messages> z.B. am Ende der Seite. So wer-den alle auftretenden Fehler auch tatsachlich angezeigt.

Wir werden in Abschnitt 4.4 noch weitere Moglichkeiten der Validierung ken-nen lernen.

3.4.3 Pflege der Stammdaten

Der Anwendungsfall ”Pflege der Stammdaten“ ermoglicht es Bankkunden, ihreStammdaten selbst zu aktualisieren, z.B. nach einem Umzug oder nach einerNamensanderung. Die entsprechende JSF-Seite ist typisch fur die Stammda-tenverwaltung und wird in abgewandelter Form haufig in betrieblichen Infor-mationssystemen Verwendung finden. Wir stellen hier zunachst die Seitendar-

Page 12: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

32 3 Der Anwendungsprototyp

stellung vor, um danach die entsprechenden JSF-Elemente zu ihrer Entwick-lung zu erarbeiten.

Abbildung 3.6: Seite fur den Anwendungsfall ”Pflege der Stammdaten“

Abbildung 3.6 zeigt die zu erstellende Seite zur Pflege der personlichen Daten.Man erkennt bereits die Tabellenform, die typische zeilenweise Beschriftungund Eingabe-Anordung sowie eine Schaltflache zum Abspeichern von Ande-rungen.Ebenfalls zu erkennen ist die Menufuhrung auf der linken Seite. Die JSF-Spezifikation kennt in der Version 1.1 keine Menukomponente. Wir verwendenhier jedoch MyFaces. In dieser Implementierung ist eine Menukomponente vor-handen, die wir auch einsetzen. Eine alternative Umsetzung ausschließlich mitKomponenten der Spezifikation ist moglich, benotigt dann aber aufwandigereKonstrukte im HTML- und CSS-Code und soll hier nicht weiter Gegenstandsein. Auf der Web-Site des Buches steht der Quell-Code fur die dargestelltenSeiten zur Verfugung. Wir gehen daher im Folgenden nicht auf das Menu, denSeitenkopf und die Fußzeile ein und verweisen fur weitere Informationen auf dieWeb-Site des Buches, von der Sie den kompletten Quell-Code herunterladenkonnen.

Listing 3.6: Personliche Daten als JSF-Code (persoenliche-daten.jsp)

1 <h:form id="form">

2 <h:panelGrid columns="2" styleClass="borderTable"

Page 13: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 33

3 style="width: 100%;" headerClass="panelHeading">

4 <f:facet name="header">

5 <h:outputText value="Personliche Daten" />

6 </f:facet >

7 <h:outputLabel for="anrede" value="Anrede:" />

8 <h:selectOneMenu id="anrede"

9 value="#{ persoenlicheDatenHandler.kunde.geschlecht}">

10 <f:selectItem itemValue="m" itemLabel="Herr"/>

11 <f:selectItem itemValue="w" itemLabel="Frau"/>

12 </h:selectOneMenu >

13 <h:outputLabel for="vorname" value="Vorname:" />

14 <h:inputText id="vorname"

15 value="#{ persoenlicheDatenHandler.kunde.vorname}" />

16 <h:outputLabel for="nachname" value="Nachname:" />

17 <h:inputText id="nachname"

18 value="#{ persoenlicheDatenHandler.kunde.nachname}" />

19 <h:outputLabel for="geburtsdatum" value="Geburtsdatum:" />

20 <h:inputText id="geburtsdatum"

21 value="#{ persoenlicheDatenHandler.kunde.geburtsdatum}">

22 <f:convertDateTime pattern="dd.MM.yyyy" />

23 </h:inputText >

24 <h:outputLabel for="strasse" value="Straße:" />

25 <h:inputText id="strasse"

26 value="#{ persoenlicheDatenHandler.kunde.strasse}" />

27 <h:outputLabel for="plz" value="PLZ:" />

28 <h:inputText id="plz"

29 value="#{ persoenlicheDatenHandler.kunde.plz}" />

30 <h:outputLabel for="ort" value="Ort:" />

31 <h:inputText id="ort"

32 value="#{ persoenlicheDatenHandler.kunde.ort}" />

33 </h:panelGrid >

34 <h:panelGrid columns="1">

35 <h:commandButton value=" Anderungen speichern"

36 action="#{ persoenlicheDatenHandler.save}" />

37 </h:panelGrid >

38 </h:form >

Listing 3.6 zeigt den JSF-Code fur die Verwaltung der personlichen Daten.Die ersten Tags sind bereits bekannt. Neu ist das Tag <h:selectOneMenu> inZeile 8. Diese Komponente erzeugt eine Drop-down-Liste, die zur Auswahl derAnrede dient. Uber eine Wertebindung wird der aktuelle Wert der Auswahlmit dem JSF-EL-Ausdruck

#{ persoenlicheDatenHandler.kunde.geschlecht}

verbunden. Wir hatten bereits bei der Anmeldung derartige Ausdrucke ver-wendet, jedoch in einfacherer Form. Die JSF-Expression-Language ahnelt der

Page 14: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

34 3 Der Anwendungsprototyp

JSP-Expression-Language und wird in Abschnitt 4.2 vorgestellt. Sie enthaltKonzepte, wie man sie auch in JavaScript und XPath, einer Sprache zur Refe-renzierung von Elementen eines XML-Dokuments, findet. Der obige Ausdruckwird auf zwei Arten verwendet, zum Lesen und zum Schreiben. Er entsprichtdabei ungefahr den folgenden Code-Fragmenten:

PersoenlicheDatenHandler persoenlicheDatenHandler;

...

// in die HTML -Ausgabe schreibend:

<HTML -Code > persoenlicheDatenHandler.getKunde (). getGeschlecht ()

<HTML -Code >

...

// aus der HTML -Eingabe lesend:

persoenlicheDatenHandler

.getKunde (). setGeschlecht(<HTML -Eingabe >);

Wenn die JSF-Implementierung den HTTP-Request erhalt und beginnt, ihnabzuarbeiten, werden die beteiligten JavaBeans uber die Setter mit den Wer-ten des HTML-Formulars versorgt. Nach der Abarbeitung der Anwendungs-logik wird auf dem Server HTML-Code erzeugt, bei dem die entsprechendenFormularwerte mit den Werten der JavaBeans uber die Getter gesetzt werden.Fur die <h:inputText>-Tags ist dies leicht vorstellbar, fur das <h:select-OneMenu>-Tag muss ein wenig weiter ausgeholt werden. Dem MVC-Patternliegt eine vollige Trennung zwischen Modell und View zugrunde. Unser Modelldes UML-Klassendiagramms aus Abbildung 3.2 beschreibt das Geschlecht alsZeichen, das die Werte ’m’ und ’w’ fur mannlich und weiblich annehmenkann. In der View sind mehrere Moglichkeiten vorstellbar, z.B. als Radio-Button oder als Drop-down-Menu. Wir haben uns fur die zweite Moglichkeitentschieden, die mittels eines <h:selectOneMenu> zu realisieren ist. Es mussnun eine Konvertierung der Anzeige Herr/Frau zu den Modellwerten m/wund umgekehrt erfolgen. Dies wird durch die geschachtelten <f:selectItem>-Tags erreicht. Der Item-Wert wird fur die Getter und Setter der JavaBeanverwendet, das Item-Label fur die Darstellung in HTML.Die restlichen Eingaben sind Texte, so dass diese unproblematisch sind. Ein-zige Ausnahme ist das Eingabefeld des Geburtsdatums. Das Geburtsdatumist auf Bean-Seite vom Typ java.util.Date. Auf der HTML-Seite kann esaber nur ein String sein. Da die Konvertierung eines Datums oder etwa einerZahl in einen String und umgekehrt zu den haufigeren Aufgaben bei der Ent-wicklung von Web-Anwendungen gehort, stellen JavaServer Faces eine Reihevordefinierter Konvertierer bereit. Im Falle des Geburtsdatums verwenden wirin Zeile 22 den Datum-Konvertierer, der sehr viele Moglichkeiten der Kon-figuration kennt. Eine Moglichkeit der Einstellung erfolgt uber ein Pattern,

Page 15: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 35

das die Struktur des Datums darstellt. Hier wird als Pattern ”Tag, Monat,vierstelliges Jahr, durch Punkt getrennt“ definiert.Die Seite wird mit einer Schaltflache zum Abspeichern eventueller Anderun-gen abgeschlossen. In Zeile 36 wird im action-Attribut die Methode save()als aufzurufende Methode bei Betatigung der Schaltflache definiert. Die Java-Implementierung der Methode save() innerhalb der Handler-Bean ist trivialund reduziert sich auf einen Methodenaufruf des DAO-Objekts. Den interes-sierten Leser vertrosten wir fur Persistenzfragen auf Abschnitt 6.4.public class PersoenlicheDatenHandler {

private Kunde kunde;

public String save() {

new DAO(). saveOrUpdate(kunde);

return "success";

}

...

3.4.4 Uberweisungen

Der Anwendungsfall ”Uberweisung durchfuhren“ muss fur unseren Prototy-pen etwas eingeschrankt werden. Da nur die JSF-Bank existiert und damitkein Zahlungsverkehr zwischen Banken realisiert werden kann, konnen Uber-weisungen nur innerhalb der Konten der JSF-Bank getatigt werden. Bei einerUberweisung sind somit die Kontonummer des Empfangerkontos, der Verwen-dungszweck und der Betrag anzugeben. Abbildung 3.7 auf der nachsten Seitezeigt die fertige Uberweisungsseite im Browser.Die Uberweisungsseite ist sehr einfach strukturiert. Die eigentliche Durchfuh-rung der Uberweisung ist allerdings der komplexeste Anwendungsfall des Pro-totypen. Schauen wir uns zunachst die JSF-Seite im Quell-Code an, der inListing 3.7 dargestellt ist.

Listing 3.7: Uberweisungsseite (ueberweisung.jsp)

1 <h:form id="form">

2 <h:panelGrid columns="1" styleClass="standardTable"

3 style="width: 100%;" headerClass="panelHeading">

4 <f:facet name="header">

5 <h:outputText value=" Uberweisung" />

6 </f:facet >

7 <h:panelGrid columns="2" styleClass="borderTable">

8 <h:outputLabel for="selectOneMenuKonto" value="Konto: " />

Page 16: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

36 3 Der Anwendungsprototyp

Abbildung 3.7: Uberweisungen

9 <h:selectOneMenu id="selectOneMenuKonto"

10 value="#{ ueberweisungHandler.konto}"

11 converter="KontoConverter">

12 <f:selectItems value="#{ kundenHandler.kontenItems}" />

13 </h:selectOneMenu >

14 <h:outputLabel for="kontonummer"

15 value="Kontonummer Empfanger:" />

16 <h:inputText id="kontonummer" required="true"

17 value="#{ ueberweisungHandler.kontonummer}" />

18 <h:outputLabel for="verwendungszweck"

19 value="Verwendungszweck:" />

20 <h:inputText id="verwendungszweck" required="true"

21 value="#{ ueberweisungHandler.verwendungszweck}" />

22 <h:outputLabel for="betrag" value="Betrag" />

23 <h:inputText id="betrag" required="true"

24 value="#{ ueberweisungHandler.betrag}">

25 <f:validateDoubleRange minimum="1" maximum="1000" />

26 </h:inputText >

27 </h:panelGrid >

28 <h:commandButton id="ueberweisen"

29 value=" Uberweisung durchfuhren"

30 action="#{ ueberweisungHandler.ueberweisen}" />

31 </h:panelGrid >

32 </h:form >

Die ersten Zeilen sind als Wiederholung bereits bekannt. Interessant wird esin den Zeilen 9 bis 13. Hier wird wieder ein <h:selectOneMenu>-Tag verwen-

Page 17: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 37

det, um in der Drop-down-Auswahl eine Liste aller Konten des Kunden zuerzeugen. Wahrend im letzten Beispiel die Unterscheidung der Anrede in Herrund Frau statisch gewesen ist, sind die Konten nicht vorherbestimmt und un-terscheiden sich von Kunde zu Kunde. Die Konten mussen daher aus demBusiness-Modell bzw. aus der Datenbank geholt und dynamisch fur die Dar-stellung in der Drop-down-Auswahl vorbereitet werden. Um dies zu erreichen,mussen prinzipiell zwei Funktionalitaten realisiert werden: zum einen die Mog-lichkeit, eine dynamische Liste zu erstellen, zum anderen, Modell-Objekte inStrings (die Anzeige) und Strings in Modell-Objekte konvertieren zu konnen.Die erste Funktionalitat wird durch das <f:selectItems>-Tag realisiert, dasals value-Attribut eine Liste von Objekten des Typs javax.faces.model.Se-lectItem erwartet. Die zweite Funktionalitat, die Konvertierung von Modell-Objekten, wird durch einen anwendungsspezifischen Konvertierer realisiert. InZeile 11 wird der Konvertierer KontoConverter dem Attribut converter zu-gewiesen. Die weiteren Komponenten der Seite sind bereits bekannt, so dasswir uns der SelectItem-Liste und dem Konvertierer widmen.Die Methode getKontenItems() des Kunden-Handlers liefert die entsprechen-den SelectItems. Die Implementierung der Methode ist in Listing 3.8 darge-stellt.

Listing 3.8: Die Managed-Bean KundenHandler

public List getKontenItems () {

if (this.kontenItems == null) {

List kontenItems = new ArrayList ();

for (Iterator i = konten.iterator (); i.hasNext ();) {

Konto tmp = (Konto) i.next ();

kontenItems.add(

new SelectItem(tmp , KontoConverter.getAsString(tmp )));

}

this.kontenItems = kontenItems;

}

return this.kontenItems;

}

Die Methode getKontenItems() wird uber das <f:selectItems>-Tag immeraufgerufen, wenn die Seite neu darzustellen ist. Ein Kunde kann zwar einesseiner Konten kundigen oder ein neues Konto zu den bereits bestehenden hin-zubekommen, doch kommt dies wahrend einer Online-Banking-Sitzung rela-tiv selten vor. Der Kunden-Handler merkt sich daher in der InstanzvariablenkontenItems die Liste der Konten als SelectItems. Die Variable wird nach

Page 18: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

38 3 Der Anwendungsprototyp

dem Lazy-Initializer-Pattern erst bei Bedarf, d. h. bei der ersten Verwendunginitialisiert, danach bei jedem weiterem Zugriff ohne neuen Berechnungsvor-gang zuruckgegeben. Die Instanzvariable konten ist die Liste der Konten desKunden.Der Konstruktor von javax.faces.model.SelectItem ist uberladen. In dervon uns verwendeten Version

SelectItem(java.lang.Object value , java.lang.String label)

wird im ersten Parameter das Objekt selbst, im zweiten Parameter der anzuzei-gende String ubergeben. Das JSF-Laufzeitsystem erzeugt aus der SelectItem-Liste eine Liste von Strings, die in der Drop-down-Liste zur Anzeige gebrachtwerden. Umgekehrt muss bei einer Anfrage aus dem selektierten String wiederein Konto-Objekt erzeugt werden. Hierzu wird ein Konvertierer benotigt. Furalle Standardtypen gibt es entsprechende Konvertierer, fur ein Konto mussein Konvertierer erstellt werden. Das Listing 3.9 zeigt Teile der Konvertierer-klasse KontoConverter, die die Konvertierung zwischen Konten und Stringsrealisiert.

Listing 3.9: Der Konvertierer KontoConverter

public class KontoConverter implements Converter {

public Object getAsObject(FacesContext context ,

UIComponent component ,

String value)

throws ConverterException {

...

}

public String getAsString(FacesContext context ,

UIComponent component ,

Object value)

throws ConverterException {

...

}

public static String getAsString(Konto konto) {

return konto.toString ();

}

}

Ein Konvertierer muss das Interface javax.faces.convert.Converter imple-mentieren, das aus den beiden Methoden getAsObject() und getAsString()

Page 19: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 39

besteht, die einen String in ein Objekt bzw. ein Objekt in einen String konver-tieren. Die Implementierung ist durch die Persistenz von Konten nicht trivial,so dass wir an dieser Stelle auf eine detaillierte Darstellung verzichten.Der letzte erwahnenswerte Punkt bei der Uberweisungsseite ist die Eingabeund Anzeige des Uberweisungsbetrages. Das InputText-Tag ist an die Bean-Property betrag gebunden (Zeile 23). Diese ist vom Typ BigDecimal. Java-Server Faces erkennt den Kompatibilitatskonflikt zwischen String und Big-Decimal und setzt automatisch einen der Standard-Konvertierer ein. DieserKonvertierer geht im Default-Falle von einer amerikanischen Zahlendarstel-lung aus, so dass ein Dezimalpunkt statt des im Deutschen ublichen Dezi-malkommas verwendet wird. Fur den Prototypen ist dieses Verhalten noch zuverzeihen, in der endgultigen Anwendung werden wir dieses Manko beheben.Der in der Uberweisungsseite verwendete Handler UeberweisungHandler ist inListing 3.10 dargestellt. Der Uberweisungs-Handler besteht zum großten Teilaus der Methode ueberweisen(). Der Rest sind die Properties mit Getternund Settern. Wir verzichten auf eine Komplettdarstellung des Handlers.

Listing 3.10: Methode ueberweisen() der Klasse UeberweisungHandler

public String ueberweisen () {

try {

Konto ziel = new KontoDAO (). getKontoById(kontonummer );

Transaktionslog t1 = new Transaktionslog ();

t1.setArt(’E’);

t1.setBetrag(betrag );

t1.setText(verwendungszweck );

t1.setDatum(new Date ());

ziel.addTransaktion(t1);

ziel.setKontostand(ziel.getKontostand ().add(betrag ));

Transaktionslog t2 = new Transaktionslog ();

t2.setArt(’A’);

t2.setBetrag(betrag );

t2.setText(verwendungszweck );

t2.setDatum(new Date ());

konto.addTransaktion(t2);

konto.setKontostand(

konto.getKontostand (). subtract(betrag ));

new DAO(). saveOrUpdate(ziel);

new DAO(). saveOrUpdate(konto);

return "success";

} catch (ObjectNotFoundException e) {

return "unbekanntes Konto";

}

}

Page 20: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

40 3 Der Anwendungsprototyp

Beim Aufruf dieser Methode stehen in den Instanzvariablen kontonummer,betrag und verwendungszweck die Eingaben der Seite. Der Java-geubte Leserwird die Methode problemlos verstehen konnen. Im Transaktionslog wird zwi-schen Ein- und Auszahlungen durch die Art-Angaben ’E’ und ’A’ unterschie-den. Das als OR-Mapper verwendete Hibernate wirft eine ObjectNotFound-Exception, falls das Konto des Empfangers nicht existiert. Ganz analog zurNavigationsregel in Listing 3.3 auf Seite 28 erfolgt hier die Anzeige einer Feh-lermeldung. Wir verzichten daher auf die Darstellung der Navigationsregel undder JSF-Seite fur die Fehlermeldung.

3.4.5 Kontenubersicht

Als Kunde der JSF-Bank wird man in der Regel mehrere Konten besitzen,z.B. ein Giro-, ein Spar- und ein Festgeldkonto. Unser Business-Modell in Ab-bildung 3.2 auf Seite 24 sieht Giro- und Sparkonten vor. Der Anwendungs-fall ”Anzeige der Kurzinformationen zu allen Konten“ ist recht einfach undbesteht aus der Anzeige der Kontoart, der Kontonummer und des aktuellenKontostands. Abbildung 3.8 zeigt die Darstellung im Browser.

Abbildung 3.8: Kontenubersicht

Anwendungen besitzen haufig eine Anzeigemoglichkeit fur a priori unbekanntviele Datensatze. Bei der Kontenubersicht kann ein Kunde ein Konto, ein ande-rer Kunde 20 Konten besitzen. JavaServer Faces besitzen das <h:dataTable>-Tag, mit dem die spaltenweise Darstellung beliebig vieler Zeilen moglich ist.

Page 21: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 41

Listing 3.11 zeigt die Datentabelle der Kontenubersicht-Seite. Auf die Anzeigeder Kundendaten oberhalb der Kontenubersicht verzichten wir.

Listing 3.11: Datentabelle der Kontenubersicht

1 <h:dataTable id="data" style="width: 100%"

2 styleClass="standardTable"

3 headerClass="standardTable_Header"

4 rowClasses="standardTable_Row1 ,standardTable_Row2"

5 columnClasses="standardTable_ColumnCentered"

6 var="konto" value="#{ kundenHandler.konten}">

7 <h:column >

8 <f:facet name="header">

9 <h:outputText value="Kontoart" />

10 </f:facet >

11 <h:outputText value="#{konto.class.simpleName}" />

12 </h:column >

13 <h:column >

14 <f:facet name="header">

15 <h:outputText value="Kontonummer" />

16 </f:facet >

17 <h:outputText value="#{konto.id}" />

18 </h:column >

19 <h:column >

20 <f:facet name="header">

21 <h:outputText value="Kontostand" />

22 </f:facet >

23 <h:outputText value="#{konto.kontostand}" />

24 </h:column >

25 </h:dataTable >

Das <h:dataTable>-Tag besitzt zwei Attribute, die fur die Iteration uber dieDaten benotigt werden. Das Attribut value (im Listing in Zeile 6) ist eineWertebindung, die eine Referenz auf ein List-Objekt oder ein Array liefernmuss. Moglich sind auch JDBC-ResultSets, JSTL-ResultSets und andereObjekte. Das Attribut var (ebenfalls Zeile 6) deklariert einen Bezeichner, deranalog zu einem Iterator des Collection-Frameworks uber die Daten iteriert.Dieser Iterator wird innerhalb der Spalten wiederum in Wertebindungen uberGetter zugegriffen. Die Tabelle der Kontenubersicht besteht aus drei Spal-ten (<h:column>-Tag) mit den Uberschriften (<f:facet>-Tag mit Attributname="header") Kontoart, Kontonummer und Kontostand. Der Zeilenwerteiner jeden Spalte wird durch das <h:outputText>-Tag belegt. In der SpalteKontoart ist dies konto.class.simpleName, ein JSF-EL-Ausdruck, der demJava-Ausdruck konto.getClass().getSimpleName() entspricht. Die Metho-

Page 22: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

42 3 Der Anwendungsprototyp

de Class.getSimpleName() gibt den Namen der Klasse ohne Package-Prafixzuruck. Die Methode wurde in Java 5.0 dem Class-API hinzugefugt. Die Spal-te Kontonummer enthalt die Id eines Kontos. Dieses Attribut ist im UML-Klassendiagramm in Abbildung 3.2 nicht enthalten, da es als Implementie-rungsdetail des OR-Mappers in alle Java-Klassen aufgenommen werden muss,die persistent gemacht werden sollen und nicht zur Fachlichkeit gehort. DasAttribut entspricht dem Primarschlussel der Datenbank. Die Spalte Konto-stand enthalt schließlich den Wert des Properties kontostand. Der kompletteQuell-Code der Seite ist uber die Web-Site des Buches zu erhalten.

3.4.6 Umsatzanzeige

Der letzte Anwendungsfall ist die Anzeige der Umsatze. Fur ein auszuwahlen-des Konto werden die Umsatze tabellarisch angezeigt. Im Prototyp werden alleUmsatze angezeigt, die produktive Anwendung wird Moglichkeiten zur Selek-tion von Umsatzen anbieten. Abbildung 3.9 zeigt die Darstellung im Browser.Die Seite enthalt auf den ersten Blick nur bekannte Elemente: eine Drop-down-Auswahl, eine Schaltflache und eine Tabelle. Trotzdem lohnt ein Blick in denQuell-Code. Listing 3.12 zeigt den interessanten Teil der JSF-Seite.

Abbildung 3.9: Umsatzanzeige

Page 23: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 43

Listing 3.12: Ausschnitt der JSF-Seite Umsatzanzeige

1 <h:panelGrid columns="3" styleClass="borderTable"

2 style="width: 100%;">

3 <h:outputText value="Konto: " />

4 <h:selectOneMenu id="selectOneMenuKonto"

5 value="#{ umsatzanzeigeHandler.konto}"

6 converter="KontoConverter">

7 <f:selectItems value="#{ kundenHandler.kontenItems}" />

8 </h:selectOneMenu >

9 <h:commandButton value="Aktualisieren"

10 action="#{ umsatzanzeigeHandler.aktualisieren}"/>

11 </h:panelGrid >

12 <h:dataTable id="data" style="width: 100%;"

13 styleClass="standardTable"

14 headerClass="standardTable_Header"

15 rowClasses="standardTable_Row1 ,standardTable_Row2"

16 columnClasses="standardTable_Column"

17 var="transaktion"

18 value="#{ umsatzanzeigeHandler.transaktionen}">

19 <h:column >

20 <f:facet name="header">

21 <h:outputText value="Buchungsdatum" />

22 </f:facet >

23 <h:outputText value="#{ transaktion.datum}">

24 <f:convertDateTime pattern="dd.MM.yyyy" />

25 </h:outputText >

26 </h:column >

Das <h:selectOneMenu>-Tag in den Zeilen 3 bis 7 zeigt alle Konten des Kun-den an und ist identisch mit der Uberweisungs-Seite (Listing 3.7 auf Seite 36)mit Ausnahme des value-Attributs. Dies wird hier an das Property konto desUmsatzanzeige-Handlers gebunden.Die in Zeile 11 beginnende Datentabelle ist ahnlich der Datentabelle der Kon-tenubersicht aufgebaut. Interessant ist hier das Property transaktionen desUmsatzanzeige-Handlers. Wir schauen uns dieses Property nun genauer an.Listing 3.13 zeigt einen Ausschnitt der Klasse UmsatzanzeigeHandler.

Listing 3.13: Ausschnitt der Klasse UmsatzanzeigeHandler

public class UmsatzanzeigeHandler {

private Konto konto; // Konto des SelectOneMenu

public List getTransaktionen () {

if (konto != null) {

Page 24: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

44 3 Der Anwendungsprototyp

new DAO(). saveOrUpdate(konto ); // an Session binden

return new ArrayList(konto.getTransaktionen ());

}

return null;

}

public String aktualisieren () {

return "success";

}

...

Die Methode getTransaktionen(), die in der JSF-Seite als Datenquelle ver-wendet wird, gibt die Liste aller Transaktionslog-Eintrage des ausgewahltenKontos zuruck. Zunachst wird die Variable konto wieder mit der aktuellenHibernate-Session verbunden, da das konto-Objekt zum Zeitpunkt des Me-thodenaufrufs mit keiner Session verbunden ist. Eine ausfuhrliche Darstel-lung und Begrundung des Vorgehens erfolgt in Abschnitt 6.4. Im Augenblickkonzentrieren wir uns auf die Fertigstellung unseres Prototyps. Die MethodegetTransaktionen() der Klasse Konto gibt ein java.util.Set zuruck, dieMethode verlangt aber einen Ruckgabewert vom Typ List. Dies lasst sich ameinfachsten durch einen Wrapper der Klasse ArrayList realisieren.Die als Action-Methode der Schaltflache verwendete Methode aktualisie-ren() besteht lediglich aus der Ruckgabe der Konstanten "success". WelcheFunktion wird durch diese Methode erfullt? Wahlt der Benutzer in der Drop-down-Liste ein Konto aus und betatigt die Schaltflache, so wird vor Aufrufder Methode aktualisieren() das in der Drop-down-Liste aktuell selektierteKonto der Variablen konto zugewiesen. Zur neuen Darstellung der Datenta-belle wird die Methode getTransaktionen() aufgerufen, und zwar fur dasneu ausgewahlte Konto. Damit ist die Methode aktualisieren() nur einePlacebo-Methode ohne eigentliche Aufgabe.Die explizite Betatigung der Schaltflache nach der Auswahl eines Kontos istnicht sehr benutzerfreundlich und im Prinzip unnotig. Wir werden dieses Man-ko in Kapitel 6 beseitigen.In diesem Kapitel haben wir den Prototypen unseres Online-Bankings erstellt.Die typische Struktur einer JSF-basierten Anwendung wurde vorgestellt, undwir haben einige Details einer solchen Anwendung auch realisiert. Viele Fragenbleiben allerdings auch offen. Im folgenden Kapitel wird die Struktur undFunktionsweise einer JSF-Implementierung ausfuhrlich dargestellt, um dieseFragen zu beantworten.

Page 25: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer

3.4 Realisierung 45

Aufgabe 3.1Der JSF-EL-Ausdruck

"#{umsatzanzeigeHandler.aktualisieren}"

gibt die Konstante "success" zuruck, die allerdings in keiner Navigationsregelverwendet wird. Die Konstante selbst ist ebenfalls ein Ausdruck und kann auchdirekt verwendet werden. Andern Sie die JSF-Seite so ab, dass als Wert desaction-Attributs der Schaltflache die String-Konstante steht, und uberzeugenSie sich von der korrekten Funktion.

Page 26: Der Anwendungsprototyp - 1.auflage.jsfpraxis.de fileJSF-Anf¨anger zu komplex zu werden. Nach einer ausf uhrlichen Darstellung¨ Nach einer ausf uhrlichen Darstellung¨ von JavaServer