5. JavaServer Faces (JSF) -...

131
Prof. Dr. Stephan Kleuker 246 Komponentenbasierte Software- Entwicklung 5. JavaServer Faces (JSF) 5.1 Grundlagen 5.2 Einführendes nulltes Beispiel 5.3 Validierung 5.4 JSF mit JPA und JNDI 5.5 Kompakt: EJB-SessionBeans und CDI 5.6 Funktionale Erweiterung 5.7 Sicherheit 5.8 Weitere JSF-Möglichkeiten 5.9 JSF-Lebenszyklus 5.10 Templates und Komponenten 5.11 Nutzung von Ajax 5.12 Testen von Web-Applikationen - Selenium 5.13 JSF-Erweiterungen

Transcript of 5. JavaServer Faces (JSF) -...

Prof. Dr. Stephan Kleuker

246Komponentenbasierte Software-Entwicklung

5. JavaServer Faces (JSF)

5.1 Grundlagen

5.2 Einführendes nulltes Beispiel

5.3 Validierung

5.4 JSF mit JPA und JNDI

5.5 Kompakt: EJB-SessionBeans und CDI

5.6 Funktionale Erweiterung

5.7 Sicherheit

5.8 Weitere JSF-Möglichkeiten

5.9 JSF-Lebenszyklus

5.10 Templates und Komponenten

5.11 Nutzung von Ajax

5.12 Testen von Web-Applikationen - Selenium

5.13 JSF-Erweiterungen

Prof. Dr. Stephan Kleuker

247Komponentenbasierte Software-Entwicklung

Literatur

• E.Burns, C. Schalk, JavaServer Faces 2.0: The CompleteReference, Mc Graw Hill, New York, 2010

• M. Marinschek, M. Kurz, G. Müllan, JavaServer Faces 2.0, dpunkt, Heidelberg, 2010 (im Wesentlichen auch: http://tutorials.irian.at/jsf/semistatic/introduction.html)

• D. Geary, C. Horstmann, Core JavaServer Faces, 3. Auflage, Prentice Hall, USA, 2010

• K. Ka Iok Tong, Beginning JSF 2 APIs and JBoss Seam, Apress, Berkeley, USA, 2009

• Standard: Sun, JSR 314: JavaServer Faces 2.1, http://www.jcp.org/en/jsr/detail?id=314

• Sun, JEE6 Tutorial, http://download.oracle.com/javaee/6/tutorial/doc/

• Bücher fixieren teilweise auf Eclipse und JBoss; nicht notwendig, funktioniert fast alles mit Netbeans und Glassfish / Apache

Prof. Dr. Stephan Kleuker

248Komponentenbasierte Software-Entwicklung

5.1 Grundlagen

verschiedene Ziele von JSF-Applikationen

• Software, die Web als zusätzlichen Nutzen hat (z. B. Web-Präsenz, Kataloge, Bestellmöglichkeiten)

• verteilte Softwaresysteme, die Netz als Komponentenverbindung nutzen (z. B. B2B)

• Arbeitsplatzsoftware, die auch das Web nutzt (nahtlose Integration, Web ist „unsichtbar“)

• letztes Ziel gewinnt immer mehr Bedeutung für andere Ziele

• Aber: Nicht immer ist Web-fähige Software gewünscht!

Prof. Dr. Stephan Kleuker

249Komponentenbasierte Software-Entwicklung

Technische Herausforderungen (1/2)

auf welchem Rechner läuft welche Software

• zentraler Server oder peer-to-peer

• Client-Server, wer ist thin, wer ist fat

Browser-fähig oder standalone

• welcher Browser, welche Sicherheitseinstellungen, welche Plugins, welches HTML

• Wie bekommt Kunde Software zum Laufen, wie funktionieren Updates

• darf man, muss man offline arbeiten können

• Usability

Prof. Dr. Stephan Kleuker

250Komponentenbasierte Software-Entwicklung

Technische Herausforderungen (2/2)

Sicherheit

• wie Daten sicher verschicken, wem gehört Internet, wer muss zuhören dürfen

Performance und Stabilität

• schnelle Antworten auch bei Last

• saubere, reproduzierbare Transaktionen

• was passiert bei Netzausfall

Prof. Dr. Stephan Kleuker

251Komponentenbasierte Software-Entwicklung

Typische Entwicklungsplattformen (Ausschnitt)

.Net / Microsoft• ASP.Net (Active Server Pages, gute Abstraktion, zunächst zu

wenig Web-Server (IIS))• Silverlight (Browser-PlugIn) für RIA, mittlerweile auch lokal• Oberflächen basierend auf WPF (Windows Presentation

Forum, vektorbasiert, anfänglich zu langsam)Java• Servlets, JSP, JSF [später genauer], angegeben mit

steigenden Abstraktionsgrad sehr weit verbreitet• verschiedene neue Frameworks (z. B. Apache Wicket)• GWT (Google Widget Toolset), SW einmal in Java schreiben,

dann individuell für Browser in Javascript übersetzen• JavaFX , eigene Sprache nutzt im Browser JREMeinung: Silverlight und JavaFX gegenüber HTML5 und aktuell noch Flash immer im Nachteil

Prof. Dr. Stephan Kleuker

252Komponentenbasierte Software-Entwicklung

Konzept eines Seitenaufrufs

• HTML (Hypertext Markup Language)

– Auszeichnungssprache mit festgelegten tags zum Aufbau der Ausgabe

• Ebene 3/4 typisch TCP/IP, Session Ebene 5: HHTP, Darstellungsebene 6: HTML, Programmebene 7: JVM

ClientClientClientClient ApplicationApplicationApplicationApplication ServerServerServerServer

HTTPHTTPHTTPHTTP----RequestRequestRequestRequest

HTTPHTTPHTTPHTTP----ResponseResponseResponseResponsemitmitmitmitHTMLHTMLHTMLHTML----Datei im Body Datei im Body Datei im Body Datei im Body

Web

Web

Web

Web -- --

Container

Container

Container

Container

EJB

EJB

EJB

EJB -- --

Container

Container

Container

Container

Prof. Dr. Stephan Kleuker

253Komponentenbasierte Software-Entwicklung

HTTP-Ablauf

• Client: Request

– get, post, head, put, ... URL HTTP1.x

– Header Info: Accept, Cookie, ...

– Body: Post-Parameter

• Server: Response

– Statusmeldung: HTTP1.x 200 OK, oder 404 Error

– Header Info: Content-type, set-cookie, ...

– Body: Dokument

• Verbindungsabbau

• Protokoll ist zustandslos/gedächtnislos; Client wird bei erneutem Request ohne Trick nicht als Bekannter erkannt

Prof. Dr. Stephan Kleuker

254Komponentenbasierte Software-Entwicklung

Web-Server mit Container nutzen

• Servlet: Wortkreation aus den Begriffen „Server“ und „Applet“, (serverseitiges Applet)

• Web-Server leitet HTTP-Request an Servlet weiter

• Servlet kann Antwort (HTML-Code) berechnen

• Servlet kann Anfrage-Informationen und Serverumgebung nutzen

• Servlet kann mit anderen Servlets kommunizieren

Container

Prof. Dr. Stephan Kleuker

255Komponentenbasierte Software-Entwicklung

Motivation für JSF

• Die Widerverwendbarkeit von Servlets ist gering

• Innerhalb jeder JSP bzw. jedes Servlets müssen ähnliche Schritte ausgeführt werden

• Nur ein Teil der Applikationslogik kann in Tag-Bibliotheken gekapselt werden

• Workflow ist in der Applikationslogik versteckt, dadurch schwer nachvollzierbar

• ab JSF 2.0 sehr flexible Gestaltungsmöglichkeiten, u. a. AJAX-Einbettung

• Hinweis: wir betrachten nur Grundkonzepte (-> mehr evtl. Semesteraufgabe)

Prof. Dr. Stephan Kleuker

256Komponentenbasierte Software-Entwicklung

Web-Server mit JSF- (und EJB-) Unterstützung

• Beispiele:

– Apache Tomcat

– BEA WebLogic Server

– IBM WebSphere (Apache Geronimo)

– JBoss

– Oracle WebLogic

– Sun Glassfish Enterprise Server (Glassfish)

Prof. Dr. Stephan Kleuker

257Komponentenbasierte Software-Entwicklung

Konzeptübersicht

Input-Komponente beschrieben in

XHTML...

Web-Seite in XHTML

Output-Komponente beschrieben in

XHTML...

Web-Seite in XHTML

Modell

Java-Programmim Container

im Server

eventeventeventevent

leitet aufleitet aufleitet aufleitet aufFolgeseiteFolgeseiteFolgeseiteFolgeseite

liestliestliestliest

Prof. Dr. Stephan Kleuker

258Komponentenbasierte Software-Entwicklung

XHTML

• Idee: HTML nicht XML-konform und zu viele Freiheiten

• XHTML in fast allen Elementen wie HTML

• XHTML basierend auf XML-Schema leichter zu verarbeiten

• Unterschiede zu HTML (Ausschnitt)

– Tags und Attribute müssen klein geschrieben werden

– Attributwerte immer in Anführungsstrichen boarderboarderboarderboarder="7"="7"="7"="7"

– korrekte XML-Syntax: <<<<brbrbrbr/>/>/>/> nicht <<<<brbrbrbr>>>>

– generell saubere Terminierung <<<<inputinputinputinput ... />... />... />... />

• XHTML2 wegen HTML5 zurückgestellt (verschwimmt damit) http://www.w3.org/2009/06/xhtml-faq.html

• Standard: http://www.w3.org/TR/xhtml1/

• Literatur: U. Ogbuji, XHTML step-by-step, http://www.ibm.com/developerworks/edu/x-dw-x-xhtml-i.html

Prof. Dr. Stephan Kleuker

259Komponentenbasierte Software-Entwicklung

Web-GUI-Komponenten

• JSF bietet alle klassischen GUI-Komponenten zur Darstellung und Bearbeitung an

• Grundidee: Komponenten schicken bei Veränderungen Events

• Nutzung von MVC2

• Komponenten als XHTML eingebettet

<h:inputText id="imname" value="#{modul.name}“ <h:inputText id="imname" value="#{modul.name}“ <h:inputText id="imname" value="#{modul.name}“ <h:inputText id="imname" value="#{modul.name}“ required="true"/>required="true"/>required="true"/>required="true"/>

<h:outputText id=<h:outputText id=<h:outputText id=<h:outputText id=""""omname" value="#{modul.name}"/>omname" value="#{modul.name}"/>omname" value="#{modul.name}"/>omname" value="#{modul.name}"/>

• Kontakt zum Java-Programm über Methodenaufrufe (lesend und aufrufend, z. B. modul.setName(...), modul.getName()modul.setName(...), modul.getName()modul.setName(...), modul.getName()modul.setName(...), modul.getName()

• große Komponenten können aus kleineren komponiert werden

Prof. Dr. Stephan Kleuker

260Komponentenbasierte Software-Entwicklung

5.2 Nulltes JSF-Beispiel (1/11)

• Aufgabe: Modul (Name + Nummer) eingeben und auf zweiter Seite wieder ausgeben

• Beispiel zeigt:

– Konzept der XHTML-Nutzung

– erste JSF-Befehle

– Seitenmanövrierung durch JSF

• 0. Beispiel zeigt nicht:

– ordentliche Softwarearchitektur (Controller und Model trennen)

– Validierungsmöglichkeiten für Eingaben

– Layoutgestaltung

– viele coole Dinge

Prof. Dr. Stephan Kleuker

261Komponentenbasierte Software-Entwicklung

<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 TransitionalTransitionalTransitionalTransitional//EN" //EN" //EN" //EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"

xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">"><<<<h:headh:headh:headh:head>>>>

<title>Moduleingabe</title><title>Moduleingabe</title><title>Moduleingabe</title><title>Moduleingabe</title></</</</h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{modul.name}" ="#{modul.name}" ="#{modul.name}" ="#{modul.name}"

requiredrequiredrequiredrequired="="="="truetruetruetrue"/><"/><"/><"/><brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="#{modul.nr}" ="#{modul.nr}" ="#{modul.nr}" ="#{modul.nr}"

requiredrequiredrequiredrequired="="="="truetruetruetrue"/><"/><"/><"/><brbrbrbr/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Abschicken" ="Abschicken" ="Abschicken" ="Abschicken"

actionactionactionaction="#{="#{="#{="#{modul.uebernehmenmodul.uebernehmenmodul.uebernehmenmodul.uebernehmen}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Nulltes JSF-Beispiel (2/11) - Start index.xhtml

Prof. Dr. Stephan Kleuker

262Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (3/11) - Analyse der Startseite

• Einbinden der JSF-Bibliotheken<<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"

xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml""""xmlns:fxmlns:fxmlns:fxmlns:f ="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////corecorecorecore" >" >" >" >

• Nutzung von Standard XHTML (vereinfacht, da so als Standardnamensraum gesetzt)

• enge Verwandtschaft HTML zu XHTML (<h:form>)

• für valuevaluevaluevalue="#{modul.name}" ="#{modul.name}" ="#{modul.name}" ="#{modul.name}" offene Fragen:

– was ist modul? ( -> Managed Bean)

– warum #? (Trennung von ausführbaren Elementen)

– was passiert bei modul.name? (set/get abhängig von in/out)

• Ausblick: actionactionactionaction="#{="#{="#{="#{modul.uebernehmenmodul.uebernehmenmodul.uebernehmenmodul.uebernehmen}"}"}"}", echtes Event-Handling (Methodenaufruf)

Prof. Dr. Stephan Kleuker

263Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (4/11) - Ausgabe ausgabe.xhtml<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 TransitionalTransitionalTransitionalTransitional//EN" //EN" //EN" //EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"

xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">"><<<<h:headh:headh:headh:head>>>>

<title>Modulausgabe</title><title>Modulausgabe</title><title>Modulausgabe</title><title>Modulausgabe</title></</</</h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulname: "/>="Modulname: "/>="Modulname: "/>="Modulname: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{modul.name}"/> <="#{modul.name}"/> <="#{modul.name}"/> <="#{modul.name}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulnummer: "/>="Modulnummer: "/>="Modulnummer: "/>="Modulnummer: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="#{modul.nr}"/><="#{modul.nr}"/><="#{modul.nr}"/><="#{modul.nr}"/><brbrbrbr/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Zur Eingabe" ="Zur Eingabe" ="Zur Eingabe" ="Zur Eingabe"

actionactionactionaction="#{="#{="#{="#{modul.eingebenmodul.eingebenmodul.eingebenmodul.eingeben}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Prof. Dr. Stephan Kleuker

264Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (5/11) - Managed Bean [1/3]

packagepackagepackagepackage entitiesentitiesentitiesentities;;;;

importimportimportimport java.io.Serializablejava.io.Serializablejava.io.Serializablejava.io.Serializable;;;;importimportimportimport javax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBean;;;;importimportimportimport javax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScoped;;;;

@@@@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename="="="="modulmodulmodulmodul")")")")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;private private private private intintintint nrnrnrnr;;;;private String private String private String private String namenamenamename;;;;

publicpublicpublicpublic Modul(){}Modul(){}Modul(){}Modul(){}

publicpublicpublicpublic Modul(Modul(Modul(Modul(intintintint nrnrnrnr, String , String , String , String namenamenamename) {) {) {) {this.nr = this.nr = this.nr = this.nr = nrnrnrnr;;;;this.name = this.name = this.name = this.name = namenamenamename;;;;

}}}}

Prof. Dr. Stephan Kleuker

265Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (6/11) - Managed Bean [2/3]

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen(){(){(){(){returnreturnreturnreturn "./"./"./"./ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml";";";";

}}}}

publicpublicpublicpublic String eingeben(){String eingeben(){String eingeben(){String eingeben(){returnreturnreturnreturn "./"./"./"./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml";";";";

}}}}

publicpublicpublicpublic String String String String getNamegetNamegetNamegetName() {() {() {() {returnreturnreturnreturn namenamenamename;;;;

}}}}

publicpublicpublicpublic voidvoidvoidvoid setNamesetNamesetNamesetName(String (String (String (String namenamenamename) {) {) {) {this.name = this.name = this.name = this.name = namenamenamename;;;;

}}}}

publicpublicpublicpublic intintintint getNrgetNrgetNrgetNr() {() {() {() {returnreturnreturnreturn nrnrnrnr;;;;

}}}}

publicpublicpublicpublic voidvoidvoidvoid setNrsetNrsetNrsetNr((((intintintint nrnrnrnr) {) {) {) {this.nr = this.nr = this.nr = this.nr = nrnrnrnr;;;;

}}}}

//Manövrieren//Manövrieren//Manövrieren//Manövrieren

Prof. Dr. Stephan Kleuker

266Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (7/11) - Managed Bean [3/3]

@@@@OverrideOverrideOverrideOverridepublicpublicpublicpublic booleanbooleanbooleanboolean equalsequalsequalsequals((((ObjectObjectObjectObject objectobjectobjectobject) {) {) {) {ifififif ((((objectobjectobjectobject==null || !(==null || !(==null || !(==null || !(objectobjectobjectobject instanceofinstanceofinstanceofinstanceof Modul)) Modul)) Modul)) Modul)) returnreturnreturnreturn falsefalsefalsefalse;;;;

Modul Modul Modul Modul otherotherotherother = (Modul) = (Modul) = (Modul) = (Modul) objectobjectobjectobject;;;;ifififif (this.nr != other.nr || !(this.nr != other.nr || !(this.nr != other.nr || !(this.nr != other.nr || !this.name.equalsthis.name.equalsthis.name.equalsthis.name.equals(other.name)) (other.name)) (other.name)) (other.name)) returnreturnreturnreturn falsefalsefalsefalse;;;;

returnreturnreturnreturn truetruetruetrue;;;;}}}}

@@@@OverrideOverrideOverrideOverride // generieren lassen// generieren lassen// generieren lassen// generieren lassenpublicpublicpublicpublic intintintint hashCodehashCodehashCodehashCode() {() {() {() {

intintintint hashhashhashhash = 5;= 5;= 5;= 5;hashhashhashhash = 47 * = 47 * = 47 * = 47 * hashhashhashhash + this.nr;+ this.nr;+ this.nr;+ this.nr;hashhashhashhash = 47 * = 47 * = 47 * = 47 * hashhashhashhash

