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
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
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()));
}}}}}}}}
Top Related