5. JavaServer Faces (JSF)



Ähnliche Dokumente
5. JavaServer Faces(JSF)

Ansatz 1: Alle kennen Entitäten-Modell (1/2) Erinnerung: Eine Komponentenarchitektur-Variante. Ansatz 1: Alle kennen Entitäten-Modell (2/2)

5. JavaServer Faces (JSF) / JEE

EJB Beispiel. JEE Vorlesung 10. Ralf Gitzel

Session Beans & Servlet Integration. Ralf Gitzel ralf_gitzel@hotmail.de

JBoss Seam. Ein JEE 5 Webframework. Jörg Wüthrich Infopoint, 4. Februar 2009

Programmierung von Client/Server- Anwendungen

Sicherheit. letzten beiden Punkte typischerweise durch Verschlüsselung realisiert. Komponentenbasierte Software Entwicklung. Prof. Dr.

Standardattribut rendered(2/3) - JSF-Seite. Standardattribut rendered(1/3) Strukturierung mit panelgrid/ Kommentare. Standardattribut rendered(3/3)

Der lokale und verteilte Fall

OP-LOG

JSP Grundlagen. JEE Vorlesung Teil 5. Ralf Gitzel

Erstellung eines Frameworks für Shop Systeme im Internet auf Basis von Java

Java - Webapplikationen

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

WEBAPPLIKATIONEN MIT PHP. Wo gibt es Hilfe? Wie fang ich an?

4. Servlets Ein kleiner Einstieg. Kurze Java Historie. Erinnerung: Internet Anwendungen. Konzept eines Seitenaufrufs

Erfahrungen und Erkenntnisse. Klaus Richarz, HBT GmbH

Web-Kürzel. Krishna Tateneni Yves Arrouye Deutsche Übersetzung: Stefan Winter

Inhalt. 1 Einleitung AUTOMATISCHE DATENSICHERUNG AUF EINEN CLOUDSPEICHER

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 16: 3-Schichten-Architektur 1 Fachkonzept - GUI

Fehleingaben im nullten Beispiel (2/2) 5.3 Validierung/ Fehleingaben im nullten Beispiel (1/2) Ausgaben beim Drücken von Abschicken

Faclets. Eine alternative View Technologie um JSF Applikationen OHNE JSP zu entwickeln Wird unter java.net gehostet Open Source, CDDL Lizenz

Workshop Java Webentwicklung Einführung in Hibernate. Ulrich Stärk

Konfigurationslanleitung für J2EE und Eclipse im KBS-Pool

Multimedia im Netz. Wintersemester 2011/12. Übung 10. Betreuer: Verantwortlicher Professor: Sebastian Löhmann. Prof. Dr.

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Es wird das Struts <html:option> Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht.

4. JavaServer Faces (JSF) / JEE

Design anpassen eine kurze Einführung

Meldung Lokale Anwendung inkompatibel oder Microsoft Silverlight ist nicht aktuell bei Anmeldung an lokal gespeicherter RWE SmartHome Anwendung

Einrichten des IIS für VDF WebApp. Einrichten des IIS (Internet Information Server) zur Verwendung von Visual DataFlex Web Applications

HTML5. Wie funktioniert HTML5? Tags: Attribute:

Kleines Handbuch zur Fotogalerie der Pixel AG

.htaccess HOWTO. zum Schutz von Dateien und Verzeichnissen mittels Passwortabfrage

Seite 1. Abbildung 1: Einrichtung der Datenbank

Folgende Voraussetzungen für die Konfiguration müssen erfüllt sein:

WebService in Java SE und EE

Eine Anwendung mit InstantRails 1.7

Nathan Burgener. Design by Contract. Modul SWE

Multimedia im Netz Wintersemester 2012/13

JSP und Servlet Programmierung

OWASP Stammtisch München Sep 2014 XSS und andere Sicherheitslücken aus der Perspektive des Programmcodes

Die Installation des GeoShop Redirector für IIS (Internet Information Server, Version 4.0, 5.0 und 6.0) umfasst folgende Teilschritte:

Facebook I-Frame Tabs mit Papoo Plugin erstellen und verwalten

Architektur des agimatec-validation Frameworks

Design Patterns 2. Model-View-Controller in der Praxis

php Hier soll ein Überblick über das Erstellen von php Programmen gegeben werden. Inhaltsverzeichnis 1.Überblick Parameterübergabe...

SANDBOXIE konfigurieren

Lokale Installation von DotNetNuke 4 ohne IIS

Wichtige Hinweise zu den neuen Orientierungshilfen der Architekten-/Objektplanerverträge

Benutzerhandbuch. Leitfaden zur Benutzung der Anwendung für sicheren Dateitransfer.

Anleitung BFV-Widget-Generator

Anwendungsprotokolle: HTTP, POP, SMTP

EJBs und Sicherheit. Vorlesung: Applikationsserver. Prof. Dr. Ch. Reich furtwangen.de furtwangen.

Installation von NetBeans inkl. Glassfish Anwendungs-Server

Datenbanksysteme SS 2007

Anleitung zum Login. über die Mediteam- Homepage und zur Pflege von Praxisnachrichten

Installation des GeoShop Redirector für Apache (Stand ) ================================================================

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Enterprise Java Beans Einführung

Einrichtung des Cisco VPN Clients (IPSEC) in Windows7

KeePass Anleitung. 1.0Allgemeine Informationen zu Keepass. KeePass unter Windows7

Suche schlecht beschriftete Bilder mit Eigenen Abfragen

Übung: Verwendung von Java-Threads

Cookies. Krishna Tateneni Jost Schenck Übersetzer: Jürgen Nagel

Erste Erfahrungen mit NSASJ anhand der OmnivoBase Portierung. September 2013

Anwendung eines Enterprise Java Beans

Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten

Seite Out-Of-Band-Authentifizierung (OOBA) 8.1 Einleitung

Ihr Benutzerhandbuch für das IntelliWebs - Redaktionssystem

Application Frameworks

Anleitungen zum KMG- -Konto

Web 2.0 Software-Architekturen

ID VisitControl. Dokumentation Administration Equitania Software GmbH cmc Gruppe Seite 1

Im Folgenden wird Ihnen an einem Beispiel erklärt, wie Sie Excel-Anlagen und Excel-Vorlagen erstellen können.