+ (this.name != null ? + (this.name != null ? + (this.name != null ? + (this.name != null ? this.name.hashCodethis.name.hashCodethis.name.hashCodethis.name.hashCode() : 0);() : 0);() : 0);() : 0);returnreturnreturnreturn hashhashhashhash;;;;

}}}}

@@@@OverrideOverrideOverrideOverridepublicpublicpublicpublic String String String String toStringtoStringtoStringtoString() {() {() {() {returnreturnreturnreturn namenamenamename+"("++"("++"("++"("+nrnrnrnr+")";}+")";}+")";}+")";}

}}}}

Prof. Dr. Stephan Kleuker

267Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (8/11) - web.xml [1/2]• Konfigurationsdatei für Servlets (hier benötigt)• sun-web.xml ist Glassfish-spezifische Konfiguratonsdatei<?<?<?<?xmlxmlxmlxml versionversionversionversion="1.0" ="1.0" ="1.0" ="1.0" encodingencodingencodingencoding="UTF="UTF="UTF="UTF----8"?>8"?>8"?>8"?><web<web<web<web----appappappapp versionversionversionversion="3.0" ="3.0" ="3.0" ="3.0"

xmlnsxmlnsxmlnsxmlns="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/xmlxmlxmlxml////nsnsnsns////javaeejavaeejavaeejavaee" " " " xmlns:xsixmlns:xsixmlns:xsixmlns:xsi="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocationxsi:schemaLocationxsi:schemaLocationxsi:schemaLocation="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/xmlxmlxmlxml////nsnsnsns////javaeejavaeejavaeejavaeehttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/web----app_3_0.xsd">app_3_0.xsd">app_3_0.xsd">app_3_0.xsd">

<<<<contextcontextcontextcontext----paramparamparamparam>>>><<<<paramparamparamparam----name>name>name>name>javax.faces.PROJECT_STAGEjavax.faces.PROJECT_STAGEjavax.faces.PROJECT_STAGEjavax.faces.PROJECT_STAGE</</</</paramparamparamparam----name>name>name>name><<<<paramparamparamparam----valuevaluevaluevalue>Development</>Development</>Development</>Development</paramparamparamparam----valuevaluevaluevalue>>>>

</</</</contextcontextcontextcontext----paramparamparamparam>>>><<<<servletservletservletservlet>>>>

<<<<servletservletservletservlet----name>name>name>name>FacesFacesFacesFaces Servlet</Servlet</Servlet</Servlet</servletservletservletservlet----name>name>name>name><<<<servletservletservletservlet----classclassclassclass>>>>javax.faces.webapp.FacesServletjavax.faces.webapp.FacesServletjavax.faces.webapp.FacesServletjavax.faces.webapp.FacesServlet</</</</servletservletservletservlet----classclassclassclass>>>><<<<loadloadloadload----onononon----startup>1</startup>1</startup>1</startup>1</loadloadloadload----onononon----startup>startup>startup>startup>

</</</</servletservletservletservlet>>>>

Prof. Dr. Stephan Kleuker

268Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (9/11) - web.xml [2/2]