Seite 1 von 14. Cookie-Einstellungen verschiedener Browser

Artikel Schnittstelle über CSV

robotron*e count robotron*e sales robotron*e collect Anmeldung Webkomponente Anwenderdokumentation Version: 2.0 Stand:

Datenbank-Verschlüsselung mit DbDefence und Webanwendungen.

Objektorientierte Programmierung

Web-Anwendungen mit JavaServer Faces

Praktikum Datenbanksysteme. Ho Ngoc Duc IFIS Universität zu Lübeck

Software Engineering Klassendiagramme Assoziationen

Sophia Business Leitfaden zur Administration

Mit der Maus im Menü links auf den Menüpunkt 'Seiten' gehen und auf 'Erstellen klicken.

Eclipse Equinox als Basis für Smart Client Anwendungen. Christian Campo, compeople AG, Java Forum Stuttgart 2007

Übungen zur Softwaretechnik

Schlussbewertung FB VI SOFTWAREPROJEKT II WS 09/10 TEAM. Alexander Kalden Dominik Eckelmann Marcel Pierry Julian Heise Besha Taher

Workshop Java Webentwicklung Tapestry. Ulrich Stärk

Ein Ausflug zu ACCESS

Java Script für die Nutzung unseres Online-Bestellsystems

Bedienungsanleitung für den SecureCourier

Flowy Apps erzählt eine kurze Geschichte über REDS. Remotely Encrypted Distributed Storage

Diese Ansicht erhalten Sie nach der erfolgreichen Anmeldung bei Wordpress.

Struts 2 Das Imperium schlägt zurück?

Installation des edu- sharing Plug- Ins für Moodle

Einstellungen im Internet-Explorer (IE) (Stand 11/2013) für die Arbeit mit IOS2000 und DIALOG

PHP - Projekt Personalverwaltung. Erstellt von James Schüpbach

Transkript:

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-SessionBeansund 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 246

Literatur E.Burns, C. Schalk, JavaServer Faces 2.0: The Complete Reference, Mc Graw Hill, New York, 2010 M. Marinschek, M. Kurz, G. Müllan, JavaServerFaces2.0, dpunkt, Heidelberg, 2010 (im Wesentlichen auch: http://tutorials.irian.at/jsf/semistatic/introduction.html) D. Geary, C. Horstmann, Core JavaServerFaces, 3. Auflage, Prentice Hall, USA, 2010 K. Ka IokTong, Beginning JSF 2 APIs and JBossSeam, Apress, Berkeley, USA, 2009 Standard: Sun, JSR 314: JavaServerFaces 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 247

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! 248

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 249

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 250

Typische splattformen (Ausschnitt).Net / Microsoft ASP.Net(ActiveServer 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 WidgetToolset), SW einmal in Java schreiben, dann individuell für Browser in Javascript übersetzen JavaFX, eigene Sprache nutzt im Browser JRE Meinung: Silverlight und JavaFXgegenüber HTML5 und aktuell noch Flash immer im Nachteil 251

Konzept eines Seitenaufrufs Client HTTP-Request HTTP-Response mit HTML-Datei im Body HTML (Hypertext Markup Language) Web- Container Application Server Auszeichnungssprache mit festgelegten tags zum Aufbau der Ausgabe Ebene 3/4 typisch TCP/IP, Session Ebene 5: HHTP, Darstellungsebene 6: HTML, Programmebene 7: JVM EJB- Container 252

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 253

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 254

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) 255

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) 256