<<<<servletservletservletservlet----mappingmappingmappingmapping>>>><<<<servletservletservletservlet----name>name>name>name>FacesFacesFacesFaces Servlet</Servlet</Servlet</Servlet</servletservletservletservlet----name>name>name>name><<<<urlurlurlurl----pattern>/pattern>/pattern>/pattern>/facesfacesfacesfaces/*<//*<//*<//*</urlurlurlurl----pattern>pattern>pattern>pattern>

</</</</servletservletservletservlet----mappingmappingmappingmapping>>>><<<<sessionsessionsessionsession----configconfigconfigconfig>>>><<<<sessionsessionsessionsession----timeout>timeout>timeout>timeout>30303030

</</</</sessionsessionsessionsession----timeout>timeout>timeout>timeout></</</</sessionsessionsessionsession----configconfigconfigconfig>>>><<<<welcomewelcomewelcomewelcome----filefilefilefile----list>list>list>list><<<<welcomewelcomewelcomewelcome----file>file>file>file>facesfacesfacesfaces////index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml</</</</welcomewelcomewelcomewelcome----file>file>file>file>

</</</</welcomewelcomewelcomewelcome----filefilefilefile----list>list>list>list></web</web</web</web----appappappapp>>>>

in sun-web.xml steht u. a.<<<<contextcontextcontextcontext----rootrootrootroot>/JSFSpielerei2</>/JSFSpielerei2</>/JSFSpielerei2</>/JSFSpielerei2</contextcontextcontextcontext----rootrootrootroot>>>>

Prof. Dr. Stephan Kleuker

269Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (10/11) - Projektstruktur

Prof. Dr. Stephan Kleuker

270Komponentenbasierte Software-Entwicklung

Nulltes JSF-Beispiel (11/11) - Ergebnis

Prof. Dr. Stephan Kleuker

271

Einschub: IE 9 - Problem

• Programm läuft problemlos in Firefox und Chrome

• in IE 8 gab es auch keine Probleme

• in IE 9, erfolgt nach Drücken des Knopfes folgende Ausgabe

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

272

Einschub: IE 9 - Lösung

• Session-Informationen können statt im Server auch im Client gehalten werden

• entlastet Server, ist aber für Nutzer langsamer

• Ergänzung in web.xml:

<<<<contextcontextcontextcontext----paramparamparamparam> > > > <<<<paramparamparamparam----name>name>name>name>javax.faces.STATE_SAVING_METHODjavax.faces.STATE_SAVING_METHODjavax.faces.STATE_SAVING_METHODjavax.faces.STATE_SAVING_METHOD</</</</paramparamparamparam----name> name> name> name> <<<<paramparamparamparam----valuevaluevaluevalue>>>>clientclientclientclient</</</</paramparamparamparam----valuevaluevaluevalue> > > >

</</</</contextcontextcontextcontext----paramparamparamparam>>>>

• Anmerkung: fehlt systematische Fehleranalyse: NetBeans 7.2, Glassfish 3.1.2, MS IE 9, MS IE 9 Nutzereinstellungen, Win 7 x64, …

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

273

Einschub: korrekte Pfadangabe

• Browser zeugt immer vergangene Seite

• wenn nicht gewünscht, dann Manövrierungsstring ändern

• ist etwas langsamer (später genauer)

• Scope auf @SessionScoped setzen

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen(){(){(){(){returnreturnreturnreturn "./"./"./"./ausgabe.xhtml?facesausgabe.xhtml?facesausgabe.xhtml?facesausgabe.xhtml?faces----redirectredirectredirectredirect====truetruetruetrue";";";";

}}}}

publicpublicpublicpublic String eingeben(){String eingeben(){String eingeben(){String eingeben(){returnreturnreturnreturn "./"./"./"./index.xhtml?facesindex.xhtml?facesindex.xhtml?facesindex.xhtml?faces----redirectredirectredirectredirect====truetruetruetrue";";";";

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

274Komponentenbasierte Software-Entwicklung

Basisprinzip der Applikationssteuerung

• Im Controller: Aufruf einer Methode ohne Parameter vom Rückgabetyp String<h:commandButton value="Abschicken" <h:commandButton value="Abschicken" <h:commandButton value="Abschicken" <h:commandButton value="Abschicken"

action="#{modul.uebernehmen}"/>action="#{modul.uebernehmen}"/>action="#{modul.uebernehmen}"/>action="#{modul.uebernehmen}"/>

• Im Modell:public String uebernehmen(){public String uebernehmen(){public String uebernehmen(){public String uebernehmen(){

return "./ausgabe.xhtml";return "./ausgabe.xhtml";return "./ausgabe.xhtml";return "./ausgabe.xhtml";}}}}

• Methode kann natürlich abhängig von Variablen unterschiedliche Seiten liefern

• Beachten: Navigation kann in den Tiefen des Codes verschwinden ( -> Konstanten nutzen, Architektur)

• Hinweis: wir werden noch Varianten kennenlernen

Prof. Dr. Stephan Kleuker

275Komponentenbasierte Software-Entwicklung

Lebensdauer von Informationen (scope)

• Scope NoneNoneNoneNone passt sich Aufrufer-Scope an (default kein Leben)

• Anmerkung: Obwohl es verlockend ist, viele Informationen in Session oder Application zu legen, ist dies wg Performance verboten (wird gespeichert, evtl. passiviert, hat wilde Referenzen, Zugriff muss ggfls. synchronisiert werden)

ViewViewViewView

SessionSessionSessionSession

ApplicationApplicationApplicationApplication

nur für einenAufruf (auch fürWeiterleitung)

für eineNutzer-Sitzung

solangeaktuellesDeploymentläuft

Zeit

RequestRequestRequestRequest

solangeNutzer aufApplikations-seiten bleibt

Prof. Dr. Stephan Kleuker

276Komponentenbasierte Software-Entwicklung

Scope-Beispiel (1/5) - Bean-Klasse

//@//@//@//@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename = "= "= "= "modulmodulmodulmodul")")")")//@//@//@//@RequestScopedRequestScopedRequestScopedRequestScoped Modul als einfache Modul als einfache Modul als einfache Modul als einfache Klasse (wichtig!)Klasse (wichtig!)Klasse (wichtig!)Klasse (wichtig!)publicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable { ...// wie vorher{ ...// wie vorher{ ...// wie vorher{ ...// wie vorher

@@@@ManagedBeanManagedBeanManagedBeanManagedBean(name = "(name = "(name = "(name = "modulnmodulnmodulnmoduln")")")")@@@@NoneScopedNoneScopedNoneScopedNoneScopedpublic class public class public class public class ModulNoneModulNoneModulNoneModulNone extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBeanManagedBeanManagedBeanManagedBean(name = "(name = "(name = "(name = "modulrmodulrmodulrmodulr")")")")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublic class public class public class public class ModulRequestModulRequestModulRequestModulRequest extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBeanManagedBeanManagedBeanManagedBean(name = "(name = "(name = "(name = "modulsmodulsmodulsmoduls")")")")@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublic class public class public class public class ModulSessionModulSessionModulSessionModulSession extends extends extends extends ModulModulModulModul{}{}{}{}

@@@@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename = "= "= "= "modulamodulamodulamodula")")")")@@@@ApplicationScopedApplicationScopedApplicationScopedApplicationScopedpublicpublicpublicpublic classclassclassclass ModulApplicationModulApplicationModulApplicationModulApplication extendsextendsextendsextends Modul{}Modul{}Modul{}Modul{}

Prof. Dr. Stephan Kleuker

277Komponentenbasierte Software-Entwicklung

Scope-Beispiel (2/5) - Ausschnitt index.xhtml<<<<h:formh:formh:formh:form>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid columnscolumnscolumnscolumns="3" >="3" >="3" >="3" ><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamenmnamenmnamenmnamen" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamenmnamenmnamenmnamen" " " " valuevaluevaluevalue="#{moduln.name}"/>="#{moduln.name}"/>="#{moduln.name}"/>="#{moduln.name}"/><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamenmnamenmnamenmnamen" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnrnmnrnmnrnmnrn" " " " valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrnmnrnmnrnmnrn" " " " valuevaluevaluevalue="#{moduln.nr}"/> ="#{moduln.nr}"/> ="#{moduln.nr}"/> ="#{moduln.nr}"/> <<<<h:messageh:messageh:messageh:message forforforfor="="="="mnrnmnrnmnrnmnrn" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamermnamermnamermnamer" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamermnamermnamermnamer" " " " valuevaluevaluevalue="#{modulr.name}"/>="#{modulr.name}"/>="#{modulr.name}"/>="#{modulr.name}"/><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamermnamermnamermnamer" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnrrmnrrmnrrmnrr" " " " valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrrmnrrmnrrmnrr" " " " valuevaluevaluevalue="#{modulr.nr}"/> ="#{modulr.nr}"/> ="#{modulr.nr}"/> ="#{modulr.nr}"/> <<<<h:messageh:messageh:messageh:message forforforfor="="="="mnrrmnrrmnrrmnrr" />" />" />" /><!<!<!<!-------- auch auch auch auch modulsmodulsmodulsmoduls und und und und modulamodulamodulamodula -------->>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Abschicken"="Abschicken"="Abschicken"="Abschicken"

actionactionactionaction="#{="#{="#{="#{modulr.uebernehmenmodulr.uebernehmenmodulr.uebernehmenmodulr.uebernehmen}"/>}"/>}"/>}"/></</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>>

Prof. Dr. Stephan Kleuker

278Komponentenbasierte Software-Entwicklung

Scope-Beispiel (3/5) - Ausschnitt ausgabe.xhtml

<<<<h:formh:formh:formh:form>>>><<<<h:messagesh:messagesh:messagesh:messages globalOnlyglobalOnlyglobalOnlyglobalOnly="="="="truetruetruetrue"/>"/>"/>"/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulname n: "/>="Modulname n: "/>="Modulname n: "/>="Modulname n: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnamenmnamenmnamenmnamen" " " " valuevaluevaluevalue="#{moduln.name}"/> <="#{moduln.name}"/> <="#{moduln.name}"/> <="#{moduln.name}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulnummer n: "/>="Modulnummer n: "/>="Modulnummer n: "/>="Modulnummer n: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnrnmnrnmnrnmnrn" " " " valuevaluevaluevalue="#{moduln.nr}"/><="#{moduln.nr}"/><="#{moduln.nr}"/><="#{moduln.nr}"/><brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulname r: "/>="Modulname r: "/>="Modulname r: "/>="Modulname r: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnamermnamermnamermnamer" " " " valuevaluevaluevalue="#{modulr.name}"/> <="#{modulr.name}"/> <="#{modulr.name}"/> <="#{modulr.name}"/> <brbrbrbr/>/>/>/><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulnummer r: "/>="Modulnummer r: "/>="Modulnummer r: "/>="Modulnummer r: "/><<<<h:outputTexth:outputTexth:outputTexth:outputText idididid="="="="mnrrmnrrmnrrmnrr" " " " valuevaluevaluevalue="#{modulr.nr}"/><="#{modulr.nr}"/><="#{modulr.nr}"/><="#{modulr.nr}"/><brbrbrbr/>/>/>/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Zur Eingabe" ="Zur Eingabe" ="Zur Eingabe" ="Zur Eingabe"

actionactionactionaction="#{="#{="#{="#{modulr.eingebenmodulr.eingebenmodulr.eingebenmodulr.eingeben}"/><}"/><}"/><}"/><brbrbrbr/>/>/>/><!<!<!<!-------- auch auch auch auch modulsmodulsmodulsmoduls und und und und modulamodulamodulamodula -------->>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Ausgabe wiederholen" ="Ausgabe wiederholen" ="Ausgabe wiederholen" ="Ausgabe wiederholen"

actionactionactionaction="#{="#{="#{="#{modulr.uebernehmenmodulr.uebernehmenmodulr.uebernehmenmodulr.uebernehmen}"/>}"/>}"/>}"/></</</</h:formh:formh:formh:form>>>>

Prof. Dr. Stephan Kleuker

279Komponentenbasierte Software-Entwicklung

Scope-Beispiel (4/5) - Ein Nutzer, zwei Klicks

Prof. Dr. Stephan Kleuker

280Komponentenbasierte Software-Entwicklung

Scope-Beispiel (5/5) - Zwei NutzerN

utz

er

1N

utz

er

2

Zeit

Prof. Dr. Stephan Kleuker

281Komponentenbasierte Software-Entwicklung

Manövrieren vor JSF 2.0

• Grundidee: Automat mit Seiten als Knoten (Zustände), Übergang findet durch String-Konstanten statt

• String-Konstanten sind Ergebnisse von (Action-) Methoden (oder stehen direkt in action="EINGEBEN"action="EINGEBEN"action="EINGEBEN"action="EINGEBEN")

index.xhtml

ausgabe.xhtml

Prof. Dr. Stephan Kleuker

282Komponentenbasierte Software-Entwicklung

Manövrieren vor JSF 2.0 - faces-config.xml 1/2<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8'?>8'?>8'?>8'?><<<<facesfacesfacesfaces----configconfigconfigconfig versionversionversionversion="1.2" ="1.2" ="1.2" ="1.2"

xmlnsxmlnsxmlnsxmlns="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/xmlxmlxmlxml////nsnsnsns////javaeejavaeejavaeejavaee" " " " xmlns:xsixmlns:xsixmlns:xsixmlns:xsi="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocationxsi:schemaLocationxsi:schemaLocationxsi:schemaLocation="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/xmlxmlxmlxml////nsnsnsns////javaeejavaeejavaeejavaeehttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/webhttp://java.sun.com/xml/ns/javaee/web----facesconfig_1_2.xsd">facesconfig_1_2.xsd">facesconfig_1_2.xsd">facesconfig_1_2.xsd">

<<<<navigationnavigationnavigationnavigation----rulerulerulerule>>>><<<<fromfromfromfrom----viewviewviewview----idididid>/>/>/>/index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml</</</</fromfromfromfrom----viewviewviewview----idididid>>>><<<<navigationnavigationnavigationnavigation----casecasecasecase>>>><<<<fromfromfromfrom----outcomeoutcomeoutcomeoutcome>ANZEIGEN</>ANZEIGEN</>ANZEIGEN</>ANZEIGEN</fromfromfromfrom----outcomeoutcomeoutcomeoutcome>>>><<<<totototo----viewviewviewview----idididid>/>/>/>/ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml</</</</totototo----viewviewviewview----idididid>>>>

</</</</navigationnavigationnavigationnavigation----casecasecasecase>>>></</</</navigationnavigationnavigationnavigation----rulerulerulerule>>>><<<<navigationnavigationnavigationnavigation----rulerulerulerule>>>>

<<<<fromfromfromfrom----viewviewviewview----idididid>/>/>/>/ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml</</</</fromfromfromfrom----viewviewviewview----idididid>>>><<<<navigationnavigationnavigationnavigation----casecasecasecase>>>><<<<fromfromfromfrom----outcomeoutcomeoutcomeoutcome>EINGEBEN</>EINGEBEN</>EINGEBEN</>EINGEBEN</fromfromfromfrom----outcomeoutcomeoutcomeoutcome>>>><<<<totototo----viewviewviewview----idididid>/ >/ >/ >/ index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml </</</</totototo----viewviewviewview----idididid>>>>

</</</</navigationnavigationnavigationnavigation----casecasecasecase>>>></</</</navigationnavigationnavigationnavigation----rulerulerulerule>>>>

Prof. Dr. Stephan Kleuker

283Komponentenbasierte Software-Entwicklung

Manövrieren vor JSF 2.0 - Managed Bean

// statt durch Annotationen können Beans auch in faces// statt durch Annotationen können Beans auch in faces// statt durch Annotationen können Beans auch in faces// statt durch Annotationen können Beans auch in faces----// config.xml angelegt werden// config.xml angelegt werden// config.xml angelegt werden// config.xml angelegt werdenpublic class Modul implements Serializable {public class Modul implements Serializable {public class Modul implements Serializable {public class Modul implements Serializable {private static final long serialVersionUID = 1L;private static final long serialVersionUID = 1L;private static final long serialVersionUID = 1L;private static final long serialVersionUID = 1L;private int nr;private int nr;private int nr;private int nr;private String name;private String name;private String name;private String name;// fehlt: get// fehlt: get// fehlt: get// fehlt: get---- und setund setund setund set----Methoden für ExemplarvariablenMethoden für ExemplarvariablenMethoden für ExemplarvariablenMethoden für Exemplarvariablenpublic Modul(){}public Modul(){}public Modul(){}public Modul(){}

public String uebernehmen(){ //Actionpublic String uebernehmen(){ //Actionpublic String uebernehmen(){ //Actionpublic String uebernehmen(){ //Action----MethodeMethodeMethodeMethode// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglichreturn "ANZEIGEN";return "ANZEIGEN";return "ANZEIGEN";return "ANZEIGEN";

}}}}

public String eingeben(){public String eingeben(){public String eingeben(){public String eingeben(){// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglich// Zugriff auf Exemplarvariablen möglichreturn "EINGEBEN";return "EINGEBEN";return "EINGEBEN";return "EINGEBEN";

}}}}............

}}}}

Prof. Dr. Stephan Kleuker

284Komponentenbasierte Software-Entwicklung

Manövrieren vor JSF 2.0 - faces-config.xml 2/2<managed<managed<managed<managed----bean>bean>bean>bean><managed<managed<managed<managed----beanbeanbeanbean----name>modul</managedname>modul</managedname>modul</managedname>modul</managed----beanbeanbeanbean----name>name>name>name><managed<managed<managed<managed----beanbeanbeanbean----class>entities.Modul</managedclass>entities.Modul</managedclass>entities.Modul</managedclass>entities.Modul</managed----beanbeanbeanbean----class>class>class>class><managed<managed<managed<managed----beanbeanbeanbean----scope>request</managedscope>request</managedscope>request</managedscope>request</managed----beanbeanbeanbean----scope>scope>scope>scope>

</managed</managed</managed</managed----bean>bean>bean>bean></faces</faces</faces</faces----config>config>config>config>

Vorteil der klassischen Navigation:

• Es gibt zentrale Stelle, an der es einen Überblick über mögliche Abläufe gibt

Nachteile:

• JSF 2.0 bietet flexiblere Ablaufsteuerung

• XML ist schwer nachvollziehbar

• Konfigurationsdatei facesfacesfacesfaces----config.xmlconfig.xmlconfig.xmlconfig.xml bleibt trotzdem wichtig

Prof. Dr. Stephan Kleuker

285Komponentenbasierte Software-Entwicklung

Erinnerung: Konstanten in Programmen

• schlecht return "ANZEIGEN";return "ANZEIGEN";return "ANZEIGEN";return "ANZEIGEN";

• besser: Konstanten getrennt deklarierenpublic class Modul implements Serializable{public class Modul implements Serializable{public class Modul implements Serializable{public class Modul implements Serializable{private final static string ANZEIGEN = "ANZEIGEN";private final static string ANZEIGEN = "ANZEIGEN";private final static string ANZEIGEN = "ANZEIGEN";private final static string ANZEIGEN = "ANZEIGEN";............return ANZEIGEN;return ANZEIGEN;return ANZEIGEN;return ANZEIGEN;

• Alternativ: Klasse mit Konstantenpackage konstanten;package konstanten;package konstanten;package konstanten;public class Navigation{public class Navigation{public class Navigation{public class Navigation{public final static string ANZEIGEN = "ANZEIGEN";public final static string ANZEIGEN = "ANZEIGEN";public final static string ANZEIGEN = "ANZEIGEN";public final static string ANZEIGEN = "ANZEIGEN";............return konstanten.Navigation.ANZEIGEN;return konstanten.Navigation.ANZEIGEN;return konstanten.Navigation.ANZEIGEN;return konstanten.Navigation.ANZEIGEN;

– Entwicklungsumgebungen erlauben dann einfache Suche und Änderung (Refactoring)

Prof. Dr. Stephan Kleuker

286Komponentenbasierte Software-Entwicklung

Standardattribut rendered (1/3)

• JSF-Elemente werden typischerweise ineinander geschachtelt (typische GUI-Idee der Schächtelchen in Schächtelchen)

• viele (Schachtel-)Elemente haben Attribut rendered; Boolescher Wert, ob Element dargestellt werden soll

@ManagedBean(name="mo")@ManagedBean(name="mo")@ManagedBean(name="mo")@ManagedBean(name="mo")@SessionScoped@SessionScoped@SessionScoped@SessionScopedpublic class Mojo {public class Mojo {public class Mojo {public class Mojo {private boolean jo=true;private boolean jo=true;private boolean jo=true;private boolean jo=true;public Mojo(){}public Mojo(){}public Mojo(){}public Mojo(){}

public boolean getJo() {return jo;}public boolean getJo() {return jo;}public boolean getJo() {return jo;}public boolean getJo() {return jo;}

public void setJo(boolean jo) {this.jo = jo;}public void setJo(boolean jo) {this.jo = jo;}public void setJo(boolean jo) {this.jo = jo;}public void setJo(boolean jo) {this.jo = jo;}

public String change(){public String change(){public String change(){public String change(){jo=!jo;jo=!jo;jo=!jo;jo=!jo;return "./index.xhtml";return "./index.xhtml";return "./index.xhtml";return "./index.xhtml";

}}}}}}}}

Prof. Dr. Stephan Kleuker

287Komponentenbasierte Software-Entwicklung

<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 TransitionalTransitionalTransitionalTransitional//EN" //EN" //EN" //EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"

xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">"><<<<h:headh:headh:headh:head> <title>Klickklack</title> </> <title>Klickklack</title> </> <title>Klickklack</title> </> <title>Klickklack</title> </h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>>

<<<<h:formh:formh:formh:form idididid="f1">="f1">="f1">="f1"><<<<h:panelGridh:panelGridh:panelGridh:panelGrid idididid="p1" ="p1" ="p1" ="p1" renderedrenderedrenderedrendered="#{mo.jo}">="#{mo.jo}">="#{mo.jo}">="#{mo.jo}"><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue=„HS =„HS =„HS =„HS rocksrocksrocksrocks"/>"/>"/>"/>

</</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid idididid="p2" ="p2" ="p2" ="p2" renderedrenderedrenderedrendered="#{!mo.jo}">="#{!mo.jo}">="#{!mo.jo}">="#{!mo.jo}">

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue="OS ="OS ="OS ="OS rocksrocksrocksrocks"/>"/>"/>"/></</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton actionactionactionaction="#{="#{="#{="#{mo.changemo.changemo.changemo.change}" }" }" }" valuevaluevaluevalue="Press"/>="Press"/>="Press"/>="Press"/>

</</</</h:formh:formh:formh:form>>>></</</</h:bodyh:bodyh:bodyh:body>>>>

</</</</htmlhtmlhtmlhtml>>>>

Standardattribut rendered (2/3) - JSF-Seite

Prof. Dr. Stephan Kleuker

288Komponentenbasierte Software-Entwicklung

Standardattribut rendered (3/3)

<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8'?>8'?>8'?>8'?><<<<facesfacesfacesfaces----configconfigconfigconfig versionversionversionversion="1.2" ...>="1.2" ...>="1.2" ...>="1.2" ...><<<<managedmanagedmanagedmanaged----beanbeanbeanbean>>>>

<<<<managedmanagedmanagedmanaged----beanbeanbeanbean----name>name>name>name>momomomo</</</</managedmanagedmanagedmanaged----beanbeanbeanbean----name>name>name>name><<<<managedmanagedmanagedmanaged----beanbeanbeanbean----classclassclassclass>>>>entities.Mojoentities.Mojoentities.Mojoentities.Mojo</</</</managedmanagedmanagedmanaged----beanbeanbeanbean----classclassclassclass>>>><<<<managedmanagedmanagedmanaged----beanbeanbeanbean----scopescopescopescope>>>>sessionsessionsessionsession</</</</managedmanagedmanagedmanaged----beanbeanbeanbean----scopescopescopescope>>>>

</</</</managedmanagedmanagedmanaged----beanbeanbeanbean>>>></</</</facesfacesfacesfaces----configconfigconfigconfig>>>>

oder infaces-config.xhtml

Prof. Dr. Stephan Kleuker

289Komponentenbasierte Software-Entwicklung

Strukturierung mit panelgrid / Kommentare

• mit h:panelgridh:panelgridh:panelgridh:panelgrid können einzelne Komponenten zu einem Block zusammengefasst und einheitlich behandelt werden (ähnlich zu JPanel in Swing)

• weiterhin kann durch columnscolumnscolumnscolumns="3"="3"="3"="3" eine Spaltenanzahl

angegeben werden

• Ausgabe erfolgt in Tabellenform

• Elemente werden zeilenweise ergänzt

• echte JSF-Kommentare sehen wie folgt aus

<%<%<%<%-------- Dies liest eh keiner Dies liest eh keiner Dies liest eh keiner Dies liest eh keiner --------%>%>%>%>

Prof. Dr. Stephan Kleuker

290Komponentenbasierte Software-Entwicklung

5.3 Validierung/ Fehleingaben im nullten Beispiel (1/2)

Eingabe:

Fehler wird automatisch unter der bleibender Seite ausgegebenj_idt7 ist interner Name, mname ist „unsere“ id des

Eingabefeldes

Prof. Dr. Stephan Kleuker

291Komponentenbasierte Software-Entwicklung

Fehleingaben im nullten Beispiel (2/2)

Anpassung des Projektstatus (oder Parameter löschen) in web.xml<context<context<context<context----param>param>param>param>

<param<param<param<param----name>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</paramname>javax.faces.PROJECT_STAGE</param----name>name>name>name><!<!<!<!-------- <param<param<param<param----value>Development</paramvalue>Development</paramvalue>Development</paramvalue>Development</param----value> value> value> value> -------->>>><param<param<param<param----value>Production</paramvalue>Production</paramvalue>Production</paramvalue>Production</param----value>value>value>value>

</context</context</context</context----param>param>param>param>

Applikation bleibt auf der Seite, keine sichtbare Fehlermeldungim Serverim Serverim Serverim Server----Log:Log:Log:Log:INFO: WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange INFO: WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange INFO: WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange INFO: WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange

gestellt, aber möglicherweise nicht angezeigt.gestellt, aber möglicherweise nicht angezeigt.gestellt, aber möglicherweise nicht angezeigt.gestellt, aber möglicherweise nicht angezeigt.sourceId=j_idt7:mname[severity=(ERROR 2), summary=(j_idt7:mname: sourceId=j_idt7:mname[severity=(ERROR 2), summary=(j_idt7:mname: sourceId=j_idt7:mname[severity=(ERROR 2), summary=(j_idt7:mname: sourceId=j_idt7:mname[severity=(ERROR 2), summary=(j_idt7:mname:

ValidierungsValidierungsValidierungsValidierungs----Fehler: Wert wird benötigt.), Fehler: Wert wird benötigt.), Fehler: Wert wird benötigt.), Fehler: Wert wird benötigt.), detail=(j_idt7:mname: Validierungsdetail=(j_idt7:mname: Validierungsdetail=(j_idt7:mname: Validierungsdetail=(j_idt7:mname: Validierungs----Fehler: Wert wird Fehler: Wert wird Fehler: Wert wird Fehler: Wert wird benötigt.)]benötigt.)]benötigt.)]benötigt.)]

Prof. Dr. Stephan Kleuker

292Komponentenbasierte Software-Entwicklung

Direkte Validierungen - einige Möglichkeiten<<<<h:formh:formh:formh:form>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid columnscolumnscolumnscolumns="3" >="3" >="3" >="3" ><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{modul.name}"="#{modul.name}"="#{modul.name}"="#{modul.name}"

requiredrequiredrequiredrequired="="="="truetruetruetrue" " " " sizesizesizesize="8" ="8" ="8" ="8" requiredMessagerequiredMessagerequiredMessagerequiredMessage="="="="nichnichnichnich leer"leer"leer"leer"validatorMessagevalidatorMessagevalidatorMessagevalidatorMessage="4 Zeichen">="4 Zeichen">="4 Zeichen">="4 Zeichen">

<<<<f:validateLengthf:validateLengthf:validateLengthf:validateLength minimumminimumminimumminimum="4" ="4" ="4" ="4" maximummaximummaximummaximum="4"/>="4"/>="4"/>="4"/></</</</h:inputTexth:inputTexth:inputTexth:inputText>>>><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamemnamemnamemname" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="#{modul.nr}" ="#{modul.nr}" ="#{modul.nr}" ="#{modul.nr}" requiredrequiredrequiredrequired="="="="truetruetruetrue""""

requiredMessagerequiredMessagerequiredMessagerequiredMessage="mach Zahl eh" ="mach Zahl eh" ="mach Zahl eh" ="mach Zahl eh" sizesizesizesize="4"="4"="4"="4"converterMessageconverterMessageconverterMessageconverterMessage="="="="nomahlenomahlenomahlenomahle Zahl"/>Zahl"/>Zahl"/>Zahl"/>

<<<<h:messageh:messageh:messageh:message forforforfor="="="="mnrmnrmnrmnr" />" />" />" /><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Abschicken"="Abschicken"="Abschicken"="Abschicken"

actionactionactionaction="#{="#{="#{="#{modul.uebernehmenmodul.uebernehmenmodul.uebernehmenmodul.uebernehmen}"/>}"/>}"/>}"/></</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>>

</</</</h:formh:formh:formh:form>>>>

Prof. Dr. Stephan Kleuker

293Komponentenbasierte Software-Entwicklung

Ausgaben beim Drücken von „Abschicken“

Prof. Dr. Stephan Kleuker

294Komponentenbasierte Software-Entwicklung

Globale Fehlermeldungen erzeugen und anzeigen

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen() {() {() {() {ifififif ((((name.equalsname.equalsname.equalsname.equals("OOAD")) {("OOAD")) {("OOAD")) {("OOAD")) {FacesContextFacesContextFacesContextFacesContext ctxtctxtctxtctxt = = = = FacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstance();();();();FacesMessageFacesMessageFacesMessageFacesMessage msmsmsms = = = = newnewnewnew FacesMessageFacesMessageFacesMessageFacesMessage();();();();ms.setSeverityms.setSeverityms.setSeverityms.setSeverity((((FacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERROR););););ms.setSummaryms.setSummaryms.setSummaryms.setSummary("OOAD ist schon da");("OOAD ist schon da");("OOAD ist schon da");("OOAD ist schon da");ms.setDetailms.setDetailms.setDetailms.setDetail("OOAD im Standard");("OOAD im Standard");("OOAD im Standard");("OOAD im Standard");ctxt.addMessagectxt.addMessagectxt.addMessagectxt.addMessage(null, (null, (null, (null, msmsmsms););););

}}}}returnreturnreturnreturn "ANZEIGEN";"ANZEIGEN";"ANZEIGEN";"ANZEIGEN";

}}}}

//in //in //in //in ausgabe.xhtmlausgabe.xhtmlausgabe.xhtmlausgabe.xhtml<<<<h:formh:formh:formh:form>>>><<<<h:messagesh:messagesh:messagesh:messages globalOnlyglobalOnlyglobalOnlyglobalOnly="true"/>="true"/>="true"/>="true"/><<<<h:outputTexth:outputTexth:outputTexth:outputText value="value="value="value="ModulnameModulnameModulnameModulname: "/>: "/>: "/>: "/>

Prof. Dr. Stephan Kleuker

295Komponentenbasierte Software-Entwicklung

Validierer selbst gestrickt (1/2)

publicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{............// Validierungsmethoden können beliebigen Namen haben,// Validierungsmethoden können beliebigen Namen haben,// Validierungsmethoden können beliebigen Namen haben,// Validierungsmethoden können beliebigen Namen haben,// müssen aber die folgende Signatur haben// müssen aber die folgende Signatur haben// müssen aber die folgende Signatur haben// müssen aber die folgende Signatur habenpublicpublicpublicpublic voidvoidvoidvoid pruefepruefepruefepruefe((((FacesContextFacesContextFacesContextFacesContext contextcontextcontextcontext,,,,

UIComponentUIComponentUIComponentUIComponent componentcomponentcomponentcomponent, , , , ObjectObjectObjectObject valuevaluevaluevalue))))throwsthrowsthrowsthrows ValidatorExceptionValidatorExceptionValidatorExceptionValidatorException {{{{

ifififif (((String) (((String) (((String) (((String) valuevaluevaluevalue).).).).equalsequalsequalsequals("OOAD")) {("OOAD")) {("OOAD")) {("OOAD")) {throwthrowthrowthrow newnewnewnew ValidatorExceptionValidatorExceptionValidatorExceptionValidatorException((((newnewnewnew FacesMessageFacesMessageFacesMessageFacesMessage((((

FacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERRORFacesMessage.SEVERITY_ERROR, ", ", ", "owehowehowehoweh", "", "", "", "oleoleoleole oleoleoleole"));"));"));"));}}}}

}}}}............

Prof. Dr. Stephan Kleuker

296Komponentenbasierte Software-Entwicklung

Validierer selbst gestrickt (2/2)

• in index.xhtml

<<<<h:panelGridh:panelGridh:panelGridh:panelGrid columnscolumnscolumnscolumns="3" >="3" >="3" >="3" >

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/>

<<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{modul.name}" ="#{modul.name}" ="#{modul.name}" ="#{modul.name}"

validatorvalidatorvalidatorvalidator="#{="#{="#{="#{modul.pruefemodul.pruefemodul.pruefemodul.pruefe}"/>}"/>}"/>}"/>

<<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamemnamemnamemname" />" />" />" />

Prof. Dr. Stephan Kleuker

297Komponentenbasierte Software-Entwicklung

Erinnerung: Bean Validation

• nicht:

• besser:

Datenzu-griffsschicht

fachlicheEbene

Oberfläche DB

Nutzer

Java

individuelleDaten-

validierung

individuelleDaten-

validierung

individuelleDaten-

validierung

individuelleDaten-

validierung

Datenzu-griffsschicht

fachlicheEbene

Oberfläche DB

Java

Datenmodell mitValidierungsregeln

Nutzer

Prof. Dr. Stephan Kleuker

298Komponentenbasierte Software-Entwicklung

Beispiel Bean-Validation (1/6)

@@@@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename="="="="modulmodulmodulmodul")")")")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;@Min(@Min(@Min(@Min(valuevaluevaluevalue=100, =100, =100, =100, messagemessagemessagemessage="dreistellig")="dreistellig")="dreistellig")="dreistellig")@Max(@Max(@Max(@Max(valuevaluevaluevalue=999, =999, =999, =999, messagemessagemessagemessage="dreistellig")="dreistellig")="dreistellig")="dreistellig")private private private private intintintint nrnrnrnr;;;;@@@@NotNullNotNullNotNullNotNull @Modulnamenregel(verboten={"VHDL","PNP"}, @Modulnamenregel(verboten={"VHDL","PNP"}, @Modulnamenregel(verboten={"VHDL","PNP"}, @Modulnamenregel(verboten={"VHDL","PNP"},

groupsgroupsgroupsgroups={={={={validators.ModulGroup.classvalidators.ModulGroup.classvalidators.ModulGroup.classvalidators.ModulGroup.class})})})})private String private String private String private String namenamenamename;;;;

//... übliche //... übliche //... übliche //... übliche KonstruktorenKonstruktorenKonstruktorenKonstruktoren, , , , getgetgetget und und und und setsetsetset

Hinweis: Implementierung des Validierers in Libraries benötigt (Klasseneigenschaften werden nicht unterstützt!?)

Prof. Dr. Stephan Kleuker

299Komponentenbasierte Software-Entwicklung

Beispiel Bean-Validation (2/6)

@Target({ElementType.FIELD})@Target({ElementType.FIELD})@Target({ElementType.FIELD})@Target({ElementType.FIELD})

@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)@Retention(RetentionPolicy.RUNTIME)

@Constraint(validatedBy = {ModulnamenregelValidator.class})@Constraint(validatedBy = {ModulnamenregelValidator.class})@Constraint(validatedBy = {ModulnamenregelValidator.class})@Constraint(validatedBy = {ModulnamenregelValidator.class})

@Documented@Documented@Documented@Documented

public @interface Modulnamenregel {public @interface Modulnamenregel {public @interface Modulnamenregel {public @interface Modulnamenregel {

String message() default "Modul unerwuenscht";String message() default "Modul unerwuenscht";String message() default "Modul unerwuenscht";String message() default "Modul unerwuenscht";

Class<?>[] groups() default {};Class<?>[] groups() default {};Class<?>[] groups() default {};Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};Class<? extends Payload>[] payload() default {};

String[] verboten() default {};String[] verboten() default {};String[] verboten() default {};String[] verboten() default {};

}}}}

package validators;package validators;package validators;package validators;

public interface ModulGroup {}public interface ModulGroup {}public interface ModulGroup {}public interface ModulGroup {}

Prof. Dr. Stephan Kleuker

300Komponentenbasierte Software-Entwicklung

Beispiel Bean-Validation (3/6)

public class ModulnamenregelValidator implements public class ModulnamenregelValidator implements public class ModulnamenregelValidator implements public class ModulnamenregelValidator implements ConstraintValidator<Modulnamenregel,String>{ConstraintValidator<Modulnamenregel,String>{ConstraintValidator<Modulnamenregel,String>{ConstraintValidator<Modulnamenregel,String>{

private String[] niveau;private String[] niveau;private String[] niveau;private String[] niveau;

public void initialize(Modulnamenregel cA) {public void initialize(Modulnamenregel cA) {public void initialize(Modulnamenregel cA) {public void initialize(Modulnamenregel cA) {niveau=cA.verboten();niveau=cA.verboten();niveau=cA.verboten();niveau=cA.verboten();

}}}}

public boolean isValid(String t, public boolean isValid(String t, public boolean isValid(String t, public boolean isValid(String t, ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {ConstraintValidatorContext cvc) {

System.out.println("isValid");System.out.println("isValid");System.out.println("isValid");System.out.println("isValid");for(String s:niveau)for(String s:niveau)for(String s:niveau)for(String s:niveau)if(s.equals(t)){if(s.equals(t)){if(s.equals(t)){if(s.equals(t)){cvc.buildConstraintViolationWithTemplate(cvc.buildConstraintViolationWithTemplate(cvc.buildConstraintViolationWithTemplate(cvc.buildConstraintViolationWithTemplate(

"Modul in unerwuenschter Liste: ""Modul in unerwuenschter Liste: ""Modul in unerwuenschter Liste: ""Modul in unerwuenschter Liste: "+Arrays.toString(niveau))+Arrays.toString(niveau))+Arrays.toString(niveau))+Arrays.toString(niveau))

.addConstraintViolation();.addConstraintViolation();.addConstraintViolation();.addConstraintViolation();return false;return false;return false;return false;

}}}}return true;return true;return true;return true;

}}}}}}}}

Prof. Dr. Stephan Kleuker

301Komponentenbasierte Software-Entwicklung

Beispiel Bean-Validation (4/6) - index.xhtml

<<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid columnscolumnscolumnscolumns="3" >="3" >="3" >="3" >

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{modul.name}">="#{modul.name}">="#{modul.name}">="#{modul.name}">

<<<<f:validateBeanf:validateBeanf:validateBeanf:validateBean disableddisableddisableddisabled="="="="falsefalsefalsefalse" " " " validationGroupsvalidationGroupsvalidationGroupsvalidationGroups="="="="validators.ModulGroupvalidators.ModulGroupvalidators.ModulGroupvalidators.ModulGroup"/>"/>"/>"/>

</</</</h:inputTexth:inputTexth:inputTexth:inputText>>>><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamemnamemnamemname" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="#{modul.nr}" />="#{modul.nr}" />="#{modul.nr}" />="#{modul.nr}" /><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnrmnrmnrmnr" />" />" />" /><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Abschicken"="Abschicken"="Abschicken"="Abschicken"

actionactionactionaction="#{="#{="#{="#{modul.uebernehmenmodul.uebernehmenmodul.uebernehmenmodul.uebernehmen}"/>}"/>}"/>}"/></</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>>

</</</</h:formh:formh:formh:form>>>></</</</h:bodyh:bodyh:bodyh:body>>>>

Prof. Dr. Stephan Kleuker

302Komponentenbasierte Software-Entwicklung

Beispiel Bean-Validation (5/6)

Prof. Dr. Stephan Kleuker

303

Beispiel Bean-Validation (6/6)

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

304Komponentenbasierte Software-Entwicklung

Ordentliche Softwarearchitektur

• Controller (und Bean) auch „backing bean“ genannt

• bei DB-Nutzung greift Controller auf DB-Verwaltungsschicht zu; die verwaltet Bean-Objekte

• JPA einfach im Controller (besser eigener Schicht) nutzen (später schöner mit JEE als SessionBean @Stateless)

JSFJSFJSFJSF----SeiteSeiteSeiteSeite<<managed<<managed<<managed<<managed----bean>>bean>>bean>>bean>>

ControllerControllerControllerControllerBeanBeanBeanBean

(Entität)(Entität)(Entität)(Entität)

#{controller.speichern}#{controller.speichern}#{controller.speichern}#{controller.speichern}

#{controller.bearbeiten}#{controller.bearbeiten}#{controller.bearbeiten}#{controller.bearbeiten}

#{controller.bean.attribut}#{controller.bean.attribut}#{controller.bean.attribut}#{controller.bean.attribut}

Prof. Dr. Stephan Kleuker

305Komponentenbasierte Software-Entwicklung

5.4 JSF mit JPA und JNDI

Einschub: Nutzung von JPA bei DB im Server

• Datenbank einrichten

• Datenbank wird unter JNDI-Namen im Server registriert

• JSF-Applikation kann

über JNDI auf DB zugreifen

• JSF-Container regelt DB-Zugriff (nicht Nutzer!), typische container-managed Persistance [geht auch individuell]

Prof. Dr. Stephan Kleuker

306Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (1/9) - Entität (Wdh)

@@@@EntityEntityEntityEntitypublicpublicpublicpublic classclassclassclass Modul Modul Modul Modul implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;@@@@IdIdIdId @@@@GeneratedValueGeneratedValueGeneratedValueGeneratedValue((((strategystrategystrategystrategy = = = = GenerationType.AUTOGenerationType.AUTOGenerationType.AUTOGenerationType.AUTO))))private private private private intintintint idididid;;;;private private private private intintintint nrnrnrnr; // so sind gleiche Nummern erlaubt; // so sind gleiche Nummern erlaubt; // so sind gleiche Nummern erlaubt; // so sind gleiche Nummern erlaubtprivate String private String private String private String namenamenamename;;;;@Version private @Version private @Version private @Version private intintintint versionversionversionversion;;;;publicpublicpublicpublic Modul() { }Modul() { }Modul() { }Modul() { }

publicpublicpublicpublic Modul(Modul(Modul(Modul(intintintint nrnrnrnr, String , String , String , String namenamenamename) {) {) {) {this.nr = this.nr = this.nr = this.nr = nrnrnrnr;;;;this.name = this.name = this.name = this.name = namenamenamename;;;;

}}}}

// fehlen // fehlen // fehlen // fehlen getgetgetget---- und und und und setsetsetset----Methoden, Methoden, Methoden, Methoden, equalsequalsequalsequals über über über über idididid}}}}

Prof. Dr. Stephan Kleuker

307Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (2/9) - Seitenstruktur

Prof. Dr. Stephan Kleuker

308Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (3/9) - Datenbank<?xml version="1.0" encoding="UTF<?xml version="1.0" encoding="UTF<?xml version="1.0" encoding="UTF<?xml version="1.0" encoding="UTF----8"?>8"?>8"?>8"?><persistence version="2.0" <persistence version="2.0" <persistence version="2.0" <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchema----instance" instance" instance" instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence<persistence<persistence<persistence----unit name="JSFModulliste1MitJPAPU" unit name="JSFModulliste1MitJPAPU" unit name="JSFModulliste1MitJPAPU" unit name="JSFModulliste1MitJPAPU"

transactiontransactiontransactiontransaction----type="JTA"> type="JTA"> type="JTA"> type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider<provider>org.eclipse.persistence.jpa.PersistenceProvider<provider>org.eclipse.persistence.jpa.PersistenceProvider<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider></provider></provider></provider><jta<jta<jta<jta----datadatadatadata----source>JSFModul1</jtasource>JSFModul1</jtasource>JSFModul1</jtasource>JSFModul1</jta----datadatadatadata----source>source>source>source><exclude<exclude<exclude<exclude----unlistedunlistedunlistedunlisted----classes>false</excludeclasses>false</excludeclasses>false</excludeclasses>false</exclude----unlistedunlistedunlistedunlisted----classes>classes>classes>classes><properties><properties><properties><properties><property name="eclipselink.ddl<property name="eclipselink.ddl<property name="eclipselink.ddl<property name="eclipselink.ddl----generation" generation" generation" generation"

value="dropvalue="dropvalue="dropvalue="drop----andandandand----createcreatecreatecreate----tables"/>tables"/>tables"/>tables"/></properties></properties></properties></properties>

</persistence</persistence</persistence</persistence----unit>unit>unit>unit></persistence></persistence></persistence></persistence>

Prof. Dr. Stephan Kleuker

309Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (4/9) - Startseite

<h:form id="f1"><h:form id="f1"><h:form id="f1"><h:form id="f1"><h:messages globalOnly="true"/><h:messages globalOnly="true"/><h:messages globalOnly="true"/><h:messages globalOnly="true"/><h:panelGrid columns="3" ><h:panelGrid columns="3" ><h:panelGrid columns="3" ><h:panelGrid columns="3" ><h:outputLabel for="mname" value="Modulname "/><h:outputLabel for="mname" value="Modulname "/><h:outputLabel for="mname" value="Modulname "/><h:outputLabel for="mname" value="Modulname "/><h:inputText id="mname" value="#{module.modul.name}"/><h:inputText id="mname" value="#{module.modul.name}"/><h:inputText id="mname" value="#{module.modul.name}"/><h:inputText id="mname" value="#{module.modul.name}"/><h:message for="mname" /><h:message for="mname" /><h:message for="mname" /><h:message for="mname" /><h:outputLabel for="mnr" value="Modulnummer "/><h:outputLabel for="mnr" value="Modulnummer "/><h:outputLabel for="mnr" value="Modulnummer "/><h:outputLabel for="mnr" value="Modulnummer "/><h:inputText id="mnr" value="#{module.modul.nr}"/><h:inputText id="mnr" value="#{module.modul.nr}"/><h:inputText id="mnr" value="#{module.modul.nr}"/><h:inputText id="mnr" value="#{module.modul.nr}"/><h:message for="mnr"/><h:message for="mnr"/><h:message for="mnr"/><h:message for="mnr"/><h:commandButton value="Abschicken" <h:commandButton value="Abschicken" <h:commandButton value="Abschicken" <h:commandButton value="Abschicken"

action="#{module.uebernehmen}"/>action="#{module.uebernehmen}"/>action="#{module.uebernehmen}"/>action="#{module.uebernehmen}"/></h:panelGrid></h:panelGrid></h:panelGrid></h:panelGrid><h:commandLink action="#{module.anzeigen}" ><h:commandLink action="#{module.anzeigen}" ><h:commandLink action="#{module.anzeigen}" ><h:commandLink action="#{module.anzeigen}" ><h:outputText value="Zur Modulübersicht"/><h:outputText value="Zur Modulübersicht"/><h:outputText value="Zur Modulübersicht"/><h:outputText value="Zur Modulübersicht"/>

</h:commandLink></h:commandLink></h:commandLink></h:commandLink></h:form></h:form></h:form></h:form>

Prof. Dr. Stephan Kleuker

310Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (5/9) - Controller 1/3

@@@@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename="="="="modulemodulemodulemodule")")")")@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublicpublicpublicpublic classclassclassclass ModuleControllerModuleControllerModuleControllerModuleController {{{{

@@@@PersistenceUnitPersistenceUnitPersistenceUnitPersistenceUnit //wichtig, nicht selber erzeugen !!!//wichtig, nicht selber erzeugen !!!//wichtig, nicht selber erzeugen !!!//wichtig, nicht selber erzeugen !!!private private private private EntityManagerFactoryEntityManagerFactoryEntityManagerFactoryEntityManagerFactory emfemfemfemf;;;;@@@@ResourceResourceResourceResourceprivate private private private UserTransactionUserTransactionUserTransactionUserTransaction utxutxutxutx;;;;private List<Modul> private List<Modul> private List<Modul> private List<Modul> modulemodulemodulemodule = = = = newnewnewnew ArrayListArrayListArrayListArrayList<Modul>();<Modul>();<Modul>();<Modul>();private Modul private Modul private Modul private Modul modulmodulmodulmodul====newnewnewnew Modul();Modul();Modul();Modul();private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem;;;;private final String HINZUFUEGEN = "./private final String HINZUFUEGEN = "./private final String HINZUFUEGEN = "./private final String HINZUFUEGEN = "./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml";";";";private final String ANZEIGEN = "./private final String ANZEIGEN = "./private final String ANZEIGEN = "./private final String ANZEIGEN = "./uebersicht.xhtmluebersicht.xhtmluebersicht.xhtmluebersicht.xhtml";";";";private final String EINGEBEN = "./private final String EINGEBEN = "./private final String EINGEBEN = "./private final String EINGEBEN = "./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml";";";";

publicpublicpublicpublic ModuleControllerModuleControllerModuleControllerModuleController() {() {() {() {}}}}

Prof. Dr. Stephan Kleuker

311Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (6/9) - Controller 2/3

publicpublicpublicpublic Modul Modul Modul Modul getModulgetModulgetModulgetModul() {() {() {() {returnreturnreturnreturn modulmodulmodulmodul;};};};}publicpublicpublicpublic void void void void setModulsetModulsetModulsetModul(Modul (Modul (Modul (Modul modulmodulmodulmodul) {) {) {) {this.modulthis.modulthis.modulthis.modul = = = = modulmodulmodulmodul;};};};}publicpublicpublicpublic List<Modul> List<Modul> List<Modul> List<Modul> getModulegetModulegetModulegetModule() {() {() {() {returnreturnreturnreturn modulemodulemodulemodule;};};};}publicpublicpublicpublic void void void void setModulesetModulesetModulesetModule(List<Modul> (List<Modul> (List<Modul> (List<Modul> modulemodulemodulemodule) {) {) {) {this.modulethis.modulethis.modulethis.module = = = = modulemodulemodulemodule;};};};}

publicpublicpublicpublic String anzeigen() {String anzeigen() {String anzeigen() {String anzeigen() {emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager();();();();modulemodulemodulemodule= = = = em.createQueryem.createQueryem.createQueryem.createQuery("SELECT m FROM Modul m",("SELECT m FROM Modul m",("SELECT m FROM Modul m",("SELECT m FROM Modul m",Modul.classModul.classModul.classModul.class))))

....getResultListgetResultListgetResultListgetResultList();();();();em.closeem.closeem.closeem.close();();();();returnreturnreturnreturn ANZEIGEN;ANZEIGEN;ANZEIGEN;ANZEIGEN;

}}}}

publicpublicpublicpublic String eingeben() {String eingeben() {String eingeben() {String eingeben() {modulmodulmodulmodul = = = = newnewnewnew Modul();Modul();Modul();Modul();returnreturnreturnreturn EINGEBEN;EINGEBEN;EINGEBEN;EINGEBEN;

}}}}

Prof. Dr. Stephan Kleuker

312Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (7/9) - Controller 3/3

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen() {() {() {() {FacesContextFacesContextFacesContextFacesContext ctxtctxtctxtctxt = = = = FacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstance();();();();FacesMessageFacesMessageFacesMessageFacesMessage msmsmsms = = = = newnewnewnew FacesMessageFacesMessageFacesMessageFacesMessage("Erfolgreich eingetragen");("Erfolgreich eingetragen");("Erfolgreich eingetragen");("Erfolgreich eingetragen");trytrytrytry {{{{emememem = = = = emf.createEntityManageremf.createEntityManageremf.createEntityManageremf.createEntityManager(); (); (); (); utx.beginutx.beginutx.beginutx.begin();();();();em.persistem.persistem.persistem.persist((((modulmodulmodulmodul););););modulemodulemodulemodule= = = = em.createQueryem.createQueryem.createQueryem.createQuery("SELECT m FROM Modul m",("SELECT m FROM Modul m",("SELECT m FROM Modul m",("SELECT m FROM Modul m",Modul.classModul.classModul.classModul.class) ) ) )

....getResultListgetResultListgetResultListgetResultList();();();();utx.commitutx.commitutx.commitutx.commit();();();();

} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {} catch (Exception e) {trytrytrytry {{{{msmsmsms = = = = newnewnewnew FacesMessageFacesMessageFacesMessageFacesMessage((((

e.getMessagee.getMessagee.getMessagee.getMessage());());());());utx.rollbackutx.rollbackutx.rollbackutx.rollback();();();();

} catch (Exception e2) {} catch (Exception e2) {} catch (Exception e2) {} catch (Exception e2) {msmsmsms = = = = newnewnewnew FacesMessageFacesMessageFacesMessageFacesMessage((((

e2.getMessage());e2.getMessage());e2.getMessage());e2.getMessage());}}}}

} } } } finallyfinallyfinallyfinally {{{{ifififif ((((emememem != null) {!= null) {!= null) {!= null) {

em.closeem.closeem.closeem.close();();();();}}}}

}}}}ctxt.addMessagectxt.addMessagectxt.addMessagectxt.addMessage(null, (null, (null, (null, msmsmsms););););modulmodulmodulmodul====newnewnewnew Modul();Modul();Modul();Modul();returnreturnreturnreturn HINZUFUEGEN;HINZUFUEGEN;HINZUFUEGEN;HINZUFUEGEN;

}}}}}}}}

Prof. Dr. Stephan Kleuker

313Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (8/9) - Ergebnisseite 1/2

<<<<h:formh:formh:formh:form idididid="f2">="f2">="f2">="f2">

<<<<h:messagesh:messagesh:messagesh:messages globalOnlyglobalOnlyglobalOnlyglobalOnly="true"/>="true"/>="true"/>="true"/>

<<<<h:panelGridh:panelGridh:panelGridh:panelGrid renderedrenderedrenderedrendered="#{!="#{!="#{!="#{!emptyemptyemptyempty module.modulemodule.modulemodule.modulemodule.module}">}">}">}">

<<<<h:dataTableh:dataTableh:dataTableh:dataTable valuevaluevaluevalue="#{="#{="#{="#{module.modulemodule.modulemodule.modulemodule.module}" }" }" }" varvarvarvar="m" ="m" ="m" ="m" borderborderborderborder="8" ="8" ="8" ="8"

frameframeframeframe="box" >="box" >="box" >="box" >

<<<<h:columnh:columnh:columnh:column >>>>

<<<<f:facetf:facetf:facetf:facet namenamenamename="="="="headerheaderheaderheader">">">">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Nummer" />="Nummer" />="Nummer" />="Nummer" />

</</</</f:facetf:facetf:facetf:facet>>>>

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue="#{m.nr}"/>="#{m.nr}"/>="#{m.nr}"/>="#{m.nr}"/>

</</</</h:columnh:columnh:columnh:column>>>>

Prof. Dr. Stephan Kleuker

314Komponentenbasierte Software-Entwicklung

Verwaltung einer Modulliste (9/9) - Ergebnisseite 2/2

<<<<h:columnh:columnh:columnh:column>>>>

<<<<f:facetf:facetf:facetf:facet namenamenamename="="="="headerheaderheaderheader">">">">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Modulname" />="Modulname" />="Modulname" />="Modulname" />

</</</</f:facetf:facetf:facetf:facet>>>>

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue="#{m.name}"/>="#{m.name}"/>="#{m.name}"/>="#{m.name}"/>

</</</</h:columnh:columnh:columnh:column>>>>

</</</</h:dataTableh:dataTableh:dataTableh:dataTable>>>>

</</</</h:panelGridh:panelGridh:panelGridh:panelGrid> > > >

<<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink actionactionactionaction="#{="#{="#{="#{module.eingebenmodule.eingebenmodule.eingebenmodule.eingeben}" >}" >}" >}" >

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Zur Moduleingabe"/>="Zur Moduleingabe"/>="Zur Moduleingabe"/>="Zur Moduleingabe"/>

</</</</h:commandLinkh:commandLinkh:commandLinkh:commandLink>>>>

</</</</h:formh:formh:formh:form>>>>

Prof. Dr. Stephan Kleuker

315

Projektaufbau

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

316

Einschub: Ausgabe von Sammlungen

<<<<h:dataTableh:dataTableh:dataTableh:dataTable valuevaluevaluevalue="#{="#{="#{="#{module.modulemodule.modulemodule.modulemodule.module}" }" }" }" varvarvarvar="m">="m">="m">="m">

• dataTable erlaubt die Datenaufbereitung einer Collection in Tabellenform (Iterator über Daten mit getModule(); Elemente in Variable m); grundlegende Darstellungsmöglichkeiten einstellbar

• Zur Ausgabe wird minimal <<<<h:columnh:columnh:columnh:column>>>> benötigt

• Attribut firstfirstfirstfirst für erste Zeile und rowsrowsrowsrows für Zeilenzahl

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

317

5.5 Kompakt: EJB-SessionBeans und CDI

Architekturvariante

• bisher einfache direkte Software-Architektur (nutzbar für kleinere und mittlere Projekte)

• Problem: Skalierung nicht unbedingt sichergestellt, da Server nicht im Detail eingreifen kann (Ansatz: Mehrschichtarchitektur basierend auf EJB)

• Problem: direkte Nutzung von JPA sehr bastelig

• JEE-Problematik: JSF-Lösungen stark auf JSF-fokussiert, wie auf verwandte JEE-Techniken übertragen (Ansatz: Contextand Dependency Injection, CDI)

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

318

EJB - Konzept

• Standardisierte Komponenten eines JEE-Servers

• Klassen zur Steuerung von Prozessen und Verwaltung von Daten, die leicht in anderen EJB-Applikationen nutzbar sind

• Unterstützt mit wenig Aufwand

– Transaktionssteuerung

– Sicherheitseinstellungen

– Identifikation von Objekten zur Zusammenarbeit

• Drei Arten (local und remote Varianten)

– Entity Bean (POJO, @Entity wie bereits bekannt)

– Session Bean: Kommunikation mit (End-)Anwendungen

• @Stateless: bei jeder Nutzung neu erstellt

• @Stateful: in einer Session nutzbar

– Message Driven Bean: asynchroner NachrichtenablaufKomponentenbasierte Software-

Entwicklung

Prof. Dr. Stephan Kleuker

319

EJB-Umsetzung (1/4)

packagepackagepackagepackage ejbejbejbejb;;;;importimportimportimport entities.Modulentities.Modulentities.Modulentities.Modul;;;;importimportimportimport java.util.Listjava.util.Listjava.util.Listjava.util.List;;;;importimportimportimport javax.ejb.Statelessjavax.ejb.Statelessjavax.ejb.Statelessjavax.ejb.Stateless;;;;importimportimportimport javax.persistence.EntityManagerjavax.persistence.EntityManagerjavax.persistence.EntityManagerjavax.persistence.EntityManager;;;;importimportimportimport javax.persistence.PersistenceContextjavax.persistence.PersistenceContextjavax.persistence.PersistenceContextjavax.persistence.PersistenceContext;;;;

@@@@StatelessStatelessStatelessStatelesspublicpublicpublicpublic classclassclassclass Modulverwaltung {Modulverwaltung {Modulverwaltung {Modulverwaltung {@@@@PersistenceContextPersistenceContextPersistenceContextPersistenceContext((((unitNameunitNameunitNameunitName = "= "= "= "vlJSFModullisteMitEJBPUvlJSFModullisteMitEJBPUvlJSFModullisteMitEJBPUvlJSFModullisteMitEJBPU")")")")private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem;;;;

publicpublicpublicpublic voidvoidvoidvoid persistpersistpersistpersist((((ObjectObjectObjectObject objectobjectobjectobject) {) {) {) {em.persistem.persistem.persistem.persist((((objectobjectobjectobject); //); //); //); //ExceptionExceptionExceptionException weiterreichenweiterreichenweiterreichenweiterreichen

}}}}

publicpublicpublicpublic List<Modul> List<Modul> List<Modul> List<Modul> getModulegetModulegetModulegetModule() { () { () { () { returnreturnreturnreturn em.createQueryem.createQueryem.createQueryem.createQuery("SELECT m FROM Modul m", ("SELECT m FROM Modul m", ("SELECT m FROM Modul m", ("SELECT m FROM Modul m", Modul.classModul.classModul.classModul.class) ) ) )

....getResultListgetResultListgetResultListgetResultList(); (); (); (); } } } }

}}}}Komponentenbasierte Software-

Entwicklung

Prof. Dr. Stephan Kleuker

320

EJB-Umsetzung (2/4) – Teil 1/2

packagepackagepackagepackage viewviewviewview;;;;importimportimportimport ejb.Modulverwaltungejb.Modulverwaltungejb.Modulverwaltungejb.Modulverwaltung;;;;importimportimportimport entities.Modulentities.Modulentities.Modulentities.Modul;;;;importimportimportimport java.io.Serializablejava.io.Serializablejava.io.Serializablejava.io.Serializable;;;;importimportimportimport java.util.Listjava.util.Listjava.util.Listjava.util.List;;;;importimportimportimport javax.ejb.EJBjavax.ejb.EJBjavax.ejb.EJBjavax.ejb.EJB;;;;importimportimportimport javax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBeanjavax.faces.bean.ManagedBean;;;;importimportimportimport javax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScopedjavax.faces.bean.RequestScoped;;;;

@@@@ManagedBeanManagedBeanManagedBeanManagedBean((((namenamenamename = "= "= "= "modulemodulemodulemodule")")")")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublicpublicpublicpublic classclassclassclass ModulBeanModulBeanModulBeanModulBean implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;private private private private Modul Modul Modul Modul modulmodulmodulmodul = = = = newnewnewnew Modul();Modul();Modul();Modul();@EJB@EJB@EJB@EJBprivate Modulverwaltung mv;private Modulverwaltung mv;private Modulverwaltung mv;private Modulverwaltung mv;

publicpublicpublicpublic ModulBeanModulBeanModulBeanModulBean() {() {() {() {}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

321

EJB-Umsetzung (3/4) – Teil 2/2

publicpublicpublicpublic List<Modul> List<Modul> List<Modul> List<Modul> getModulegetModulegetModulegetModule() {() {() {() {returnreturnreturnreturn mv.getModulemv.getModulemv.getModulemv.getModule();();();();

}}}}

publicpublicpublicpublic String String String String uebernehmenuebernehmenuebernehmenuebernehmen() {() {() {() {trytrytrytry {{{{mv.persistmv.persistmv.persistmv.persist((((modulmodulmodulmodul););););// // // // modulmodulmodulmodul = = = = newnewnewnew Modul() nicht notwendigModul() nicht notwendigModul() nicht notwendigModul() nicht notwendig

} catch (} catch (} catch (} catch (ExceptionExceptionExceptionException e) e) e) e) { // wie vorher mit { // wie vorher mit { // wie vorher mit { // wie vorher mit FacesContextFacesContextFacesContextFacesContext}}}}returnreturnreturnreturn "./"./"./"./uebersicht.xhtmluebersicht.xhtmluebersicht.xhtmluebersicht.xhtml";";";";

}}}}

publicpublicpublicpublic String eingeben() String eingeben() String eingeben() String eingeben() { { { { returnreturnreturnreturn "./"./"./"./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml";}";}";}";}

publicpublicpublicpublic String anzeigenString anzeigenString anzeigenString anzeigen() () () () { { { { returnreturnreturnreturn "./"./"./"./uebersicht.xhtmluebersicht.xhtmluebersicht.xhtmluebersicht.xhtml";}";}";}";}

// // // // getgetgetget und und und und setsetsetset für für für für this.modulthis.modulthis.modulthis.modul

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

322

EJB-Umsetzung (4/4)

• Klasse Modul bleibt unverändert

• XHTML-Seiten bleiben unverändert

• gleiches Verhalten, wie vorher

• wenn durchhangeln über this.modul nicht gewünscht:publicpublicpublicpublic classclassclassclass ModulBeanModulBeanModulBeanModulBean implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private private private private staticstaticstaticstatic final final final final longlonglonglong serialVersionUIDserialVersionUIDserialVersionUIDserialVersionUID = 1L;= 1L;= 1L;= 1L;private private private private intintintint nrnrnrnr;;;;private private private private String String String String namenamenamename;;;;@@@@EJBEJBEJBEJBprivate Modulverwaltung mvprivate Modulverwaltung mvprivate Modulverwaltung mvprivate Modulverwaltung mv;;;;// Methoden anpassen, in index.html direkt module.nr// Methoden anpassen, in index.html direkt module.nr// Methoden anpassen, in index.html direkt module.nr// Methoden anpassen, in index.html direkt module.nr

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

323

Projektstruktur

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

324

CDI

• JSF-Lösungen stark auf JSF-fokussiert, wie auf verwandte JEE-Techniken übertragen?

• JSR 299: Contexts and Dependency Injection for the JavaTM

EE platform (http://www.jcp.org/en/jsr/detail?id=299)

• Zugriff von JSF-Seiten auf Objekte über @Named-Annotation (statt @ManagedBean); auch außerhalb JSF nutzbar

• Wunsch flexible Nutzung von Objekten innerhalb des Servers -> Server kennt Klassen und stellt Objekte zur Verfügung

• Exemplarvariable/ als Parameter @Inject Modul m

• Benötigt beans.xml-Datei (in META-INF), ist im einfachsten Fall leer

• Dokumentation: http://docs.jboss.org/weld/reference/1.1.0.Final/en-

US/pdf/weld-reference.pdf

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

325

Beispiel: Modulverwaltung aus mehreren Schichten

• Web-Design (XHTML-Seiten) [unverändert]

• Managed Bean (jetzt @Named) zur Verwaltung der Ein- und Ausgaben

• Session-Bean zur Verwaltung der Objekte; Kapselung der JPA-Schicht (Details für Entwickler verstecken)

• Datenobjekte (@Entity) [unverändert]

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

326

Umsetzung

@@@@NamedNamedNamedNamed("("("("modulDelegatemodulDelegatemodulDelegatemodulDelegate") // flexibler als ") // flexibler als ") // flexibler als ") // flexibler als ManagedBeanManagedBeanManagedBeanManagedBean//(braucht beans.xml)//(braucht beans.xml)//(braucht beans.xml)//(braucht beans.xml)

@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublicpublicpublicpublic classclassclassclass ModulDelegateModulDelegateModulDelegateModulDelegate implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

• Generell weitere Annotation möglich, die z. B. Observer-Observable allein über Annotationen regeln

• ausnahmsweise gutes Video

http://www.youtube.com/watch?v=ZKpUoatSkTc&list=UUkQX1tChV7Z7l1LFF4L9j_g&index=50&feature=plpp

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

327Komponentenbasierte Software-Entwicklung

5.6 Funktionale Erweiterung

Interessante JSF-Elemente

<<<<f:facetf:facetf:facetf:facet namenamenamename="="="="headerheaderheaderheader">">">">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Nummer" />="Nummer" />="Nummer" />="Nummer" />

</</</</f:facetf:facetf:facetf:facet>>>>

• facet dient zur Ergänzung verschiedener anderer JSF-Elemente; Art der Ergänzung durch Attribut name festgelegt

Prof. Dr. Stephan Kleuker

328Komponentenbasierte Software-Entwicklung

Architekturvariante ab JSF 2.0

• Grundidee: (fast) alle Objekte werden als ManagedBeans(mit unterschiedlichem Scope) aufgefasst

• ManagedBeans können andere als Parameter in Methodenaufrufen (action-Methoden) enthalten

@@@@ManagedBeanManagedBeanManagedBeanManagedBean(name = "a")(name = "a")(name = "a")(name = "a")@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublic class A { ...public class A { ...public class A { ...public class A { ...

private String private String private String private String machmachmachmach(B b){(B b){(B b){(B b){// // // // kannkannkannkann b b b b bearbeitenbearbeitenbearbeitenbearbeiten////nutzennutzennutzennutzenreturn "String return "String return "String return "String mitmitmitmit PfadPfadPfadPfad zurzurzurzur nächstennächstennächstennächsten SeiteSeiteSeiteSeite";";";";

} ...} ...} ...} ...

@@@@ManagedBeanManagedBeanManagedBeanManagedBean(name = "b")(name = "b")(name = "b")(name = "b")@@@@RequestScopedRequestScopedRequestScopedRequestScopedpublic class B { ...public class B { ...public class B { ...public class B { ...

<<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink value="value="value="value="BearbeitungBearbeitungBearbeitungBearbeitung" action="#{" action="#{" action="#{" action="#{a.macha.macha.macha.mach(b)}"/>(b)}"/>(b)}"/>(b)}"/>

Prof. Dr. Stephan Kleuker

329Komponentenbasierte Software-Entwicklung

Kurze Diskussion der Architekturvarianten

• Klassischer Ansatz

– saubere Steuerungsklasse(n)

– Mehrfachpunktnotation sehr unüblich für Attribute

• neuer Ansatz ab JSF 2.0

<<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink value="value="value="value="BearbeitungBearbeitungBearbeitungBearbeitung" action="#{" action="#{" action="#{" action="#{a.macha.macha.macha.mach(b)}"/>(b)}"/>(b)}"/>(b)}"/>

– für Programmierer (!) intuitive Methodennutzung

– Objekt b nicht änderbar (sei anderes Objekt, geht nicht)

• CDI-Variante über Annotationen

• generelle Frage: wie steht es mit Objektorientierung

#{#{#{#{controller.bean.attributcontroller.bean.attributcontroller.bean.attributcontroller.bean.attribut}}}}

Prof. Dr. Stephan Kleuker

330Komponentenbasierte Software-Entwicklung

Funktionalität ergänzen (1/6) - Aufgabe

• Moduleinträge sollen editierbar werden

• Problem: Editieren-Link muss Modul erkennen

• Ansatz: Link erhält Parameter, der als Request-Parameter ausgelesen werden kann

• Hinweis: JSFfigerer Ansatz unter Nutzung des DataModels und von Data-Model-Events lösbar

Prof. Dr. Stephan Kleuker

331

<<<<h:dataTableh:dataTableh:dataTableh:dataTable valuevaluevaluevalue="#{="#{="#{="#{module.modulemodule.modulemodule.modulemodule.module}" }" }" }" varvarvarvar="m" ="m" ="m" ="m" borderborderborderborder="8" ="8" ="8" ="8"

frameframeframeframe="box" >="box" >="box" >="box" >

............

<<<<h:columnh:columnh:columnh:column>>>>

<<<<f:facetf:facetf:facetf:facet namenamenamename="="="="headerheaderheaderheader">">">">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Bearbeitung"/>="Bearbeitung"/>="Bearbeitung"/>="Bearbeitung"/>

</</</</f:facetf:facetf:facetf:facet>>>>

<<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink actionactionactionaction="#{="#{="#{="#{module.editierenmodule.editierenmodule.editierenmodule.editieren}">}">}">}">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Editieren"/>="Editieren"/>="Editieren"/>="Editieren"/>

<<<<f:paramf:paramf:paramf:param namenamenamename="="="="editediteditedit" " " " valuevaluevaluevalue="#{m.id}"/>="#{m.id}"/>="#{m.id}"/>="#{m.id}"/>

</</</</h:commandLinkh:commandLinkh:commandLinkh:commandLink>>>>

</</</</h:columnh:columnh:columnh:column>>>>

............

Komponentenbasierte Software-Entwicklung

Funktionalität ergänzen (2/6) - uebersicht.xhtml

Prof. Dr. Stephan Kleuker

332

Funktionalität ergänzen (3/6) - Persistierung@@@@StatelessStatelessStatelessStatelesspublicpublicpublicpublic classclassclassclass Modulverwaltung {Modulverwaltung {Modulverwaltung {Modulverwaltung {@@@@PersistenceContextPersistenceContextPersistenceContextPersistenceContext((((unitNameunitNameunitNameunitName = = = = """"JSFModullisteAenderungPUJSFModullisteAenderungPUJSFModullisteAenderungPUJSFModullisteAenderungPU")")")")private private private private EntityManagerEntityManagerEntityManagerEntityManager emememem;;;;

publicpublicpublicpublic voidvoidvoidvoid persistpersistpersistpersist((((ObjectObjectObjectObject objectobjectobjectobject) {) {) {) {em.persistem.persistem.persistem.persist((((objectobjectobjectobject); //Erinnerung ); //Erinnerung ); //Erinnerung ); //Erinnerung –––– ExceptionsExceptionsExceptionsExceptions weitergegebenweitergegebenweitergegebenweitergegeben

}}}}

publicpublicpublicpublic voidvoidvoidvoid update(update(update(update(ObjectObjectObjectObject objectobjectobjectobject) {) {) {) {em.mergeem.mergeem.mergeem.merge((((objectobjectobjectobject););););

}}}}

publicpublicpublicpublic Modul find(String Modul find(String Modul find(String Modul find(String idididid){){){){returnreturnreturnreturn em.findem.findem.findem.find((((Modul.classModul.classModul.classModul.class, , , , Integer.parseIntInteger.parseIntInteger.parseIntInteger.parseInt((((idididid));));));));

}}}}

publicpublicpublicpublic List<Modul> List<Modul> List<Modul> List<Modul> getModulegetModulegetModulegetModule() { () { () { () { returnreturnreturnreturn em.createQueryem.createQueryem.createQueryem.createQuery("SELECT m FROM Modul m", ("SELECT m FROM Modul m", ("SELECT m FROM Modul m", ("SELECT m FROM Modul m", Modul.classModul.classModul.classModul.class) ) ) )

....getResultListgetResultListgetResultListgetResultList(); (); (); (); } } } }

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

333Komponentenbasierte Software-Entwicklung

Funktionalität ergänzen (4/6) - Seite einbauen

// in // in // in // in ModuleBean.javaModuleBean.javaModuleBean.javaModuleBean.java@@@@SessionScopedSessionScopedSessionScopedSessionScoped // neu// neu// neu// neupublicpublicpublicpublic classclassclassclass ModulBeanModulBeanModulBeanModulBean implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private String private String private String private String getRequestParametergetRequestParametergetRequestParametergetRequestParameter(String par) {(String par) {(String par) {(String par) {returnreturnreturnreturn FacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstanceFacesContext.getCurrentInstance()()()()

....getExternalContextgetExternalContextgetExternalContextgetExternalContext()()()()

....getRequestParameterMapgetRequestParameterMapgetRequestParameterMapgetRequestParameterMap().().().().getgetgetget(par);(par);(par);(par);} //evtl. in Hilfsklasse auslagern} //evtl. in Hilfsklasse auslagern} //evtl. in Hilfsklasse auslagern} //evtl. in Hilfsklasse auslagern

publicpublicpublicpublic String editieren() {String editieren() {String editieren() {String editieren() {String String String String midmidmidmid = = = = getRequestParametergetRequestParametergetRequestParametergetRequestParameter("("("("editediteditedit");");");");modulmodulmodulmodul = = = = mv.findmv.findmv.findmv.find((((midmidmidmid); // Erinnerung @EJB Modulverwaltung); // Erinnerung @EJB Modulverwaltung); // Erinnerung @EJB Modulverwaltung); // Erinnerung @EJB Modulverwaltungreturnreturnreturnreturn "./"./"./"./edit.xhtmledit.xhtmledit.xhtmledit.xhtml"; "; "; ";

}}}}

Prof. Dr. Stephan Kleuker

334Komponentenbasierte Software-Entwicklung

Funktionalität ergänzen (5/6) - edit.xhtml

<<<<h:formh:formh:formh:form>>>><<<<h:panelGridh:panelGridh:panelGridh:panelGrid columnscolumnscolumnscolumns="3">="3">="3">="3">

<<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue="interne ID "/>="interne ID "/>="interne ID "/>="interne ID "/><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue="#{module.modul.id}"/>="#{module.modul.id}"/>="#{module.modul.id}"/>="#{module.modul.id}"/><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel valuevaluevaluevalue=" "/>=" "/>=" "/>=" "/><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="Modulname "/>="Modulname "/>="Modulname "/>="Modulname "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnamemnamemnamemname" " " " valuevaluevaluevalue="#{module.modul.name}"/>="#{module.modul.name}"/>="#{module.modul.name}"/>="#{module.modul.name}"/><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnamemnamemnamemname" />" />" />" /><<<<h:outputLabelh:outputLabelh:outputLabelh:outputLabel forforforfor="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="Modulnummer "/>="Modulnummer "/>="Modulnummer "/>="Modulnummer "/><<<<h:inputTexth:inputTexth:inputTexth:inputText idididid="="="="mnrmnrmnrmnr" " " " valuevaluevaluevalue="#{module.modul.nr}"/>="#{module.modul.nr}"/>="#{module.modul.nr}"/>="#{module.modul.nr}"/><<<<h:messageh:messageh:messageh:message forforforfor="="="="mnrmnrmnrmnr"/>"/>"/>"/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Ändern" ="Ändern" ="Ändern" ="Ändern" actionactionactionaction="#{="#{="#{="#{module.aendernmodule.aendernmodule.aendernmodule.aendern}"/>}"/>}"/>}"/>

</</</</h:panelGridh:panelGridh:panelGridh:panelGrid>>>><<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink actionactionactionaction="#{="#{="#{="#{module.anzeigenmodule.anzeigenmodule.anzeigenmodule.anzeigen}" >}" >}" >}" ><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Zur Modulübersicht"/>="Zur Modulübersicht"/>="Zur Modulübersicht"/>="Zur Modulübersicht"/>

</</</</h:commandLinkh:commandLinkh:commandLinkh:commandLink>>>></</</</h:formh:formh:formh:form>>>>

Prof. Dr. Stephan Kleuker

335Komponentenbasierte Software-Entwicklung

Funktionalität ergänzen (6/6) - Ändern

// in // in // in // in ModuleBean.javaModuleBean.javaModuleBean.javaModuleBean.javapublicpublicpublicpublic String String String String aendernaendernaendernaendern() () () () {{{{

trytrytrytry{ { { { mv.updatemv.updatemv.updatemv.update((((modulmodulmodulmodul););););modulmodulmodulmodul = = = = newnewnewnew ModulModulModulModul();();();();

} catch (} catch (} catch (} catch (ExceptionExceptionExceptionException e) {e) {e) {e) {// TODO sinnvolle Fehlermeldung für JSF// TODO sinnvolle Fehlermeldung für JSF// TODO sinnvolle Fehlermeldung für JSF// TODO sinnvolle Fehlermeldung für JSF

}}}}returnreturnreturnreturn "./"./"./"./uebersicht.xhtmluebersicht.xhtmluebersicht.xhtmluebersicht.xhtml";";";";

}}}}

// in // in // in // in uebernehmenuebernehmenuebernehmenuebernehmen() und eingeben() vor () und eingeben() vor () und eingeben() vor () und eingeben() vor returnreturnreturnreturn ergänzenergänzenergänzenergänzenmodulmodulmodulmodul = = = = newnewnewnew Modul();Modul();Modul();Modul();

}}}}

Prof. Dr. Stephan Kleuker

336Komponentenbasierte Software-Entwicklung

Beispielnutzung

11112222

3333

44445555

6666

Prof. Dr. Stephan Kleuker

337Komponentenbasierte Software-Entwicklung

Variante: JSF 2.0 ohne f:param

<<<<h:dataTableh:dataTableh:dataTableh:dataTable value="#{value="#{value="#{value="#{module.modulemodule.modulemodule.modulemodule.module}" }" }" }" varvarvarvar="m" border="8" ="m" border="8" ="m" border="8" ="m" border="8" frame="box" >frame="box" >frame="box" >frame="box" >

............<<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink value="value="value="value="EditierenEditierenEditierenEditieren" " " "

action="#{action="#{action="#{action="#{module.editierenmodule.editierenmodule.editierenmodule.editieren(m)}"/>(m)}"/>(m)}"/>(m)}"/>

// in ModulBean.java// in ModulBean.java// in ModulBean.java// in ModulBean.javapublicpublicpublicpublic String editieren(Modul m) {String editieren(Modul m) {String editieren(Modul m) {String editieren(Modul m) {

modulmodulmodulmodul=m=m=m=m;;;;returnreturnreturnreturn EDITIEREN;EDITIEREN;EDITIEREN;EDITIEREN;

}}}}

Prof. Dr. Stephan Kleuker

338Komponentenbasierte Software-Entwicklung

5.7 Sicherheit

Vier Aufgaben

• Authentifizierung: Nutzer erkennen; klassisch über Name und Passwort

• Autorisierung: Nutzer darf nur bestimmte Aktionen durchführen, klassisch über Rechte-Rollen-System

• Vertraulichkeit: kein weiterer Nutzer (außer BKA, CIA, ...) darf Informationen mitlesen

• Unverfälschtheit: Inhalte werden zwischen Senden und Empfangen nicht verändert

• letzten beiden Punkte typischerweise durch Verschlüsselung realisiert

Prof. Dr. Stephan Kleuker

339

Nutzer – Rollen – Gruppen

• typischerweise wird ein Nutzer einer oder mehreren Gruppen (mit unterschiedlichen) Rechten zugeordnet

• zur Vereinfachung (Abstraktion) bekommt jeder Nutzer genau eine Rolle, die dann verschiedenen Gruppen zugeordnet werden kann

• jede benötigte Gruppenkombination benötigt eine Rolle

Komponentenbasierte Software-Entwicklung

Nutzer

Rolle

Gruppe

1

MNC

NC

NC M

Prof. Dr. Stephan Kleuker

340Komponentenbasierte Software-Entwicklung

Varianten zur Realisierung

• direkt von Hand codieren (mit DB-Anbindung für uns technisch kein Problem; Übertragung aber unsicher mit HTTP)

– jeder Methodenaufruf beginnt mit Berechtigungsprüfung

• deklarativ

– Möglichkeit zur abgetrennten Authentifizierung

– Seiten (Servlets, JSP, JSF) können als schützenswert markiert werden (im Deployment Descriptor)

– Zugang zu Seiten wird nur Nutzer in bestimmten Rollen gewährleistet

• deklarativ (Variante)

– Programmcode direkt mit erlaubten Rollen annotieren

Prof. Dr. Stephan Kleuker

341Komponentenbasierte Software-Entwicklung

Umsetzungsmöglichkeit in JSF

Deployment Descriptor (web.xml)

• Man kann Rollen definieren

• Man kann Seiten/Ordner Rollen zuordnen

• Man kann Art der Übertragung festlegen

und Applikationsserver-spezifisch:

• Auswahl eines Informationssystems zur Authentifizierung (Nutzer, Passwort, zugehörige Rollen), z. B. im Server selbst, Datenbank, Anbindung LDAP

• Zuordnung der Server-Gruppen zu den Rollen der JSF-Applikation (oder Zuordnung von Nutzern zu Rollen der JSF-Applikation)

Prof. Dr. Stephan Kleuker

342Komponentenbasierte Software-Entwicklung

Applikationsbeispiel - Überblick

1. Nutzer wählt Funktionalität

2. Nutzer muss sich authentifizieren

3. Prüfung ob Nutzer erlaubt und ob er benötigte Rechte hat

4a. falls ja, Zugang zur Funktionalität

4b. falls Nutzer unbekannt, ihn über Scheitern informieren

4c. falls Nutzer bekannt und zu wenig Rechte, ihn über fehlende Rechte informieren [oder wie 4b behandeln]

• Hinweis: statt geschützten Zugriff auf Startseite kann diese noch offen sein (ergonomisch, weitere Einstellungen regelbar)

• technische Probleme:

– Nutzer kann mehrere Seiten für gleiche Applikation nutzen

– Nutzer spielt mit „Back“-Button

Prof. Dr. Stephan Kleuker

343

Sicheres JSF (1/17) – Aufgabenstellung / Nutzer

• Nur registrierte Basisnutzer können Modul hinzufügen

• Nur Editierer (Admins) dürfen Modul bearbeiten

• Server unterstützen verschiedene Sicherheitsmechanismen

• direkter Eintrag von Nutzern im Server

• Anbindung an LDAP

• Nutzung eigener Tabellen (wird hier genutzt, eigener Realm, eigene Tabellen zur Verwaltung, mit verschlüsselten Passwort, genauer: http://home.edvsz.hs-osnabrueck.de/skleuker/querschnittlich/NetbeansNutzung.pdf)

Komponentenbasierte Software-Entwicklung

username password

edna edna

uwe uwe

otto otto

groupid usernme

admin edna

basic edna

basic uwe

Nutzer Gruppen

Prof. Dr. Stephan Kleuker

344

Sicheres JSF (2/17) – Ergebnis 1/3

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

345

Sicheres JSF (3/17) – Ergebnis 2/3

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

346

Sicheres JSF (4/17) – Ergebnis 3/3 - Konzept

• Web-Seiten in Ordner pro Nutzergruppe einordnen

• In web.xml regeln, welche Gruppe worauf zugreifen darf

• Standard login-Servlet einschalten und nutzen

• Ausnahmefälle regeln

• Ausloggen sicherstellen (Session deaktivieren)

• generell: inkrementelle Entwicklung

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

347

Sicheres JSF (5/17) - Projektstruktur

Komponentenbasierte Software-Entwicklung

• serverspezifische Einstellungen• Angabe von Rollen und Rechten

• zu schützende Informationen pro Gruppe

• auch Startseite geschützt

• Eingabe der Nutzererkennung

• bekannter Nutzer ohne Rechte

• nicht existenter Nutzer

Prof. Dr. Stephan Kleuker

348Komponentenbasierte Software-Entwicklung

Sicheres JSF (6/17) - serverindividuelle Vorbereitung

• Rechte-Rollen werden mit konkreten Nutzern in Datei glassfish-web.xml (vorher sun-web.xml) umgesetzt

• <<<<securitysecuritysecuritysecurity----rolerolerolerole----mapping>mapping>mapping>mapping><role<role<role<role----name>name>name>name>basisnutzerbasisnutzerbasisnutzerbasisnutzer</role</role</role</role----name>name>name>name><group<group<group<group----name>basic</groupname>basic</groupname>basic</groupname>basic</group----name>name>name>name>

</security</security</security</security----rolerolerolerole----mapping>mapping>mapping>mapping><security<security<security<security----rolerolerolerole----mapping>mapping>mapping>mapping><role<role<role<role----name>name>name>name>editierereditierereditierereditierer</role</role</role</role----name>name>name>name><group<group<group<group----name>admin</groupname>admin</groupname>admin</groupname>admin</group----name>name>name>name>

</security</security</security</security----rolerolerolerole----mapping>mapping>mapping>mapping>

• Auch Nutzer (username) direkt eintragbar

Gruppenname aus Datenbank (Spalte)

Prof. Dr. Stephan Kleuker

349

<<<<welcomewelcomewelcomewelcome----filefilefilefile----list>list>list>list><<<<welcomewelcomewelcomewelcome----file>file>file>file>facesfacesfacesfaces////hinzufuegenhinzufuegenhinzufuegenhinzufuegen////index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml</</</</welcomewelcomewelcomewelcome----file>file>file>file>

</</</</welcomewelcomewelcomewelcome----filefilefilefile----list>list>list>list><<<<securitysecuritysecuritysecurity----constraintconstraintconstraintconstraint>>>>

<display<display<display<display----name>C1</displayname>C1</displayname>C1</displayname>C1</display----name>name>name>name><web<web<web<web----resourceresourceresourceresource----collectioncollectioncollectioncollection>>>>

<web<web<web<web----resourceresourceresourceresource----name>Basisschutz</webname>Basisschutz</webname>Basisschutz</webname>Basisschutz</web----resourceresourceresourceresource----name>name>name>name><<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<urlurlurlurl----pattern>/pattern>/pattern>/pattern>/facesfacesfacesfaces////hinzufuegenhinzufuegenhinzufuegenhinzufuegen/*<//*<//*<//*</urlurlurlurl----pattern>pattern>pattern>pattern><http<http<http<http----methodmethodmethodmethod>GET</http>GET</http>GET</http>GET</http----methodmethodmethodmethod>>>><http<http<http<http----methodmethodmethodmethod>POST</http>POST</http>POST</http>POST</http----methodmethodmethodmethod>>>>

</web</web</web</web----resourceresourceresourceresource----collectioncollectioncollectioncollection>>>><<<<authauthauthauth----constraintconstraintconstraintconstraint>>>>

<<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<rolerolerolerole----name>name>name>name>basisnutzerbasisnutzerbasisnutzerbasisnutzer</</</</rolerolerolerole----name>name>name>name>

</</</</authauthauthauth----constraintconstraintconstraintconstraint>>>><user<user<user<user----datadatadatadata----constraintconstraintconstraintconstraint>>>>

<transport<transport<transport<transport----guaranteeguaranteeguaranteeguarantee>CONFIDENTIAL</transport>CONFIDENTIAL</transport>CONFIDENTIAL</transport>CONFIDENTIAL</transport----guaranteeguaranteeguaranteeguarantee>>>></user</user</user</user----datadatadatadata----constraintconstraintconstraintconstraint>>>>

</</</</securitysecuritysecuritysecurity----constraintconstraintconstraintconstraint>>>>Komponentenbasierte Software-

Entwicklung

Sicheres JSF (7/17) - JSF-Konfiguration web.xml [1/3]

Startseite im Unterordner

Regel für alle Seiten des Ordners

wer darf

HTTPS einschalten

Prof. Dr. Stephan Kleuker

350Komponentenbasierte Software-Entwicklung

Sicheres JSF (8/17) - JSF-Konfiguration web.xml [2/3]

<<<<securitysecuritysecuritysecurity----constraintconstraintconstraintconstraint>>>><display<display<display<display----name>C2</displayname>C2</displayname>C2</displayname>C2</display----name>name>name>name><web<web<web<web----resourceresourceresourceresource----collectioncollectioncollectioncollection>>>>

<web<web<web<web----resourceresourceresourceresource----name>Editierschutz</webname>Editierschutz</webname>Editierschutz</webname>Editierschutz</web----resourceresourceresourceresource----name>name>name>name><<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<urlurlurlurl----pattern>/pattern>/pattern>/pattern>/facesfacesfacesfaces/editieren/*<//editieren/*<//editieren/*<//editieren/*</urlurlurlurl----pattern>pattern>pattern>pattern><http<http<http<http----methodmethodmethodmethod>GET</http>GET</http>GET</http>GET</http----methodmethodmethodmethod>>>><http<http<http<http----methodmethodmethodmethod>POST</http>POST</http>POST</http>POST</http----methodmethodmethodmethod>>>>

</web</web</web</web----resourceresourceresourceresource----collectioncollectioncollectioncollection>>>><<<<authauthauthauth----constraintconstraintconstraintconstraint>>>>

<<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<rolerolerolerole----name>name>name>name>editierereditierereditierereditierer</</</</rolerolerolerole----name>name>name>name>

</</</</authauthauthauth----constraintconstraintconstraintconstraint>>>><user<user<user<user----datadatadatadata----constraintconstraintconstraintconstraint>>>>

<transport<transport<transport<transport----guaranteeguaranteeguaranteeguarantee>CONFIDENTIAL</transport>CONFIDENTIAL</transport>CONFIDENTIAL</transport>CONFIDENTIAL</transport----guaranteeguaranteeguaranteeguarantee>>>></user</user</user</user----datadatadatadata----constraintconstraintconstraintconstraint>>>>

</</</</securitysecuritysecuritysecurity----constraintconstraintconstraintconstraint> > > >

Prof. Dr. Stephan Kleuker

351

Sicheres JSF (9/17) - JSF-Konfiguration web.xml [3/4]

<<<<loginloginloginlogin----configconfigconfigconfig>>>><<<<authauthauthauth----methodmethodmethodmethod>FORM</>FORM</>FORM</>FORM</authauthauthauth----methodmethodmethodmethod>>>><<<<realmrealmrealmrealm----name>name>name>name>zugriffsRealmzugriffsRealmzugriffsRealmzugriffsRealm</</</</realmrealmrealmrealm----name>name>name>name><form<form<form<form----loginloginloginlogin----configconfigconfigconfig>>>>

<form<form<form<form----loginloginloginlogin----page>/page>/page>/page>/facesfacesfacesfaces////hinzufuegenhinzufuegenhinzufuegenhinzufuegen////login.xhtmllogin.xhtmllogin.xhtmllogin.xhtml</form</form</form</form----loginloginloginlogin----page>page>page>page><form<form<form<form----errorerrorerrorerror----page>/page>/page>/page>/facesfacesfacesfaces////loginError.xhtmlloginError.xhtmlloginError.xhtmlloginError.xhtml</form</form</form</form----errorerrorerrorerror----page>page>page>page>

</form</form</form</form----loginloginloginlogin----configconfigconfigconfig>>>></</</</loginloginloginlogin----configconfigconfigconfig> > > > <<<<securitysecuritysecuritysecurity----rolerolerolerole>>>>

<<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<rolerolerolerole----name>name>name>name>basisnutzerbasisnutzerbasisnutzerbasisnutzer</</</</rolerolerolerole----name>name>name>name>

</</</</securitysecuritysecuritysecurity----rolerolerolerole>>>><<<<securitysecuritysecuritysecurity----rolerolerolerole>>>>

<<<<descriptiondescriptiondescriptiondescription/>/>/>/><<<<rolerolerolerole----name>name>name>name>editierereditierereditierereditierer</</</</rolerolerolerole----name>name>name>name>

</</</</securitysecuritysecuritysecurity----rolerolerolerole> > > >

Komponentenbasierte Software-Entwicklung

Art der Anmeldung (so sicher)

im Server; Verweis auf Nutzertabellen

Login und Login-Fehler-Seite

in glassfish-web.xml eingerichtete Rollen

Prof. Dr. Stephan Kleuker

352

Sicheres JSF (10/17) - JSF-Konfiguration web.xml [4/4]

<<<<errorerrorerrorerror----page>page>page>page><<<<errorerrorerrorerror----code>403</code>403</code>403</code>403</errorerrorerrorerror----code>code>code>code><<<<locationlocationlocationlocation>/>/>/>/facesfacesfacesfaces////fehler.xhtmlfehler.xhtmlfehler.xhtmlfehler.xhtml</</</</locationlocationlocationlocation>>>>

</</</</errorerrorerrorerror----page> page> page> page> <<<<errorerrorerrorerror----page>page>page>page>

<<<<errorerrorerrorerror----code>500</code>500</code>500</code>500</errorerrorerrorerror----code>code>code>code><<<<locationlocationlocationlocation>/>/>/>/facesfacesfacesfaces////fehler.xhtmlfehler.xhtmlfehler.xhtmlfehler.xhtml</</</</locationlocationlocationlocation>>>>

</</</</errorerrorerrorerror----page>page>page>page><<<<errorerrorerrorerror----page>page>page>page>

<<<<errorerrorerrorerror----code>404</code>404</code>404</code>404</errorerrorerrorerror----code>code>code>code><<<<locationlocationlocationlocation>/>/>/>/facesfacesfacesfaces////loginError.xhtmlloginError.xhtmlloginError.xhtmlloginError.xhtml</</</</locationlocationlocationlocation>>>>

</</</</errorerrorerrorerror----page> page> page> page> </web</web</web</web----appappappapp>>>>

Komponentenbasierte Software-Entwicklung

pro Fehlerart eigene Seite einstellbar

Prof. Dr. Stephan Kleuker

353

Sicheres JSF (11/17) – Nutzeranalyse [1/2]

• Hinweis: Klasse nicht immer notwendig@@@@ManagedBeanManagedBeanManagedBeanManagedBean@@@@SessionScopedSessionScopedSessionScopedSessionScopedpublicpublicpublicpublic classclassclassclass Nutzer Nutzer Nutzer Nutzer implementsimplementsimplementsimplements SerializableSerializableSerializableSerializable {{{{

private String private String private String private String namenamenamename;;;;private private private private booleanbooleanbooleanboolean editierereditierereditierereditierer;;;;private private private private booleanbooleanbooleanboolean basisnutzerbasisnutzerbasisnutzerbasisnutzer;;;;

publicpublicpublicpublic booleanbooleanbooleanboolean isEditisEditisEditisEdit() {() {() {() {leseNutzerleseNutzerleseNutzerleseNutzer();();();();returnreturnreturnreturn editierereditierereditierereditierer;;;;

}}}}

publicpublicpublicpublic booleanbooleanbooleanboolean isBasisisBasisisBasisisBasis() {() {() {() {leseNutzerleseNutzerleseNutzerleseNutzer();();();();returnreturnreturnreturn basisnutzerbasisnutzerbasisnutzerbasisnutzer;;;;

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

354

Sicheres JSF (12/17) - Nutzeranalyse [2/2]

private private private private voidvoidvoidvoid leseNutzerleseNutzerleseNutzerleseNutzer() {() {() {() {ifififif ((((namenamenamename == null) {== null) {== null) {== null) {

ExternalContextExternalContextExternalContextExternalContext ectxectxectxectx = = = = FacesContextFacesContextFacesContextFacesContext....getCurrentInstancegetCurrentInstancegetCurrentInstancegetCurrentInstance().().().().getExternalContextgetExternalContextgetExternalContextgetExternalContext();();();();

namenamenamename = = = = ectx.getRemoteUserectx.getRemoteUserectx.getRemoteUserectx.getRemoteUser();();();();ifififif ((((ectx.isUserInRoleectx.isUserInRoleectx.isUserInRoleectx.isUserInRole("("("("editierereditierereditierereditierer")) {")) {")) {")) {

editierereditierereditierereditierer = = = = truetruetruetrue;;;;}}}}ifififif ((((ectx.isUserInRoleectx.isUserInRoleectx.isUserInRoleectx.isUserInRole("("("("basisnutzerbasisnutzerbasisnutzerbasisnutzer")) {")) {")) {")) {

basisnutzerbasisnutzerbasisnutzerbasisnutzer = = = = truetruetruetrue;;;;}}}}

}}}}}}}}

publicpublicpublicpublic String String String String getNamegetNamegetNamegetName() {() {() {() {leseNutzerleseNutzerleseNutzerleseNutzer();();();();returnreturnreturnreturn namenamenamename;;;;

}}}}}}}}Komponentenbasierte Software-

Entwicklung

Prof. Dr. Stephan Kleuker

355

Sicheres JSF (13/17) - Startseite

<<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="Ausloggen" ="Ausloggen" ="Ausloggen" ="Ausloggen" actionactionactionaction="#{="#{="#{="#{module.ausloggenmodule.ausloggenmodule.ausloggenmodule.ausloggen((((nutzernutzernutzernutzer)}"/>)}"/>)}"/>)}"/>

// in // in // in // in ModulBeanModulBeanModulBeanModulBeanpublicpublicpublicpublic String ausloggen(Nutzer String ausloggen(Nutzer String ausloggen(Nutzer String ausloggen(Nutzer nutzernutzernutzernutzer) {) {) {) {

System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((nutzernutzernutzernutzer););););ExternalContextExternalContextExternalContextExternalContext ectxectxectxectx = = = = FacesContextFacesContextFacesContextFacesContext

....getCurrentInstancegetCurrentInstancegetCurrentInstancegetCurrentInstance().().().().getExternalContextgetExternalContextgetExternalContextgetExternalContext();();();();ectx.invalidateSessionectx.invalidateSessionectx.invalidateSessionectx.invalidateSession();();();();nutzernutzernutzernutzer = null;= null;= null;= null;returnreturnreturnreturn "/"/"/"/hinzufuegenhinzufuegenhinzufuegenhinzufuegen////index.xhtml?facesindex.xhtml?facesindex.xhtml?facesindex.xhtml?faces----redirectredirectredirectredirect====truetruetruetrue"; "; "; ";

}}}}

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

356

<<<<h:columnh:columnh:columnh:column renderedrenderedrenderedrendered="#{="#{="#{="#{nutzer.editnutzer.editnutzer.editnutzer.edit}">}">}">}"><<<<f:facetf:facetf:facetf:facet namenamenamename="="="="headerheaderheaderheader">">">">

<<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Bearbeitung"/>="Bearbeitung"/>="Bearbeitung"/>="Bearbeitung"/></</</</f:facetf:facetf:facetf:facet>>>><<<<h:commandLinkh:commandLinkh:commandLinkh:commandLink valuevaluevaluevalue="Editieren" ="Editieren" ="Editieren" ="Editieren"

actionactionactionaction="#{="#{="#{="#{module.editierenmodule.editierenmodule.editierenmodule.editieren(m)}"/>(m)}"/>(m)}"/>(m)}"/></</</</h:columnh:columnh:columnh:column>>>>

Sicheres JSF (14/17) – uebersicht.xhtml

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

357Komponentenbasierte Software-Entwicklung

Sicheres JSF (15/17) - login.xhtml<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE ...><!DOCTYPE ...><!DOCTYPE ...><!DOCTYPE ...><<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"

xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">"><<<<h:headh:headh:headh:head>>>>

<title>Einloggen</title><title>Einloggen</title><title>Einloggen</title><title>Einloggen</title></</</</h:headh:headh:headh:head>>>>

<<<<h:bodyh:bodyh:bodyh:body>>>><form <form <form <form namenamenamename="POST" ="POST" ="POST" ="POST" actionactionactionaction="="="="j_security_checkj_security_checkj_security_checkj_security_check">">">">

Nutzer:<Nutzer:<Nutzer:<Nutzer:<inputinputinputinput type="type="type="type="texttexttexttext" " " " namenamenamename="="="="j_usernamej_usernamej_usernamej_username" " " " valuevaluevaluevalue="" ="" ="" ="" sizesizesizesize="15" /><="15" /><="15" /><="15" /><brbrbrbr/>/>/>/>

Passwort:<Passwort:<Passwort:<Passwort:<inputinputinputinput type="type="type="type="texttexttexttext" " " " namenamenamename="="="="j_passwordj_passwordj_passwordj_password" " " " valuevaluevaluevalue="" ="" ="" ="" sizesizesizesize="15" /><="15" /><="15" /><="15" /><brbrbrbr/>/>/>/>

<<<<inputinputinputinput type="type="type="type="submitsubmitsubmitsubmit" " " " valuevaluevaluevalue="Anmelden" />="Anmelden" />="Anmelden" />="Anmelden" /></form></form></form></form>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Prof. Dr. Stephan Kleuker

358Komponentenbasierte Software-Entwicklung

Sicheres JSF (16/17) - loginError.xhtml

<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0

TransitionalTransitionalTransitionalTransitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd">

<<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">">

<<<<headheadheadhead>>>><title>Fehler</title><title>Fehler</title><title>Fehler</title><title>Fehler</title>

</</</</headheadheadhead>>>><<<<h:formh:formh:formh:form>>>>Passt nichtPasst nichtPasst nichtPasst nicht<<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="noch mal" ="noch mal" ="noch mal" ="noch mal"

actionactionactionaction="/="/="/="/hinzufuegenhinzufuegenhinzufuegenhinzufuegen////login.xhtmllogin.xhtmllogin.xhtmllogin.xhtml"/>"/>"/>"/></</</</h:formh:formh:formh:form>>>>

</</</</htmlhtmlhtmlhtml>>>>

Prof. Dr. Stephan Kleuker

359Komponentenbasierte Software-Entwicklung

Sicheres JSF (17/17) - fehler.xhml (hier unberechtigt)

<?<?<?<?xmlxmlxmlxml versionversionversionversion='1.0' ='1.0' ='1.0' ='1.0' encodingencodingencodingencoding='UTF='UTF='UTF='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE <!DOCTYPE <!DOCTYPE <!DOCTYPE htmlhtmlhtmlhtml PUBLIC "PUBLIC "PUBLIC "PUBLIC "----//W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0 //W3C//DTD XHTML 1.0

TransitionalTransitionalTransitionalTransitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd">

<<<<htmlhtmlhtmlhtml xmlnsxmlnsxmlnsxmlns="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"="http://www.w3.org/1999/xhtml"xmlns:hxmlns:hxmlns:hxmlns:h="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/="http://java.sun.com/jsfjsfjsfjsf////htmlhtmlhtmlhtml">">">">

<<<<h:headh:headh:headh:head>>>><title>Au <title>Au <title>Au <title>Au weiaweiaweiaweia</title></title></title></title>

</</</</h:headh:headh:headh:head>>>><<<<h:bodyh:bodyh:bodyh:body>>>><<<<h:formh:formh:formh:form>>>><<<<h:outputTexth:outputTexth:outputTexth:outputText

valuevaluevaluevalue="Hey, #{nutzer.name}, Du kommst ="Hey, #{nutzer.name}, Du kommst ="Hey, #{nutzer.name}, Du kommst ="Hey, #{nutzer.name}, Du kommst nitnitnitnit rein "/>rein "/>rein "/>rein "/><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton valuevaluevaluevalue="zurück" ="zurück" ="zurück" ="zurück"

actionactionactionaction="#{="#{="#{="#{wahrheit.ausloggenwahrheit.ausloggenwahrheit.ausloggenwahrheit.ausloggen((((nutzernutzernutzernutzer)}"/>)}"/>)}"/>)}"/></</</</h:formh:formh:formh:form>>>>

</</</</h:bodyh:bodyh:bodyh:body>>>></</</</htmlhtmlhtmlhtml>>>>

Prof. Dr. Stephan Kleuker

360Komponentenbasierte Software-Entwicklung

Auch Fehler 500 abfangen (Session-Timeout)

Prof. Dr. Stephan Kleuker

361Komponentenbasierte Software-Entwicklung

Sicherer Datenverkehr

• Übertragungsart wählen, dann anmelden

hinzufuegen/index.xhtml

hinzufuegen/index.xhtml

hinzufuegen/index.xhtml

(login.xhtml)

Prof. Dr. Stephan Kleuker

362Komponentenbasierte Software-Entwicklung

Session-Kontrolle / Vision: systematischere Rechte

• meist sinnvoll: Nutzerdaten in Session-Objekt speichern (außer, wenn nur erlaubt / nicht erlaubt)

• Bei erster Nutzung weitere Nutzerdaten setzen (evtl. jedes Attribut auf null prüfen, dann Boolean statt boolean)

• Bei Logout Nutzer-Objekt auf null setzen (!)

• Generell Session mit invalidateSessioninvalidateSessioninvalidateSessioninvalidateSession()()()() beenden

@@@@ManagedBeanManagedBeanManagedBeanManagedBean // Ausblick, wie es sein kann, noch nicht JSF// Ausblick, wie es sein kann, noch nicht JSF// Ausblick, wie es sein kann, noch nicht JSF// Ausblick, wie es sein kann, noch nicht JSF@@@@SessionScopedSessionScopedSessionScopedSessionScoped@@@@DeclareRolesDeclareRolesDeclareRolesDeclareRoles({"({"({"({"Chef","NormaloChef","NormaloChef","NormaloChef","Normalo"})"})"})"})publicpublicpublicpublic classclassclassclass Wahrheit {Wahrheit {Wahrheit {Wahrheit {

@@@@RolesAllowedRolesAllowedRolesAllowedRolesAllowed({"({"({"({"Chef","NormaloChef","NormaloChef","NormaloChef","Normalo"})"})"})"})publicpublicpublicpublic String String String String getWahrgetWahrgetWahrgetWahr(){(){(){(){returnreturnreturnreturn "Der Kunde ist König";"Der Kunde ist König";"Der Kunde ist König";"Der Kunde ist König";

}}}}

Prof. Dr. Stephan Kleuker

363

5.8 Weitere JSF-Möglichkeiten

• Graphische Elemente

• Konvertierung

• Nutzung von Listenern

Komponentenbasierte Software-Entwicklung

Prof. Dr. Stephan Kleuker

364Komponentenbasierte Software-Entwicklung

GUI-Spielereien - Boolesche Checkbox

<<<<h:formh:formh:formh:form>>>><<<<h:selectBooleanCheckboxh:selectBooleanCheckboxh:selectBooleanCheckboxh:selectBooleanCheckbox title="title="title="title="gratisprobegratisprobegratisprobegratisprobe""""

valuevaluevaluevalue="#{="#{="#{="#{guiKram.gratisguiKram.gratisguiKram.gratisguiKram.gratis}" />}" />}" />}" /><<<<h:outputTexth:outputTexth:outputTexth:outputText valuevaluevaluevalue="Wollen Sie es gratis?"/> <="Wollen Sie es gratis?"/> <="Wollen Sie es gratis?"/> <="Wollen Sie es gratis?"/> <brbrbrbr>>>><<<<h:commandButtonh:commandButtonh:commandButtonh:commandButton actionactionactionaction="./="./="./="./index.xhtmlindex.xhtmlindex.xhtmlindex.xhtml" " " " valuevaluevaluevalue="Sichern"/>="Sichern"/>="Sichern"/>="Sichern"/>

</</</</h:formh:formh:formh:form>>>>private private private private booleanbooleanbooleanboolean gratis;gratis;gratis;gratis;publicpublicpublicpublic voidvoidvoidvoid setGratissetGratissetGratissetGratis((((booleanbooleanbooleanboolean v){v){v){v){

gratis=v; gratis=v; gratis=v; gratis=v; System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("gratis: "+gratis);}("gratis: "+gratis);}("gratis: "+gratis);}("gratis: "+gratis);}

Prof. Dr. Stephan Kleuker

365Komponentenbasierte Software-Entwicklung

GUI-Spielereien - selectManyCheckBox (1/2)

importimportimportimport javax.faces.model.SelectItemjavax.faces.model.SelectItemjavax.faces.model.SelectItemjavax.faces.model.SelectItem;;;;publicpublicpublicpublic classclassclassclass GUIKramGUIKramGUIKramGUIKram {{{{private List<private List<private List<private List<SelectItemSelectItemSelectItemSelectItem> > > > listlistlistlist= = = = newnewnewnew ArrayListArrayListArrayListArrayList<<<<SelectItemSelectItemSelectItemSelectItem>();>();>();>();private String[] private String[] private String[] private String[] arrayarrayarrayarray={"={"={"={"Ute","Uwe","Urs","UtaUte","Uwe","Urs","UtaUte","Uwe","Urs","UtaUte","Uwe","Urs","Uta"};"};"};"};private private private private List<String> List<String> List<String> List<String> elementeelementeelementeelemente;;;;

publicpublicpublicpublic GUIKramGUIKramGUIKramGUIKram() {() {() {() {forforforfor(String s:array) (String s:array) (String s:array) (String s:array) list.addlist.addlist.addlist.add((((newnewnewnew SelectItemSelectItemSelectItemSelectItem(s));(s));(s));(s));

}}}}

publicpublicpublicpublic List<String> List<String> List<String> List<String> getElementegetElementegetElementegetElemente() {() {() {() {System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("("("("getgetgetget");");");");returnreturnreturnreturn elementeelementeelementeelemente;;;;

}}}}

publicpublicpublicpublic voidvoidvoidvoid setElementesetElementesetElementesetElemente(List<String> (List<String> (List<String> (List<String> e) {e) {e) {e) {elementeelementeelementeelemente = e;= e;= e;= e;System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println("("("("elementeelementeelementeelemente: "+: "+: "+: "+elementeelementeelementeelemente););););

} ...} ...} ...} ...

Prof. Dr. Stephan Kleuker

366Komponentenbasierte Software-Entwicklung

GUI-Spielereien - selectManyCheckBox (2/2)

<h:selectManyCheckbox id="nase" value="#{guiKram.elemente}"><h:selectManyCheckbox id="nase" value="#{guiKram.elemente}"><h:selectManyCheckbox id="nase" value="#{guiKram.elemente}"><h:selectManyCheckbox id="nase" value="#{guiKram.elemente}"><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/>

</h:selectManyCheckbox></h:selectManyCheckbox></h:selectManyCheckbox></h:selectManyCheckbox><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/>

Prof. Dr. Stephan Kleuker

367Komponentenbasierte Software-Entwicklung

GUI-Spielereien - selectManyMenu

<h:selectManyMenu id="nas2" value="#{guiKram.elemente}"><h:selectManyMenu id="nas2" value="#{guiKram.elemente}"><h:selectManyMenu id="nas2" value="#{guiKram.elemente}"><h:selectManyMenu id="nas2" value="#{guiKram.elemente}">

<f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/>

</h:selectManyMenu></h:selectManyMenu></h:selectManyMenu></h:selectManyMenu>

<h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/>

Prof. Dr. Stephan Kleuker

368Komponentenbasierte Software-Entwicklung

GUI-Spielereien - selectManyListBox

<h:selectManyListbox id="nas3" value="#{guiKram.elemente}"><h:selectManyListbox id="nas3" value="#{guiKram.elemente}"><h:selectManyListbox id="nas3" value="#{guiKram.elemente}"><h:selectManyListbox id="nas3" value="#{guiKram.elemente}"><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/><f:selectItems value="#{guiKram.list}"/>

</h:selectManyListbox></h:selectManyListbox></h:selectManyListbox></h:selectManyListbox><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/><h:commandButton action="./index.xhtml" value="Sichern"/>

Prof. Dr. Stephan Kleuker

369Komponentenbasierte Software-Entwicklung

GUI-Spielereien - selectOneRadio

<h:selectOneRadio id="nas4" value="#{guiKram.el}"><h:selectOneRadio id="nas4" value="#{guiKram.el}"><h:selectOneRadio id="nas4" value="#{guiKram.el}"><h:selectOneRadio id="nas4" value="#{guiKram.el}"><f:selectItems value="#{guiKram.list}" /><f:selectItems value="#{guiKram.list}" /><f:selectItems value="#{guiKram.list}" /><f:selectItems value="#{guiKram.list}" />

</h:selectOneRadio></h:selectOneRadio></h:selectOneRadio></h:selectOneRadio><h:commandButton action="save" value="Sichern"/><h:commandButton action="save" value="Sichern"/><h:commandButton action="save" value="Sichern"/><h:commandButton action="save" value="Sichern"/>

private String el;private String el;private String el;private String el;

public void setEl(String el) {public void setEl(String el) {public void setEl(String el) {public void setEl(String el) {

this.el = el;this.el = el;this.el = el;this.el = el;

System.out.println("el: "+el);System.out.println("el: "+el);System.out.println("el: "+el);System.out.println("el: "+el);

}}}}

Variante: el am Anfang setzen

analog:

selectOneMenu

selectOneListbox

Prof. Dr. Stephan Kleuker

370Komponentenbasierte Software-Entwicklung

Konvertierung: Datum (1/3)

<h:form><h:form><h:form><h:form><h:panelGrid columns="3" frame="border"><h:panelGrid columns="3" frame="border"><h:panelGrid columns="3" frame="border"><h:panelGrid columns="3" frame="border"><h:outputLabel for="da" value="Datum:"/><h:outputLabel for="da" value="Datum:"/><h:outputLabel for="da" value="Datum:"/><h:outputLabel for="da" value="Datum:"/><h:inputText id="da" value ="#{studi.start}"><h:inputText id="da" value ="#{studi.start}"><h:inputText id="da" value ="#{studi.start}"><h:inputText id="da" value ="#{studi.start}"><f:convertDateTime pattern ="dd.MM.yyyy"/><f:convertDateTime pattern ="dd.MM.yyyy"/><f:convertDateTime pattern ="dd.MM.yyyy"/><f:convertDateTime pattern ="dd.MM.yyyy"/>

</h:inputText></h:inputText></h:inputText></h:inputText><h:message for="da"/><h:message for="da"/><h:message for="da"/><h:message for="da"/><h:outputLabel value="Format:"/><h:outputLabel value="Format:"/><h:outputLabel value="Format:"/><h:outputLabel value="Format:"/><h:outputText value ="#{studi.start}"/><h:outputText value ="#{studi.start}"/><h:outputText value ="#{studi.start}"/><h:outputText value ="#{studi.start}"/><h:outputText value ="#{view.locale}" /><h:outputText value ="#{view.locale}" /><h:outputText value ="#{view.locale}" /><h:outputText value ="#{view.locale}" /><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><f:convertDateTime type ="date" /><f:convertDateTime type ="date" /><f:convertDateTime type ="date" /><f:convertDateTime type ="date" />

</h:outputText ></h:outputText ></h:outputText ></h:outputText ><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><f:convertDateTime type ="time" /><f:convertDateTime type ="time" /><f:convertDateTime type ="time" /><f:convertDateTime type ="time" />

</h:outputText ></h:outputText ></h:outputText ></h:outputText ><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><h:outputText value ="#{studi.start}"><f:convertDateTime pattern="ddd<f:convertDateTime pattern="ddd<f:convertDateTime pattern="ddd<f:convertDateTime pattern="ddd----MMMMMMMMMMMMMMMMMMMM----yy" />yy" />yy" />yy" />

</h:outputText ></h:outputText ></h:outputText ></h:outputText ></h:panelGrid></h:panelGrid></h:panelGrid></h:panelGrid>

</h:form></h:form></h:form></h:form>

Prof. Dr. Stephan Kleuker

371Komponentenbasierte Software-Entwicklung

Konvertierung: Datum (2/3)

@ManagedBean@ManagedBean@ManagedBean@ManagedBean

@RequestScoped@RequestScoped@RequestScoped@RequestScoped

public class Studi {public class Studi {public class Studi {public class Studi {

private Date start;private Date start;private Date start;private Date start;

public Date getStart() {public Date getStart() {public Date getStart() {public Date getStart() {

return start;return start;return start;return start;

}}}}

public void setStart(Date start) {public void setStart(Date start) {public void setStart(Date start) {public void setStart(Date start) {

this.start = start;this.start = start;this.start = start;this.start = start;

}}}}

}}}}

Prof. Dr. Stephan Kleuker

372Komponentenbasierte Software-Entwicklung

Konvertierung: Datum (3/3)

Datenübertragung schon durch Drücken von <Return>, wg. Converter

Prof. Dr. Stephan Kleuker

373Komponentenbasierte Software-Entwicklung

Konzept Konvertierung

• für Standardtypen findet automatisch eine Konvertierung mit Prüfung und eventueller Fehlermeldung statt (int)

• Man kann für Standarddatentypen einige Parameter zur Konvertierung ergänzen

• Generell besteht die Möglichkeit, eigene Konvertierer in XHTML-Seite einzubinden

• Konvertierer müssen Interfaces berücksichtigen

• Ziel: Konvertierung in zugehöriger Bean, möglichst wenig Aufwand auf Darstellungsseite

• Thema bietet sich zur Vertiefung an

Prof. Dr. Stephan Kleuker

374Komponentenbasierte Software-Entwicklung

Beispiel: Nutzung von Listenern (1/3)

<?xml version='1.0' encoding='UTF<?xml version='1.0' encoding='UTF<?xml version='1.0' encoding='UTF<?xml version='1.0' encoding='UTF----8' ?>8' ?>8' ?>8' ?><!DOCTYPE html PUBLIC "<!DOCTYPE html PUBLIC "<!DOCTYPE html PUBLIC "<!DOCTYPE html PUBLIC "----//W3C//DTD XHTML 1.0 Transitional//EN" //W3C//DTD XHTML 1.0 Transitional//EN" //W3C//DTD XHTML 1.0 Transitional//EN" //W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1"http://www.w3.org/TR/xhtml1/DTD/xhtml1----transitional.dtd">transitional.dtd">transitional.dtd">transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"<html xmlns="http://www.w3.org/1999/xhtml"<html xmlns="http://www.w3.org/1999/xhtml"<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/html">xmlns:h="http://java.sun.com/jsf/html">xmlns:h="http://java.sun.com/jsf/html">xmlns:h="http://java.sun.com/jsf/html"><h:head><h:head><h:head><h:head><title>Facelet Title</title><title>Facelet Title</title><title>Facelet Title</title><title>Facelet Title</title>

</h:head></h:head></h:head></h:head><h:body><h:body><h:body><h:body><h:form><h:form><h:form><h:form><h:messages globalOnly="true" layout="table"/><h:messages globalOnly="true" layout="table"/><h:messages globalOnly="true" layout="table"/><h:messages globalOnly="true" layout="table"/><h:panelGrid columns="2"><h:panelGrid columns="2"><h:panelGrid columns="2"><h:panelGrid columns="2"><h:commandButton id="c1" action="#{ac.listen}" value="c1"/><h:commandButton id="c1" action="#{ac.listen}" value="c1"/><h:commandButton id="c1" action="#{ac.listen}" value="c1"/><h:commandButton id="c1" action="#{ac.listen}" value="c1"/><h:commandButton id="c2" action="#{ac.listen}" value="c2"/><h:commandButton id="c2" action="#{ac.listen}" value="c2"/><h:commandButton id="c2" action="#{ac.listen}" value="c2"/><h:commandButton id="c2" action="#{ac.listen}" value="c2"/><h:commandButton id="c3" action="./index.xhtml" <h:commandButton id="c3" action="./index.xhtml" <h:commandButton id="c3" action="./index.xhtml" <h:commandButton id="c3" action="./index.xhtml"

actionListener="#{ac.listen}" value="c3"/>actionListener="#{ac.listen}" value="c3"/>actionListener="#{ac.listen}" value="c3"/>actionListener="#{ac.listen}" value="c3"/><h:commandButton id="c4" action="./index.xhtml" <h:commandButton id="c4" action="./index.xhtml" <h:commandButton id="c4" action="./index.xhtml" <h:commandButton id="c4" action="./index.xhtml"

actionListener="#{ac.listen}" value="c4"/>actionListener="#{ac.listen}" value="c4"/>actionListener="#{ac.listen}" value="c4"/>actionListener="#{ac.listen}" value="c4"/></h:panelGrid></h:panelGrid></h:panelGrid></h:panelGrid>

</h:form> </h:body> </html></h:form> </h:body> </html></h:form> </h:body> </html></h:form> </h:body> </html>

Prof. Dr. Stephan Kleuker

375Komponentenbasierte Software-Entwicklung

Beispiel: Nutzung von Listenern (2/3)

@ManagedBean(name="ac")@ManagedBean(name="ac")@ManagedBean(name="ac")@ManagedBean(name="ac")@NoneScoped@NoneScoped@NoneScoped@NoneScopedpublic class Knoeppke {public class Knoeppke {public class Knoeppke {public class Knoeppke {public String listen() { // zufällig gleicher Namepublic String listen() { // zufällig gleicher Namepublic String listen() { // zufällig gleicher Namepublic String listen() { // zufällig gleicher NameFacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();fc.addMessage(null, new FacesMessage("wer wars?"));fc.addMessage(null, new FacesMessage("wer wars?"));fc.addMessage(null, new FacesMessage("wer wars?"));fc.addMessage(null, new FacesMessage("wer wars?"));return "./index.xhtml";return "./index.xhtml";return "./index.xhtml";return "./index.xhtml";

}}}}

public void listen(ActionEvent e) {public void listen(ActionEvent e) {public void listen(ActionEvent e) {public void listen(ActionEvent e) {UIComponent u= e.getComponent();UIComponent u= e.getComponent();UIComponent u= e.getComponent();UIComponent u= e.getComponent();FacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();FacesContext fc = FacesContext.getCurrentInstance();fc.addMessage(null, new FacesMessage("es war "+u.getId()));fc.addMessage(null, new FacesMessage("es war "+u.getId()));fc.addMessage(null, new FacesMessage("es war "+u.getId()));fc.addMessage(null, new FacesMessage("es war "+u.getId()));

}}}}}}}}

Prof. Dr. Stephan Kleuker

376Komponentenbasierte Software-Entwicklung

Beispiel: Nutzung von Listenern (3/3)