Konzeptübersicht Web-Seite in XHTML Input-Komponente beschrieben in XHTML... Web-Seite in XHTML Output-Komponente beschrieben in XHTML... event leitet auf Folgeseite liest Modell Java-Programm im Container im Server 257

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 boarder korrekte XML-Syntax: <br br/> />nicht <br br> generell saubere Terminierung <input... /> boarder="7" 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 258

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 required="true"/> <h:outputtext id="omname" value="#{modul.name"/> Kontakt zum Java-Programm über Methodenaufrufe (lesend und aufrufend, z. B. modul.setname(...), modul.getname() große Komponenten können aus kleineren komponiert werden 259

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 260

Nulltes JSF-Beispiel (2/11) - Start index.xhtml <?xml version='1.0' encoding='utf ='UTF-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/ ="http://java.sun.com/jsf jsf/html html"> <h:head h:head> <title>moduleingabetitle> h:head h:head> <h:body h:body> <h:form h:form> <h:outputtext value="modulname "/> <h:inputtext id=" ="mname mname" value="#{modul.name" required=" ="true true"/>< "/><br br/> <h:outputtext value="modulnummer "/> <h:inputtext id=" ="mnr mnr" value="#{modul.nr" required=" ="true true"/>< "/><br br/> <h:commandbutton value="abschicken" action="#{ ="#{modul.uebernehmen modul.uebernehmen"/> h:form h:form> h:body h:body> html html> 261

Nulltes JSF-Beispiel (3/11) - Analyse der Startseite Einbinden der JSF-Bibliotheken <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/ ="http://java.sun.com/jsf jsf/html html" xmlns:f ="http://java.sun.com/jsf jsf/core core" > Nutzung von Standard XHTML (vereinfacht, da so als Standardnamensraum gesetzt) enge Verwandtschaft HTML zu XHTML (<h:form>) für value="#{modul.name" offene Fragen: was ist modul? (-> ManagedBean) warum #?(Trennung von ausführbaren Elementen) was passiert bei modul.name? (set/getabhängig von in/out) Ausblick: action="#{ Handling (Methodenaufruf) ="#{modul.uebernehmen modul.uebernehmen" ", echtes Event- 262

Nulltes JSF-Beispiel (4/11) - Ausgabe ausgabe.xhtml <?xml version='1.0' encoding='utf ='UTF-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/ ="http://java.sun.com/jsf jsf/html html"> <h:head h:head> <title>modulausgabetitle> h:head h:head> <h:body h:body> <h:form h:form> <h:outputtext value="modulname: "/> <h:outputtext id=" ="mname mname" value="#{modul.name"/> <br br/> <h:outputtext value="modulnummer: "/> <h:outputtext id=" ="mnr mnr" value="#{modul.nr"/>< ="#{modul.nr"/><br br/> <h:commandbutton value="zur Eingabe" action="#{ ="#{modul.eingeben modul.eingeben"/> h:form h:form> h:body h:body> html html> 263

Nulltes JSF-Beispiel (5/11) - Managed Bean [1/3] package entities; import java.io.serializable; import javax.faces.bean.managedbean; import javax.faces.bean.requestscoped; @ManagedBean ManagedBean(name name=" ="modul modul") @RequestScoped public class Modul implements Serializable { private static final long serialversionuid = 1L; private int nr; private String name; public Modul(){ public Modul(int nr, String name) { this.nr = nr; this.name = name; 264

Nulltes JSF-Beispiel (6/11) - Managed Bean [2/3] public String uebernehmen(){ return "./ausgabe.xhtml ausgabe.xhtml"; public String eingeben(){ return "./index.xhtml index.xhtml"; public String getname() { return name; public void setname(string name) { this.name = name; public int getnr() { return nr; public void setnr(int nr) { this.nr = nr; //Manövrieren 265

Nulltes JSF-Beispiel (7/11) - Managed Bean [3/3] @Override public boolean equals(object object) { if (object object==null!(object instanceof Modul)) return false; Modul other = (Modul) object; if (this.nr!= other.nr!this.name.equals this.name.equals(other.name)) return false; return true; @Override // generieren lassen public int hashcode() { int hash = 5; hash = 47 * hash + this.nr; hash = 47 * hash + (this.name!= null? this.name.hashcode() : 0); return hash; @Override public String tostring() {return name+"("+ +"("+nr nr+")"; 266

267 Nulltes JSF-Beispiel (8/11) - web.xml [1/2] Konfigurationsdatei für Servlets (hier benötigt) sun-web.xml ist Glassfish-spezifische Konfiguratonsdatei <? <? <? <?xml xml xml xml version version version version="1.0" ="1.0" ="1.0" ="1.0" encoding encoding encoding encoding="utf ="UTF ="UTF ="UTF-8"?> 8"?> 8"?> 8"?> <web <web <web <web-app app app app version version version version="3.0" ="3.0" ="3.0" ="3.0" xmlns xmlns xmlns xmlns="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/xml xml xml xml/ns ns ns ns/javaee javaee javaee javaee" xmlns:xsi xmlns:xsi xmlns:xsi xmlns: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:schemalocation xsi:schemalocation xsi:schemalocation xsi:schemalocation="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/xml xml xml xml/ns ns ns ns/javaee javaee javaee javaee http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> app_3_0.xsd"> app_3_0.xsd"> app_3_0.xsd"> <context context context context-param param param param> <param param param param-name> name> name> name>javax.faces.project_stage javax.faces.project_stage javax.faces.project_stage javax.faces.project_stage param param param param-name> name> name> name> <param param param param-value value value value>development >Development >Development >Developmentparam param param param-value value value value> context context context context-param param param param> <servlet servlet servlet servlet> <servlet servlet servlet servlet-name> name> name> name>faces Faces Faces Faces Servlet Servlet Servlet Servletservlet servlet servlet servlet-name> name> name> name> <servlet servlet servlet servlet-class class class class>javax.faces.webapp.facesservlet javax.faces.webapp.facesservlet javax.faces.webapp.facesservlet javax.faces.webapp.facesservlet servlet servlet servlet servlet-class class class class> <load load load load-on on on on-startup>1 startup>1 startup>1 startup>1load load load load-on on on on-startup> startup> startup> startup> servlet servlet servlet servlet>

268 Nulltes JSF-Beispiel (9/11) - web.xml [2/2] <servlet servlet servlet servlet-mapping mapping mapping mapping> <servlet servlet servlet servlet-name> name> name> name>faces Faces Faces Faces Servlet Servlet Servlet Servletservlet servlet servlet servlet-name> name> name> name> <url url url url-pattern>/ pattern>/ pattern>/ pattern>/faces faces faces faces/* /* /* /*url url url url-pattern> pattern> pattern> pattern> servlet servlet servlet servlet-mapping mapping mapping mapping> <session session session session-config config config config> <session session session session-timeout> timeout> timeout> timeout> 30 30 30 30 session session session session-timeout> timeout> timeout> timeout> session session session session-config config config config> <welcome welcome welcome welcome-file file file file-list> list> list> list> <welcome welcome welcome welcome-file> file> file> file>faces faces faces faces/index.xhtml index.xhtml index.xhtml index.xhtml welcome welcome welcome welcome-file> file> file> file> welcome welcome welcome welcome-file file file file-list> list> list> list> web web web web-app app app app> in sun-web.xml steht u. a. <context context context context-root root root root>/jsfspielerei2 >/JSFSpielerei2 >/JSFSpielerei2 >/JSFSpielerei2context context context context-root root root root>

Nulltes JSF-Beispiel (10/11) - Projektstruktur 269

Nulltes JSF-Beispiel (11/11) - Ergebnis 270

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 271

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: <context context-param param> <param param-name> name>javax.faces.state_saving_method javax.faces.state_saving_method param param-name> <param param-value value>client client param param-value value> context context-param param> Anmerkung: fehlt systematische Fehleranalyse: NetBeans 7.2, Glassfish3.1.2, MS IE 9, MS IE 9 Nutzereinstellungen, Win7 x64, 272

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 public String uebernehmen(){ return "./ausgabe.xhtml?faces ausgabe.xhtml?faces-redirect redirect=true true"; public String eingeben(){ return "./index.xhtml?faces index.xhtml?faces-redirect redirect=true true"; 273

Basisprinzip der Applikationssteuerung Im Controller: Aufruf einer Methode ohne Parameter vom Rückgabetyp String <h:commandbutton value="abschicken" Im Modell: public String uebernehmen(){ return "./ausgabe.xhtml"; action="#{modul.uebernehmen"/> 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 274

Lebensdauer von Informationen (scope) Request View Session Application nur für einen solange für eine solange Zeit Aufruf Nutzer auf Nutzer- aktuelles (auch für Applikationsseiten bleibt läuft Sitzung Deployment Weiterleitung) Scope None passt sich Aufrufer-Scope an (default kein Leben) Anmerkung: Obwohl es verlockend ist, viele Informationen in Session oder Applicationzu legen, ist dies wgperformance verboten (wird gespeichert, evtl. passiviert, hat wilde Referenzen, Zugriff muss ggfls. synchronisiert werden) 275

Scope-Beispiel (1/5) - Bean-Klasse //@ManagedBean ManagedBean(name name = "modul modul") //@RequestScoped Modul als einfache Klasse (wichtig!) public class Modul implements Serializable {...// wie vorher @ManagedBean ManagedBean(name = "moduln moduln") @NoneScoped public class ModulNone extends Modul{ @ManagedBean ManagedBean(name = "modulr modulr") @RequestScoped public class ModulRequest extends Modul{ @ManagedBean ManagedBean(name = "moduls moduls") @SessionScoped public class ModulSession extends Modul{ @ManagedBean ManagedBean(name name = "modula modula") @ApplicationScoped public class ModulApplication extends Modul{ 276

Scope-Beispiel (2/5) - Ausschnitt index.xhtml <h:form h:form> <h:panelgrid columns="3" > <h:outputlabel for=" ="mnamen mnamen" value="modulname "/> <h:inputtext id=" ="mnamen mnamen" value="#{moduln.name"/> <h:message for=" ="mnamen mnamen" /> <h:outputlabel for=" ="mnrn mnrn" value="modulnummer "/> <h:inputtext id=" ="mnrn mnrn" value="#{moduln.nr"/> <h:message for=" ="mnrn mnrn" /> <h:outputlabel for=" ="mnamer mnamer" value="modulname "/> <h:inputtext id=" ="mnamer mnamer" value="#{modulr.name"/> <h:message for=" ="mnamer mnamer" /> <h:outputlabel for=" ="mnrr mnrr" value="modulnummer "/> <h:inputtext id=" ="mnrr mnrr" value="#{modulr.nr"/> <h:message for=" ="mnrr mnrr" /> <!-- auch moduls und modula --> <h:commandbutton value="abschicken" action="#{ ="#{modulr.uebernehmen modulr.uebernehmen"/> h:panelgrid h:panelgrid> 277

Scope-Beispiel (3/5) - Ausschnitt ausgabe.xhtml <h:form h:form> <h:messages globalonly=" ="true true"/> <h:outputtext value="modulname n: "/> <h:outputtext id=" ="mnamen mnamen" value="#{moduln.name"/> <br br/> <h:outputtext value="modulnummer n: "/> <h:outputtext id=" ="mnrn mnrn" value="#{moduln.nr"/>< ="#{moduln.nr"/><br br/> <h:outputtext value="modulname r: "/> <h:outputtext id=" ="mnamer mnamer" value="#{modulr.name"/> <br br/> <h:outputtext value="modulnummer r: "/> <h:outputtext id=" ="mnrr mnrr" value="#{modulr.nr"/>< ="#{modulr.nr"/><br br/> <h:commandbutton value="zur Eingabe" action="#{ ="#{modulr.eingeben modulr.eingeben"/>< "/><br br/> <!-- auch moduls und modula --> <h:commandbutton value="ausgabe wiederholen" action="#{ ="#{modulr.uebernehmen modulr.uebernehmen"/> h:form h:form> 278

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

Scope-Beispiel (5/5) - Zwei Nutzer Nutzer 2 Nutzer 1 Zeit 280

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") index.xhtml ausgabe.xhtml 281

282 Manövrieren vor JSF 2.0 - faces-config.xml 1/2 <? <? <? <?xml xml xml xml version version version version='1.0' ='1.0' ='1.0' ='1.0' encoding encoding encoding encoding='utf ='UTF ='UTF ='UTF-8'?> 8'?> 8'?> 8'?> <faces faces faces faces-config config config config version version version version="1.2" ="1.2" ="1.2" ="1.2" xmlns xmlns xmlns xmlns="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/xml xml xml xml/ns ns ns ns/javaee javaee javaee javaee" xmlns:xsi xmlns:xsi xmlns:xsi xmlns: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:schemalocation xsi:schemalocation xsi:schemalocation xsi:schemalocation="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/ ="http://java.sun.com/xml xml xml xml/ns ns ns ns/javaee javaee javaee javaee http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"> facesconfig_1_2.xsd"> facesconfig_1_2.xsd"> facesconfig_1_2.xsd"> <navigation navigation navigation navigation-rule rule rule rule> <from from from from-view view view view-id id id id>/ >/ >/ >/index.xhtml index.xhtml index.xhtml index.xhtml from from from from-view view view view-id id id id> <navigation navigation navigation navigation-case case case case> <from from from from-outcome outcome outcome outcome>anzeigen >ANZEIGEN >ANZEIGEN >ANZEIGENfrom from from from-outcome outcome outcome outcome> <to to to to-view view view view-id id id id>/ >/ >/ >/ausgabe.xhtml ausgabe.xhtml ausgabe.xhtml ausgabe.xhtml to to to to-view view view view-id id id id> navigation navigation navigation navigation-case case case case> navigation navigation navigation navigation-rule rule rule rule> <navigation navigation navigation navigation-rule rule rule rule> <from from from from-view view view view-id id id id>/ >/ >/ >/ausgabe.xhtml ausgabe.xhtml ausgabe.xhtml ausgabe.xhtml from from from from-view view view view-id id id id> <navigation navigation navigation navigation-case case case case> <from from from from-outcome outcome outcome outcome>eingeben >EINGEBEN >EINGEBEN >EINGEBENfrom from from from-outcome outcome outcome outcome> <to to to to-view view view view-id id id id>/ >/ >/ >/ index.xhtml index.xhtml index.xhtml index.xhtml to to to to-view view view view-id id id id> navigation navigation navigation navigation-case case case case> navigation navigation navigation navigation-rule rule rule rule>

Manövrieren vor JSF 2.0 - Managed Bean // statt durch Annotationen können Beans auch in faces- // config.xml angelegt werden public class Modul implements Serializable { private static final long serialversionuid = 1L; private int nr; private String name; // fehlt: get- und set-methoden für Exemplarvariablen public Modul(){ public String uebernehmen(){ //Action-Methode // Zugriff auf Exemplarvariablen möglich return "ANZEIGEN"; public String eingeben(){ // Zugriff auf Exemplarvariablen möglich return "EINGEBEN";... 283

Manövrieren vor JSF 2.0 - faces-config.xml 2/2 <managed-bean> <managed-bean bean-name>modulmanaged name>modulmanaged-bean bean-name> name> <managed-bean bean-class>entities.modulmanaged class>entities.modulmanaged-bean bean-class> <managed-bean bean-scope>requestmanaged scope>requestmanaged-bean bean-scope> managed-bean> faces-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 faces faces-config.xml config.xml config.xml bleibt trotzdem wichtig 284

Erinnerung: Konstanten in Programmen schlecht return "ANZEIGEN"; besser: Konstanten getrennt deklarieren public class Modul implements Serializable{ private final static string ANZEIGEN = "ANZEIGEN";... return ANZEIGEN; Alternativ: Klasse mit Konstanten package konstanten; public class Navigation{ public final static string ANZEIGEN = "ANZEIGEN";... return konstanten.navigation.anzeigen; sumgebungen erlauben dann einfache Suche und Änderung (Refactoring) 285

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") @SessionScoped public class Mojo { private boolean jo=true; public Mojo(){ public boolean getjo() {return jo; public void setjo(boolean jo) {this.jo = jo; public String change(){ jo=!jo; return "./index.xhtml"; 286

Standardattribut rendered (2/3) - JSF-Seite <?xml version='1.0' encoding='utf ='UTF-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/ ="http://java.sun.com/jsf jsf/html html"> <h:head h:head> <title>klickklacktitle> h:head h:head> <h:body h:body> <h:form id="f1"> <h:panelgrid id="p1" rendered="#{mo.jo"> <h:outputlabel value= HS rocks"/> h:panelgrid h:panelgrid> <h:panelgrid id="p2" rendered="#{!mo.jo"> <h:outputlabel value="os rocks"/> h:panelgrid h:panelgrid> <h:commandbutton action="#{ ="#{mo.change mo.change" value="press"/> h:form h:form> h:body h:body> html html> 287

288 Standardattribut rendered (3/3) <? <? <? <?xml xml xml xml version version version version='1.0' ='1.0' ='1.0' ='1.0' encoding encoding encoding encoding='utf ='UTF ='UTF ='UTF-8'?> 8'?> 8'?> 8'?> <faces faces faces faces-config config config config version version version version="1.2"...> ="1.2"...> ="1.2"...> ="1.2"...> <managed managed managed managed-bean bean bean bean> <managed managed managed managed-bean bean bean bean-name> name> name> name>mo mo mo mo managed managed managed managed-bean bean bean bean-name> name> name> name> <managed managed managed managed-bean bean bean bean-class class class class>entities.mojo entities.mojo entities.mojo entities.mojo managed managed managed managed-bean bean bean bean-class class class class> <managed managed managed managed-bean bean bean bean-scope scope scope scope>session session session session managed managed managed managed-bean bean bean bean-scope scope scope scope> managed managed managed managed-bean bean bean bean> faces faces faces faces-config config config config> oder in faces-config.xhtml

Strukturierung mit panelgrid / Kommentare mit h:panelgridkönnen einzelne Komponenten zu einem Block zusammengefasst und einheitlich behandelt werden (ähnlich zu JPanel in Swing) weiterhin kann durch columns="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 --%> 289

5.3 Validierung/ Fehleingaben im nullten Beispiel (1/2) Eingabe: Fehler wird automatisch unter der bleibender Seite ausgegeben j_idt7 ist interner Name, mnameist unsere iddes Eingabefeldes 290

Fehleingaben im nullten Beispiel (2/2) Anpassung des Projektstatus (oder Parameter löschen) in web.xml <context-param> <param-name>javax.faces.project_stageparam name>javax.faces.project_stageparam-name> <!-- <param-value>developmentparam value>developmentparam-value> --> <param-value>productionparam value>productionparam-value> context-param> Applikation bleibt auf der Seite, keine sichtbare Fehlermeldung im Server-Log: INFO: WARNUNG: FacesMessage(s) wurde(n) in die Warteschlange gestellt, aber möglicherweise nicht angezeigt. sourceid=j_idt7:mname[severity=(error 2), summary=(j_idt7:mname: Validierungs-Fehler: Wert wird benötigt.), detail=(j_idt7:mname: Validierungs-Fehler: Wert wird benötigt.)] 291

Direkte Validierungen - einige Möglichkeiten <h:form h:form> <h:panelgrid columns="3" > <h:outputlabel for=" ="mname mname" value="modulname "/> <h:inputtext id=" ="mname mname" value="#{modul.name" required=" ="true true" size="8" requiredmessage=" ="nich leer" validatormessage="4 Zeichen"> <f:validatelength minimum="4" maximum="4"/> h:inputtext h:inputtext> <h:message for=" ="mname mname" /> <h:outputlabel for=" ="mnr mnr" value="modulnummer "/> <h:inputtext id=" ="mnr mnr" value="#{modul.nr" required=" ="true true" requiredmessage="mach Zahl eh" size="4" convertermessage=" ="nomahle Zahl"/> <h:message for=" ="mnr mnr" /> <h:commandbutton value="abschicken" action="#{ ="#{modul.uebernehmen modul.uebernehmen"/> h:panelgrid h:panelgrid> h:form h:form> 292

Ausgaben beim Drücken von Abschicken 293

Globale Fehlermeldungen erzeugen und anzeigen public String uebernehmen() { if (name.equals name.equals("ooad")) { FacesContext ctxt = FacesContext.getCurrentInstance(); FacesMessage ms = new FacesMessage(); ms.setseverity(facesmessage.severity_error FacesMessage.SEVERITY_ERROR); ms.setsummary("ooad ist schon da"); ms.setdetail("ooad im Standard"); ctxt.addmessage(null, ms); return "ANZEIGEN"; //in ausgabe.xhtml <h:form h:form> <h:messages globalonly="true"/> <h:outputtext value="modulname Modulname: "/> 294

Validierer selbst gestrickt (1/2) public class Modul implements Serializable {... // Validierungsmethoden können beliebigen Namen haben, // müssen aber die folgende Signatur haben public void pruefe(facescontext context, UIComponent component, Object value) throws ValidatorException { if (((String) value). ).equals equals("ooad")) { throw new ValidatorException(new new FacesMessage( FacesMessage.SEVERITY_ERROR, "oweh oweh", "ole ole"));... 295

Validierer selbst gestrickt (2/2) in index.xhtml <h:panelgrid columns="3" > <h:outputlabel for=" ="mname mname" value="modulname "/> <h:inputtext id=" ="mname mname" value="#{modul.name" validator="#{ ="#{modul.pruefe modul.pruefe"/> <h:message for=" ="mname mname" /> 296

Erinnerung: Bean Validation nicht: Nutzer Oberfläche Java fachliche Ebene Datenzugriffsschicht DB besser: individuelle Datenvalidierung individuelle Datenvalidierung Java individuelle Datenvalidierung individuelle Datenvalidierung Nutzer Oberfläche fachliche Ebene Datenzugriffsschicht DB Datenmodell mit Validierungsregeln 297

Beispiel Bean-Validation (1/6) @ManagedBean ManagedBean(name name=" ="modul modul") @RequestScoped public class Modul implements Serializable { private static final long serialversionuid = 1L; @Min(value value=100, message="dreistellig") @Max(value value=999, message="dreistellig") private int nr; @NotNull @Modulnamenregel(verboten={"VHDL","PNP", groups={ ={validators.modulgroup.class validators.modulgroup.class) private String name; //... übliche Konstruktoren, get und set Hinweis: Implementierung des Validierersin Libraries benötigt (Klasseneigenschaften werden nicht unterstützt!?) 298

Beispiel Bean-Validation (2/6) @Target({ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = {ModulnamenregelValidator.class) @Documented public @interface Modulnamenregel { String message() default "Modul unerwuenscht"; Class<?>[] groups() default {; Class<? extends Payload>[] payload() default {; String[] verboten() default {; package validators; public interface ModulGroup { 299

Beispiel Bean-Validation (3/6) public class ModulnamenregelValidator implements ConstraintValidator<Modulnamenregel,String>{ private String[] niveau; public void initialize(modulnamenregel ca) { niveau=ca.verboten(); public boolean isvalid(string t, ConstraintValidatorContext cvc) { System.out.println("isValid"); for(string s:niveau) if(s.equals(t)){ cvc.buildconstraintviolationwithtemplate( "Modul in unerwuenschter Liste: " +Arrays.toString(niveau)).addConstraintViolation(); return false; return true; 300

Beispiel Bean-Validation (4/6) - index.xhtml <h:body h:body> <h:form h:form> <h:panelgrid columns="3" > <h:outputlabel for=" ="mname mname" value="modulname "/> <h:inputtext id=" ="mname mname" value="#{modul.name"> <f:validatebean disabled=" ="false false" validationgroups=" ="validators.modulgroup validators.modulgroup"/> h:inputtext h:inputtext> <h:message for=" ="mname mname" /> <h:outputlabel for=" ="mnr mnr" value="modulnummer "/> <h:inputtext id=" ="mnr mnr" value="#{modul.nr" /> <h:message for=" ="mnr mnr" /> <h:commandbutton value="abschicken" action="#{ ="#{modul.uebernehmen modul.uebernehmen"/> h:panelgrid h:panelgrid> h:form h:form> h:body h:body> 301

Beispiel Bean-Validation (5/6) 302

Beispiel Bean-Validation (6/6) 303

Ordentliche Softwarearchitektur JSF-Seite Seite <<managed-bean>> Controller Bean (Entität) #{controller.bearbeiten #{controller.bean.attribut #{controller.speichern 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) 304

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] 305

Verwaltung einer Modulliste (1/9) - Entität (Wdh) @Entity public class Modul implements Serializable { private static final long serialversionuid = 1L; @Id @GeneratedValue GeneratedValue(strategy = GenerationType.AUTO) private int id; private int nr; // so sind gleiche Nummern erlaubt private String name; @Version private int version; public Modul() { public Modul(int nr, String name) { this.nr = nr; this.name = name; // fehlen get- und set-methoden, equals über id 306

Verwaltung einer Modulliste (2/9) - Seitenstruktur 307

Verwaltung einer Modulliste (3/9) - Datenbank <?xml version="1.0" encoding="utf-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" instance" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="jsfmodulliste1mitjpapu" transaction-type="jta"> type="jta"> <provider>org.eclipse.persistence.jpa.persistenceprovider provider> <jta-data data-source>jsfmodul1jta source>jsfmodul1jta-data data-source> <exclude-unlisted unlisted-classes>falseexclude classes>falseexclude-unlisted unlisted-classes> <properties> <property name="eclipselink.ddl-generation" value="drop-and and-create create-tables"/> tables"/> properties> persistence-unit> persistence> 308

Verwaltung einer Modulliste (4/9) - Startseite <h:form id="f1"> <h:messages globalonly="true"/> <h:panelgrid columns="3" > <h:outputlabel for="mname" value="modulname "/> <h:inputtext id="mname" value="#{module.modul.name"/> <h:message for="mname" /> <h:outputlabel for="mnr" value="modulnummer "/> <h:inputtext id="mnr" value="#{module.modul.nr"/> <h:message for="mnr"/> <h:commandbutton value="abschicken" action="#{module.uebernehmen"/> h:panelgrid> <h:commandlink action="#{module.anzeigen" > <h:outputtext value="zur Modulübersicht"/> h:commandlink> h:form> 309

Verwaltung einer Modulliste (5/9) - Controller 1/3 @ManagedBean ManagedBean(name name=" ="module module") @SessionScoped public class ModuleController { @PersistenceUnit //wichtig, nicht selber erzeugen!!! private EntityManagerFactory emf; @Resource private UserTransaction utx; private List<Modul> module = new ArrayList<Modul>(); private Modul modul=new Modul(); private EntityManager em; private final String HINZUFUEGEN = "./index.xhtml index.xhtml"; private final String ANZEIGEN = "./uebersicht.xhtml uebersicht.xhtml"; private final String EINGEBEN = "./index.xhtml index.xhtml"; public ModuleController() { 310

Verwaltung einer Modulliste (6/9) - Controller 2/3 public Modul getmodul() {return modul; public void setmodul(modul modul) {this.modul = modul; public List<Modul> getmodule() {return module; public void setmodule(list<modul> module) {this.module = module; public String anzeigen() { em = emf.createentitymanager(); module= em.createquery("select m FROM Modul m",modul.class Modul.class).getResultList getresultlist(); em.close(); return ANZEIGEN; public String eingeben() { modul = new Modul(); return EINGEBEN; 311

Verwaltung einer Modulliste (7/9) - Controller 3/3 public String uebernehmen() { FacesContext ctxt = FacesContext.getCurrentInstance(); FacesMessage ms = new FacesMessage("Erfolgreich eingetragen"); try { em = emf.createentitymanager(); utx.begin(); em.persist(modul modul); module= em.createquery("select m FROM Modul m",modul.class Modul.class).getResultList getresultlist(); utx.commit(); finally { catch (Exception e) { if (em!= null) { try { em.close(); ms = new FacesMessage( e.getmessage()); utx.rollback(); ctxt.addmessage(null, ms); catch (Exception e2) { modul=new Modul(); ms = new FacesMessage( return HINZUFUEGEN; e2.getmessage()); 312

Verwaltung einer Modulliste (8/9) - Ergebnisseite 1/2 <h:form id="f2"> <h:messages globalonly="true"/> <h:panelgrid rendered="#{! ="#{!empty module.module"> <h:datatable value="#{ ="#{module.module module.module" var="m" border="8" frame="box" > <h:column > <f:facet name=" ="header header"> <h:outputtext value="nummer" /> f:facet f:facet> <h:outputlabel value="#{m.nr"/> h:column h:column> 313

Verwaltung einer Modulliste (9/9) - Ergebnisseite 2/2 <h:column h:column> <f:facet name=" ="header header"> <h:outputtext value="modulname" /> f:facet f:facet> <h:outputlabel value="#{m.name"/> h:column h:column> h:datatable h:datatable> h:panelgrid h:panelgrid> <h:commandlink action="#{ ="#{module.eingeben module.eingeben" > <h:outputtext value="zur Moduleingabe"/> h:commandlink h:commandlink> h:form h:form> 314

Projektaufbau 315

Einschub: Ausgabe von Sammlungen <h:datatable value="#{ ="#{module.module module.module" var="m"> datatableerlaubt die Datenaufbereitung einer Collectionin Tabellenform (Iteratorüber Daten mit getmodule(); Elemente in Variable m); grundlegende Darstellungsmöglichkeiten einstellbar Zur Ausgabe wird minimal <h:column h:column> benötigt Attribut firstfür erste Zeile und rows für Zeilenzahl 316

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: Context and Dependency Injection, CDI) 317

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 Nachrichtenablauf 318

EJB-Umsetzung (1/4) package ejb; import entities.modul; import java.util.list; import javax.ejb.stateless; import javax.persistence.entitymanager; import javax.persistence.persistencecontext; @Stateless public class Modulverwaltung { @PersistenceContext PersistenceContext(unitName = "vljsfmodullistemitejbpu vljsfmodullistemitejbpu") private EntityManager em; public void persist(object object) { em.persist(object object); //Exception weiterreichen public List<Modul> getmodule() { return em.createquery("select m FROM Modul m", Modul.class).getResultList getresultlist(); 319

EJB-Umsetzung (2/4) Teil 1/2 package view; import ejb.modulverwaltung; import entities.modul; import java.io.serializable; import java.util.list; import javax.ejb.ejb; import javax.faces.bean.managedbean; import javax.faces.bean.requestscoped; @ManagedBean ManagedBean(name name = "module module") @RequestScoped public class ModulBean implements Serializable { private static final long serialversionuid = 1L; private Modul modul = new Modul(); @EJB private Modulverwaltung mv; public ModulBean() { 320

EJB-Umsetzung (3/4) Teil 2/2 public List<Modul> getmodule() { return mv.getmodule(); public String uebernehmen() { try { mv.persist(modul modul); // modul = new Modul() nicht notwendig catch (Exception e) { // wie vorher mit FacesContext return "./uebersicht.xhtml uebersicht.xhtml"; public String eingeben() { return "./index.xhtml index.xhtml"; public String anzeigen() { return "./uebersicht.xhtml uebersicht.xhtml"; // get und set für this.modul 321

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: public class ModulBean implements Serializable { private static final long serialversionuid = 1L; private int nr; private String name; @EJB private Modulverwaltung mv; // Methoden anpassen, in index.html direkt module.nr 322

Projektstruktur 323

CDI JSF-Lösungen stark auf JSF-fokussiert, wie auf verwandte JEE-Techniken übertragen? JSR 299: Contexts and Dependency Injection for the Java TM 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 324

Beispiel: Modulverwaltung aus mehreren Schichten Web-Design (XHTML-Seiten) [unverändert] ManagedBean (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] 325

Umsetzung @Named Named(" ("moduldelegate moduldelegate") // flexibler als ManagedBean //(braucht beans.xml) @SessionScoped public class ModulDelegate implements Serializable { 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=uuk QX1tChV7Z7l1LFF4L9j_g&index=50&feature=plpp 326

5.6 Funktionale Erweiterung Interessante JSF-Elemente <f:facet name=" ="header header"> <h:outputtext value="nummer" /> f:facet f:facet> facet dient zur Ergänzung verschiedener anderer JSF- Elemente; Art der Ergänzung durch Attribut name festgelegt 327

Architekturvariante ab JSF 2.0 Grundidee: (fast) alle Objekte werden als ManagedBeans (mit unterschiedlichem Scope) aufgefasst ManagedBeanskönnen andere als Parameter in Methodenaufrufen (action-methoden) enthalten @ManagedBean ManagedBean(name = "a") @SessionScoped public class A {... private String mach(b b){ // kann b bearbeiten/nutzen nutzen return "String mit Pfad zur nächsten Seite";... @ManagedBean ManagedBean(name = "b") @RequestScoped public class B {... <h:commandlink value="bearbeitung Bearbeitung" action="#{a.mach a.mach(b)"/> 328

Kurze Diskussion der Architekturvarianten Klassischer Ansatz #{controller.bean.attribut controller.bean.attribut saubere Steuerungsklasse(n) Mehrfachpunktnotation sehr unüblich für Attribute neuer Ansatz ab JSF 2.0 <h:commandlink value="bearbeitung Bearbeitung" action="#{a.mach a.mach(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 329

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 330

Funktionalität ergänzen (2/6) - uebersicht.xhtml <h:datatable value="#{ ="#{module.module module.module" var="m" border="8" frame="box" >... <h:column h:column> <f:facet name=" ="header header"> <h:outputtext value="bearbeitung"/> f:facet f:facet> <h:commandlink action="#{ ="#{module.editieren module.editieren"> <h:outputtext value="editieren"/> <f:param name=" ="edit edit" value="#{m.id"/> h:commandlink h:commandlink> h:column h:column>... 331

Funktionalität ergänzen (3/6) - Persistierung @Stateless public class Modulverwaltung { @PersistenceContext PersistenceContext(unitName = "JSFModullisteAenderungPU JSFModullisteAenderungPU") private EntityManager em; public void persist(object object) { em.persist(object object); //Erinnerung Exceptions weitergegeben public void update(object object) { em.merge(object object); public Modul find(string id){ return em.find(modul.class Modul.class, Integer.parseInt(id id)); public List<Modul> getmodule() { return em.createquery("select m FROM Modul m", Modul.class).getResultList getresultlist(); 332

Funktionalität ergänzen (4/6) -Seite einbauen // in ModuleBean.java @SessionScoped // neu public class ModulBean implements Serializable { private String getrequestparameter(string par) { return FacesContext.getCurrentInstance().getExternalContext getexternalcontext().getrequestparametermap getrequestparametermap(). ().get get(par); //evtl. in Hilfsklasse auslagern public String editieren() { String mid = getrequestparameter(" ("edit edit"); modul = mv.find(mid mid); // Erinnerung @EJB Modulverwaltung return "./edit.xhtml edit.xhtml"; 333

Funktionalität ergänzen (5/6) - edit.xhtml <h:form h:form> <h:panelgrid columns="3"> <h:outputlabel value="interne ID "/> <h:outputlabel value="#{module.modul.id"/> <h:outputlabel value=" "/> <h:outputlabel for=" ="mname mname" value="modulname "/> <h:inputtext id=" ="mname mname" value="#{module.modul.name"/> <h:message for=" ="mname mname" /> <h:outputlabel for=" ="mnr mnr" value="modulnummer "/> <h:inputtext id=" ="mnr mnr" value="#{module.modul.nr"/> <h:message for=" ="mnr mnr"/> <h:commandbutton value="ändern" action="#{ ="#{module.aendern module.aendern"/> h:panelgrid h:panelgrid> <h:commandlink action="#{ ="#{module.anzeigen module.anzeigen" > <h:outputtext value="zur Modulübersicht"/> h:commandlink h:commandlink> h:form h:form> 334

Funktionalität ergänzen (6/6) - Ändern // in ModuleBean.java public String aendern() { try{ mv.update(modul modul); modul = new Modul(); catch (Exception e) { // TODO sinnvolle Fehlermeldung für JSF return "./uebersicht.xhtml uebersicht.xhtml"; // in uebernehmen() und eingeben() vor return ergänzen modul = new Modul(); 335

Beispielnutzung 1 2 3 4 5 6 336

Variante: JSF 2.0 ohne f:param <h:datatable value="#{module.module module.module" var="m" border="8" frame="box" >... <h:commandlink value="editieren Editieren" action="#{module.editieren module.editieren(m)"/> // in ModulBean.java public String editieren(modul m) { modul=m =m; return EDITIEREN; 337

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 338

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 Nutzer NC M Gruppe NC M 1 Rolle NC 339

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 340

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) 341

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 342

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) Nutzer username password Gruppen groupid usernme edna edna admin edna uwe uwe basic edna otto otto basic uwe 343

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

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

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 346

Sicheres JSF (5/17) - Projektstruktur 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 347

Sicheres JSF (6/17) - serverindividuelle Vorbereitung Rechte-Rollen werden mit konkreten Nutzern in Datei glassfish-web.xml (vorher sun-web.xml) umgesetzt <security security-role role-mapping> <role-name> name>basisnutzer basisnutzerrole role-name> <group-name>basicgroup name>basicgroup-name> security-role role-mapping> <security-role role-mapping> <role-name> name>editierer editiererrole role-name> <group-name>admingroup name>admingroup-name> security-role role-mapping> Gruppenname aus Datenbank (Spalte) Auch Nutzer (username) direkt eintragbar 348

349 <welcome welcome welcome welcome-file file file file-list> list> list> list> <welcome welcome welcome welcome-file> file> file> file>faces faces faces faces/hinzufuegen hinzufuegen hinzufuegen hinzufuegen/index.xhtml index.xhtml index.xhtml index.xhtml welcome welcome welcome welcome-file> file> file> file> welcome welcome welcome welcome-file file file file-list> list> list> list> <security security security security-constraint constraint constraint constraint> <display <display <display <display-name>c1display name>c1display name>c1display name>c1display-name> name> name> name> <web <web <web <web-resource resource resource resource-collection collection collection collection> <web <web <web <web-resource resource resource resource-name>basisschutzweb name>basisschutzweb name>basisschutzweb name>basisschutzweb-resource resource resource resource-name> name> name> name> <description description description description/> /> /> /> <url url url url-pattern>/ pattern>/ pattern>/ pattern>/faces faces faces faces/hinzufuegen hinzufuegen hinzufuegen hinzufuegen/* /* /* /*url url url url-pattern> pattern> pattern> pattern> <http <http <http <http-method method method method>gethttp >GEThttp >GEThttp >GEThttp-method method method method> <http <http <http <http-method method method method>posthttp >POSThttp >POSThttp >POSThttp-method method method method> web web web web-resource resource resource resource-collection collection collection collection> <auth auth auth auth-constraint constraint constraint constraint> <description description description description/> /> /> /> <role role role role-name> name> name> name>basisnutzer basisnutzer basisnutzer basisnutzer role role role role-name> name> name> name> auth auth auth auth-constraint constraint constraint constraint> <user <user <user <user-data data data data-constraint constraint constraint constraint> <transport <transport <transport <transport-guarantee guarantee guarantee guarantee>confidentialtransport >CONFIDENTIALtransport >CONFIDENTIALtransport >CONFIDENTIALtransport-guarantee guarantee guarantee guarantee> user user user user-data data data data-constraint constraint constraint constraint> security security security security-constraint constraint constraint constraint> Sicheres JSF (7/17) - JSF-Konfiguration web.xml [1/3] Startseite im Unterordner Regel für alle Seiten des Ordners wer darf HTTPS einschalten