99
Prof. Dr. Stephan Kleuker 209 Komponentenbasierte Software- Entwicklung 4. JEE /JSF / EJB / CDI 4.1 Grundlagen 4.2 Einführendes nulltes Beispiel 4.3 Validierung 4.4 JSF-Lebenszyklus 4.5 JSF mit EJB und JPA 4.6 Detaillierteres Beispiel: Mitarbeiterverwaltung 4.7 Testen von JEE-Programmen 4.8 Templates und Komponenten

4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

209Komponentenbasierte Software-Entwicklung

4. JEE /JSF / EJB / CDI

4.1 Grundlagen

4.2 Einführendes nulltes Beispiel

4.3 Validierung

4.4 JSF-Lebenszyklus

4.5 JSF mit EJB und JPA

4.6 Detaillierteres Beispiel: Mitarbeiterverwaltung

4.7 Testen von JEE-Programmen

4.8 Templates und Komponenten

Page 2: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

210Komponentenbasierte Software-Entwicklung

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, 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, PrenticeHall, USA, 2010

• Standard: Sun, JSR 344: JavaServer Faces 2.2, http://jcp.org/aboutJava/communityprocess/final/jsr344/index.html

• M. Çalışkan, O. Varaksin, PrimeFaces Cookbook - Second Edition, Packt Publishing, Birmingham UK, 2015

• Oracle, JEE7 Tutorial, https://docs.oracle.com/javaee/7/tutorial/https://docs.oracle.com/javaee/7/tutorial/jsf-intro.htm#BNAPH

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

Page 3: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

211Komponentenbasierte Software-Entwicklung

4.1 Grundlagen

Page 4: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

212

Komponenten und SW-Architektur

Komponentenbasierte Software-Entwicklung

DB

ZugriffJPA

Fachklassen

Zugriffskoordination EJB

Fachlogik

View-Repräsentation Scoped Beans

Controller

View JSF

Page 5: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

213Komponentenbasierte 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

Page 6: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

214Komponentenbasierte Software-Entwicklung

Web-Server mit Container nutzen (JEE)

• 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

Page 7: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

215Komponentenbasierte Software-Entwicklung

Motivation für JSF

• Die Widerverwendbarkeit von Servlets ist gering

• Innerhalb jeder JSP (Java ServerPage) 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)

Page 8: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

216Komponentenbasierte Software-Entwicklung

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

• Beispiele:

– Apache Tomcat / TomEE

– BEA WebLogic Server

– IBM WebSphere (Apache Geronimo)

– JBoss Wildfly

– Oracle WebLogic

– Glassfish (Oracle, Referenzimplementierung)

Unterschiedliches Tempo bei der Unterstützung neuer JEE-Versionen

Page 9: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

217Komponentenbasierte 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

event

leitet auf

Folgeseite

liest

Page 10: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

218Komponentenbasierte 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 boarder="7"

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

– generell saubere Terminierung <input ... />

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

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

Page 11: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

219Komponentenbasierte 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}“ 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

Page 12: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

220

Elementare Aufgabe: Eingabeseite mit Ausgabeseite

WebSeite

Modulname:

Modulnummer:

Modulname: <Ausgabe>

Modulnummer: <Ausgabe>

Abschicken Zur Eingabe

WebSeite

Eingabefeld Ausgabefeld

="#{modul.name}" ="#{modul.name}"

@Named("modul")

@RequestScoped

public class Modul implements Serializable {

private String name;

Managed Bean(Controller)

Knopf

Komponentenbasierte Software-Entwicklung

Page 13: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

221

Projekt einrichten (1/2)

Komponentenbasierte Software-Entwicklung

Page 14: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

222

Projekt einrichten (2/2)

Komponentenbasierte Software-Entwicklung

Page 15: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

223Komponentenbasierte Software-Entwicklung

4.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

– Layout-Gestaltung

– viele weitere coole Dinge

Page 16: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

224

<?xml version='1.0' encoding='UTF-8' ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

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

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head>

<title>Moduleingabe</title>

</h:head>

<h:body>

<h:form id="form" >

<h:outputText value="Modulname "/>

<h:inputText id="mname" value="#{modul.name}"

required="true"/><br/>

<h:outputText value="Modulnummer "/>

<h:inputText id="mnr" value="#{modul.nr}"

required="true"/><br/>

<h:commandButton value="Abschicken"

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

</h:form>

</h:body>

</html>

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

Komponentenbasierte Software-Entwicklung

Page 17: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

225

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

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

xmlns:h="http://xmlns.jcp.org/jsf/html"

xmlns:f ="http://xmlns.jcp.org/jsf/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? ( -> Managed Bean)

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

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

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

Komponentenbasierte Software-Entwicklung

Page 18: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

226

Nulltes JSF-Beispiel (4/11) - Ausgabe ausgabe.xhtml<?xml version='1.0' encoding='UTF-8' ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

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

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head>

<title>Modulausgabe</title>

</h:head>

<h:body>

<h:form id="form">

<h:outputText value="Modulname: "/>

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

<h:outputText value="Modulnummer: "/>

<h:outputText id="mnr" value="#{modul.nr}"/><br/>

<h:commandButton value="Zur Eingabe"

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

</h:form>

</h:body>

</html>

Komponentenbasierte Software-Entwicklung

Page 19: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

227

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

package entities;

import java.io.Serializable;

import javax.enterprise.context.RequestScoped;

import javax.inject.Named;

@Named("modul") // nur im Minimalbeispiel hat eine Entitaet

@RequestScoped // einen zugeordneten Scope

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;

}

Komponentenbasierte Software-Entwicklung

Page 20: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

228

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

public String uebernehmen(){

return "/ausgabe.xhtml";

}

public String eingeben(){

return "/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

Komponentenbasierte Software-Entwicklung

Page 21: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

229

Nulltes JSF-Beispiel (7/11) - Managed Bean [3/3]@Override // generieren lassen

public boolean equals(Object object) {

if (object==null || !(object instanceof Modul))

return false;

Modul other = (Modul) object;

if (this.nr != other.nr || !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+")";}

}Komponentenbasierte Software-Entwicklung

Page 22: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

230

Nulltes JSF-Beispiel (8/11) - web.xml [1/2]• Konfigurationsdatei für Servlets (hier benötigt; wird generiert)<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.1"

xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

<context-param>

<param-name>javax.faces.PROJECT_STAGE</param-name>

<param-value>Development</param-value>

</context-param>

<servlet>

<servlet-name>Faces Servlet</servlet-name>

<servlet-class>javax.faces.webapp.FacesServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

Komponentenbasierte Software-Entwicklung

Page 23: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

231

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

<servlet-mapping>

<servlet-name>Faces Servlet</servlet-name>

<url-pattern>/faces/*</url-pattern>

</servlet-mapping>

<session-config>

<session-timeout>

2

</session-timeout>

</session-config>

<welcome-file-list>

<welcome-file>faces/index.xhtml</welcome-file>

</welcome-file-list>

</web-app>

fehlt z. B. gesamte Fehlercodebehandlung

in glassfish-web.xml (Glassfish-spezifisch) steht, wenn existent, z. B.<context-root>/vlJSFNulltesBeispiel</context-root>

Komponentenbasierte Software-Entwicklung

Page 24: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

232

Nulltes JSF-Beispiel (10/11) - Projektstruktur

Komponentenbasierte Software-Entwicklung

Page 25: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

233

Nulltes JSF-Beispiel (11/11) - Ergebnis

Komponentenbasierte Software-Entwicklung

Page 26: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

234

beans.xml

• Datei garantiert korrekte Abarbeitung von Annotationen

• Datei ist Konfigurationsdatei von Contexts- and DependencyInjection (CDI)

• einige Teile CDI werden in Veranstaltung nebenbei eingeführt

• Datei muss in Projekten selbst erzeugt werden

• <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

bean-discovery-mode="all">

</beans>

Komponentenbasierte Software-Entwicklung

Wert muss von Hand von „annotated“ auf „all“ gesetzt werden

Page 27: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

235

beans.xml in NetBeans erzeugen

Komponentenbasierte Software-Entwicklung

Page 28: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

236

Richtige Klassen und Annotationen nutzen!• bei Korrekturvorschlägen immer auch richtige Klasse

achten, steht nicht immer oben oder ist ausgewählt!!!

• falsche Klasse führt teilweise zu extrem schwer zu findenden Fehlern

• Historisch sind diese Klassen oft verwandt und ältere Ansätze werden nicht verschwinden

Komponentenbasierte Software-Entwicklung

Page 29: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

237

Einschub: korrekte Pfadangabe

• Browser zeigt immer vergangene Seite

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

• ist etwas langsamer (warum, später genauer)

• Scope auf @SessionScoped setzenpublic String uebernehmen(){

return "/ausgabe.xhtml?faces-redirect=true";

}

public String eingeben(){

return "/index.xhtml?faces-redirect=true";

}

Komponentenbasierte Software-Entwicklung

Page 30: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

238Komponentenbasierte Software-Entwicklung

Basisprinzip der Applikationssteuerung

• Im Controller: Aufruf einer Methode vom Rückgabetyp String, auch Parameter nutzbar (dann Klammern)<h:commandButton value="Abschicken"

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

• Im Modell:public String uebernehmen(){

return "/ausgabe.xhtml"; // Endung weglassbar

}

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

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

• gibt XML-basierte Variante

• Mit public void-Methoden wird auf gleicher Seite geblieben

Page 31: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

239Komponentenbasierte Software-Entwicklung

Lebensdauer von Informationen (Scope)

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

• fehlt: CoversationScoped; im Programm Scope starten und enden

Request

Session

Application

für eineNutzer-Sitzung

solangeaktuellesDeploymentläuft

Zeitnur ein Aufruf

Page 32: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

240

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

//@Named("modul")

//@RequestScoped Modul als einfache Klasse (wichtig!)

public class Modul implements Serializable { ...// wie vorher

@Named(value = "modulr")

@RequestScoped

public class ModulRequest extends Modul{}

@Named("moduls")

@SessionScoped

public class ModulSession extends Modul{}

@Named("modula")

@ApplicationScoped

public class ModulApplication extends Modul{}

Komponentenbasierte Software-Entwicklung

Page 33: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

241Komponentenbasierte Software-Entwicklung

Scope-Beispiel (2/5) - Ausschnitt index.xhtml

<h:form>

<h:panelGrid columns="3" >

<h:outputLabel for="mnamer" value="Modulname "/>

<h:inputText id="mnamer" value="#{modulr.name}"/>

<h:message for="mnamer" />

<h:outputLabel for="mnrr" value="Modulnummer "/>

<h:inputText id="mnrr" value="#{modulr.nr}"/>

<h:message for="mnrr" />

<!-- auch moduls und modula -->

<h:commandButton value="Abschicken"

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

</h:panelGrid>

</h:form>

Page 34: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

242Komponentenbasierte Software-Entwicklung

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

<h:form>

<h:messages globalOnly="true"/>

<h:outputText value="Modulname r: "/>

<h:outputText id="mnamer" value="#{modulr.name}"/> <br/>

<h:outputText value="Modulnummer r: "/>

<h:outputText id="mnrr" value="#{modulr.nr}"/><br/>

<h:commandButton value="Zur Eingabe"

action="#{modulr.eingeben}"/><br/>

<!-- auch moduls und modula -->

<h:commandButton value="Ausgabe wiederholen"

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

</h:form>

Page 35: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

243Komponentenbasierte Software-Entwicklung

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

Page 36: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

244Komponentenbasierte Software-Entwicklung

Scope-Beispiel (5/5) - Zwei NutzerN

utz

er

1N

utz

er

2

Zeit

Page 37: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

245

ConversationScope (1/4)

Komponentenbasierte Software-Entwicklung

• Entwickler kann selbst Länge der Session bestimmen, damit zwischen RequestScope und SessionScope

import javax.enterprise.context.Conversation;

import javax.enterprise.context.ConversationScoped;

import javax.inject.Inject;

import javax.inject.Named;

@ConversationScoped

@Named("scope")

public class Scopeanalyse implements Serializable {

private String wert;

private List<String> liste = new ArrayList<>();

@Inject

private Conversation conver;

Vorgriff auf CDI:Container stellt

Conversation-Objekt zur Verfügung

Page 38: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

246

ConversationScope (2/4)

Komponentenbasierte Software-Entwicklung

public Scopeanalyse(){} // get- und set-Methoden fehlen

public void hinzu(){

if(this.conver.isTransient()){

this.conver.begin();

}

if(this.wert != null && !this.wert.trim().equals("")){

this.liste.add(wert);

}

} // kein String zurueck, da auf gleicher Seite geblieben

public void vergiss(){

if (!this.conver.isTransient()){

this.conver.end();

}

}

Page 39: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

247

ConversationScope (3/4)

<h:head>

<title>Scope Spielerei</title>

</h:head>

<h:body>

<h:form id="main">

<h:inputTextarea id="ein" value="#{scope.wert}" rows="3"/><br/>

<ui:repeat value="#{scope.liste}" var="w">

<h:outputText value="#{w} "/>

</ui:repeat> <br/>

<h:commandButton value="Übernehmen" action="#{scope.hinzu}"/>

<h:commandButton value="Vergessen" action="#{scope.vergiss}"/>

</h:form>

</h:body>

Komponentenbasierte Software-Entwicklung

Anmerkung: mit <ui:repeat> wird über eine Sammlung (scope.liste) iteriert, jeweiliges Objekt in Laufvariable w

Page 40: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

248

ConversationScope (4/4)

• Bild jeweils nach dem Klicken

Komponentenbasierte Software-Entwicklung

Page 41: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

249

Ausgabeprobleme: Umlaute und Zeilenumbrüche

• vor Knopfnutzung danach

• danach

Komponentenbasierte Software-Entwicklung

Page 42: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

250

Umlaute – Text-Encoding

• Sonderzeichen, wie Umlaute bei Eingaben problematisch

• wenn konsequent UTF-8 genutzt, dann kein Problem; trifft man öfter nicht an

• häufig, gerade im MS-Bereich, nur ISO-8859-1 nutzbar

• nicht ganz sauberer Trick: Eingaben selbst passend umwandeln (läuft ggfls. nicht in Ländern mit nichtlateinischer Schrift)

String s1 = new String("äöüÄÖßÜ");

System.out.println(s1);

String s2 = new String(s1.getBytes("UTF-8"), "ISO-8859-1");

System.out.println(s2);

String s3 = new String(s2.getBytes("UTF-8"), "ISO-8859-1");

System.out.println(s3);

Komponentenbasierte Software-Entwicklung

Page 43: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

251

Umlaute – saubere Glassfish-Lösung

• Codierung des Glassfish auf UTF-8 umstellen in glassfish-web.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD

GlassFish Application Server 3.1 Servlet 3.0//EN"

"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">

<glassfish-web-app error-url="">

<class-loader delegate="true"/>

<locale-charset-info default-locale="">

<locale-charset-map locale="" charset=""/>

<parameter-encoding default-charset="UTF-8"/>

</locale-charset-info>

</glassfish-web-app>

Komponentenbasierte Software-Entwicklung

Page 44: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

252

Zeilenumbrüche (1/2)

• verschiedene Lösungen, alle nicht optimal

• Konvertierer schreiben <h:outputText … converter="wandel"

• hier: HTML-Wissen nutzen, genauer CSS

<h:inputTextarea id="ein" value="#{scope.wert}" rows="3"/><br/>

<div style="white-space: pre-wrap">

<ui:repeat value="#{scope.liste}" var="w">

<h:outputText value="#{w} "/>

</ui:repeat> </div>

<h:commandButton value="Übernehmen" action="#{scope.hinzu}"/>

<h:commandButton value="Vergessen" action="#{scope.vergiss}"/>

Komponentenbasierte Software-Entwicklung

Page 45: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

253

Zeilenumbrüche (2/2)

Komponentenbasierte Software-Entwicklung

Page 46: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

254

Einschub: IE 9 – ggfls. 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

Page 47: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

255

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-param>

<param-name>javax.faces.STATE_SAVING_METHOD</param-name>

<param-value>client</param-value>

</context-param>

• Anmerkung: fehlt systematische Fehleranalyse: NetBeans 6.3.1, Glassfish 4, MS IE 9, MS IE 9 Nutzereinstellungen, Win7 x64, …

Komponentenbasierte Software-Entwicklung

Page 48: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

256

Kein Konstruktor in Managed Beans (Scopes)

• generell vieles nebenläufig

• unklar, wann Objektvariablen und andere Objekte genau erzeugt werden

• Races möglich: Zugriff auf Objekt, das gerade Konstruktor durchläuft

• alle Scopes können Methoden mit folgenden Annotationen nutzen

• @PostConstruct: nachdem das Objekt erzeugt wurde; sinnvoll hier Variablen initialisieren; Nutzung statt Konstruktor

• @PreDestroy: bevor Scope abläuft (aufräumen); auch wenn Session beendet wird

• Anmerkung: für kritische Ressourcen sinnvoll Ergänzung zu @PreDestroy zum Aufräumen

Komponentenbasierte Software-Entwicklung

Page 49: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

257

Nutzung @PostConstruct und @PreDestroy (1/5)@SessionScoped

public class Session implements Serializable{

private int zaehler;

public Session(){

System.out.println("Session Konstruktor: " + new Date());

}

@PostConstruct

public void init(){

System.out.println("Session PostConstruct: " + new Date());

}

@PreDestroy

public void destroy(){

System.out.println("Session PreDestroy: " + new Date());

}

public int plus(){

return ++this.zaehler;

}

}

Komponentenbasierte Software-Entwicklung

Page 50: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

258

Nutzung @PostConstruct und @PreDestroy (2/5)@RequestScoped

@Named

public class Bean implements Serializable{

@Inject

private Session session;

public Bean(){

System.out.println("Bean Konstruktor: " + new Date()); }

@PostConstruct

public void init(){

System.out.println("Bean PostConstruct: " + new Date());}

@PreDestroy

public void destroy(){

System.out.println("Bean PreDestroy: " + new Date());}

public void mach(){ // ohne Rückgabe, dann auf Seite bleiben

System.out.println("mach: " + this.session.plus());

}

} Komponentenbasierte Software-Entwicklung

Page 51: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

259

Nutzung @PostConstruct und @PreDestroy (3/5)

• index.xhtml<h:body>

<h:form id="form">

<h:commandButton id="b" value="mach"

action="#{bean.mach}"/>

</h:form>

</h:body>

• Sessiondauer in web.xml<session-config>

<session-timeout>

1

</session-timeout>

</session-config>

Komponentenbasierte Software-Entwicklung

Page 52: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

260

Nutzung @PostConstruct und @PreDestroy (4/5)Information: Bean Konstruktor: Mon Oct 30 16:15:53 CET 2017

Information: Session Konstruktor: Mon Oct 30 16:15:53 CET 2017

Information: Bean PostConstruct: Mon Oct 30 16:15:53 CET 2017

Information: Session Konstruktor: Mon Oct 30 16:15:53 CET 2017

Information: Session PostConstruct: Mon Oct 30 16:15:53 CET 2017

Information: mach: 1

Information: Bean PreDestroy: Mon Oct 30 16:15:53 CET 2017

Information: Bean Konstruktor: Mon Oct 30 16:16:16 CET 2017

Information: Bean PostConstruct: Mon Oct 30 16:16:16 CET 2017

Information: mach: 2

Information: Bean PreDestroy: Mon Oct 30 16:16:16 CET 2017

Information: Bean Konstruktor: Mon Oct 30 16:16:26 CET 2017

Information: Bean PostConstruct: Mon Oct 30 16:16:26 CET 2017

Information: mach: 3

Information: Bean PreDestroy: Mon Oct 30 16:16:26 CET 2017

Information: Session PreDestroy: Mon Oct 30 16:18:42 CET 2017

FATAL: JSF1073: javax.faces.application.ViewExpiredException

FATAL: viewId:/index.xhtml - Ansicht /index.xhtml konnte nicht

wiederhergestellt werden.

Komponentenbasierte Software-Entwicklung

nach Klick (oder längerem Warten)

Page 53: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

261

Nutzung @PostConstruct und @PreDestroy (5/5)

• kleine Änderung in Bean-Klassepublic Bean(){

System.out.println("mach: " + this.session.plus());

System.out.println("Bean Konstruktor: " + new Date());

}

• möglicher Effekt bei erstem Klick:Warnung: #{bean.mach}: java.lang.NullPointerException

javax.faces.FacesException: #{bean.mach}:

java.lang.NullPointerException

Komponentenbasierte Software-Entwicklung

Page 54: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

262Komponentenbasierte Software-Entwicklung

Erinnerung: Konstanten in Programmen

• schlecht return "ANZEIGEN";

• besser: Konstanten getrennt deklarierenpublic class Modul implements Serializable{

private final static string ANZEIGEN = "ANZEIGEN";

...

return ANZEIGEN;

• Alternativ: Klasse mit Konstantenpackage konstanten;

public class Navigation{

public final static string ANZEIGEN = "ANZEIGEN";

...

return konstanten.Navigation.ANZEIGEN;

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

Page 55: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

263Komponentenbasierte 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

@Named("mo")

@SessionScoped

public class Mojo implements Serializable {

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";

}

}

Page 56: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

264

<?xml version='1.0' encoding='UTF-8' ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

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

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://xmlns.jcp.org/jsf/html">

<h:head> <title>Klickklack</title> </h:head>

<h:body>

<h:form id="f1">

<h:panelGrid id="p1" rendered="#{mo.jo}">

<h:outputLabel value=„HS rocks"/>

</h:panelGrid>

<h:panelGrid id="p2" rendered="#{!mo.jo}">

<h:outputLabel value="OS rocks"/>

</h:panelGrid>

<h:commandButton action="#{mo.change}" value="Press"/>

</h:form>

</h:body>

</html>

Standardattribut rendered (2/3) - JSF-Seite

Komponentenbasierte Software-Entwicklung

Page 57: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

265Komponentenbasierte Software-Entwicklung

Standardattribut rendered (3/3)

Page 58: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

266Komponentenbasierte Software-Entwicklung

Strukturierung mit panelgrid / panelgroup

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

• durch columns="3" eine Spaltenanzahl angebbar• Ausgabe erfolgt in Tabellenform• Elemente werden zeilenweise ergänzt

• mit h:panelgroup Sammlung ohne Formatierung möglich, auch als Block zusammengefasst, z. B.:<h:panelGrid rendered="#{! empty controller.foren}">

<ui:repeat value="#{controller.foren}" var="f" >

</ui:repeat>

</h:panelGrid>

Page 59: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

267Komponentenbasierte Software-Entwicklung

Kommentare

• (?!) Kommentare In JSF-Seiten <!-- Dies liest eh keiner -->

wandern in Ausgabe, Ausdrücke mit #{…} werden ausgewertet

• Ergänzung in web.xml:

<context-param>

<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>

<param-value>true</param-value>

</context-param>

Page 60: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

268

Unified Expression Language

• Zugriff auf Exemplarvariablen und Methoden der ManagedBeans

• zentrale Typen: Zahlen und Strings (können sehr gut verarbeitet und verglichen werden)

• Schreiben von Werten über set-Methoden "#{mo.jo}"

• Lesen erfolgt über get-Methoden, generell Berechnungen möglich, die beim Schreiben keinen Sinn haben "#{!mo.jo}"

• Bei Methoden mit fest vorgegebener Aufgabe (vorgegebener Signatur), stehen keine Klammern beim Aufruf action="#{mo.change}" sonst ja "#{bean1.machWasMit(bean2)}"

• Zugriff auf Variablen aus festen Namensraum: ManagedBeans und Servlet Parameter

• JSR 341: Expression Language 3.0, https://jcp.org/en/jsr/detail?id=341

Komponentenbasierte Software-Entwicklung

Page 61: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

269

Implizite Objekte der EL (Ausschnitt)

• requestScope (analog sessionScope, applicationScope)Zugriff auf Request-Map des External-Contexts

• param

Zugriff auf Request-Parameter-Map des External-Contexts

• header

Zugriff auf Request-Header-Map des External-Contexts

• facesContext

Zugriff auf den Faces-Context

• initParam

Zugriff auf Kontextparameter der Webapplikation

• cookie

Zugriff auf die Request-Cookie-Map des External-Contexts

Komponentenbasierte Software-Entwicklung

Page 62: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

270

Zusammenspiel von Scopes (1/4)

• Beispiel: Gemeinsame Erstellung eines Einkaufszettels, jeder kann Zeilen hinzufügen (nur temporärer Speicher im ApplicationScope; Eingabe benötigt nur RequestScope)

Komponentenbasierte Software-Entwicklung

Page 63: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

271

Zusammenspiel von Scopes (2/4)

@ApplicationScoped

public class Gedicht implements Serializable{

private List<String> zeilen;

@PostConstruct

public void init() {

this.zeilen = new ArrayList<>();

}

public void zeileHinzu(String text) {

this.zeilen.add(text);

}

public List<String> getZeilen() {

return this.zeilen;

}

public void setZeilen(List<String> zeilen) {

this.zeilen = zeilen;

}

}Komponentenbasierte Software-

Entwicklung

Page 64: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

272

Zusammenspiel von Scopes (3/4)@Named("vc")

@RequestScoped

public class ViewController {

@Inject

private Gedicht gedicht;

private String eingabe;

public void hinzu(){

this.gedicht.zeileHinzu(eingabe);

this.eingabe = "";

}

public List<String> getText() {

return this.gedicht.getZeilen();

}

public String getEingabe() { return this.eingabe; }

public void setEingabe(String eingabe) {

this.eingabe = eingabe;

}

}

Komponentenbasierte Software-Entwicklung

kleiner Trick: get-Methode ohne

Exemplarvariable

void-Methode bleibt auf gleicher

Seite

Page 65: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

273

Zusammenspiel von Scopes (4/4)

<h:head>

<title>WG-Einkaufszettel</title>

</h:head>

<h:body>

<h:form id="main">

Ihre Eingabe: <h:inputText id="eingabe" size="30"

value="#{vc.eingabe}"/>

<h:commandButton id ="hinzu" value="Hinzu"

action="#{vc.hinzu}"/>

<br/>

<ui:repeat var="z" value="#{vc.text}">

#{z} <br/>

</ui:repeat>

</h:form>

</h:body>

Komponentenbasierte Software-Entwicklung

Page 66: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

274Komponentenbasierte Software-Entwicklung

4.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

Page 67: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

275Komponentenbasierte Software-Entwicklung

Fehleingaben im nullten Beispiel (2/2)

Anpassung des Projektstatus (oder Parameter löschen) in web.xml

(Development, UnitTest, SystemTest, Production)<context-param>

<param-name>javax.faces.PROJECT_STAGE</param-name>

<!-- <param-value>Development</param-value> -->

<param-value>Production</param-value>

</context-param>

Applikation bleibt auf der Seite, keine sichtbare Fehlermeldungim 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.)]

Page 68: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

276

Direkte Validierungen - einige Möglichkeiten<h:form>

<h:panelGrid columns="3" >

<h:outputLabel for="mname" value="Modulname "/>

<h:inputText id="mname" value="#{modul.name}"

required="true" size="8" requiredMessage="nich leer"

validatorMessage="4 Zeichen">

<f:validateLength minimum="4" maximum="4"/>

</h:inputText>

<h:message for="mname" />

<h:outputLabel for="mnr" value="Modulnummer "/>

<h:inputText id="mnr" value="#{modul.nr}" required="true"

requiredMessage="Eingabe notwendig" size="4"

converterMessage="normale Zahl"/>

<h:message for="mnr" />

<h:commandButton value="Abschicken"

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

</h:panelGrid>

</h:form>

Komponentenbasierte Software-Entwicklung

Page 69: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

277Komponentenbasierte Software-Entwicklung

Ausgaben beim Drücken von „Abschicken“

Page 70: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

278

Globale Fehlermeldungen erzeugen und anzeigen

public String uebernehmen() {

if (name.equals("OOAD")) {

FacesContext ctxt = FacesContext.getCurrentInstance();

FacesMessage ms = new FacesMessage();

ms.setSeverity(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:messages globalOnly="true"/>

<h:outputText value="Modulname: "/>

Komponentenbasierte Software-Entwicklung

Page 71: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

279Komponentenbasierte Software-Entwicklung

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("OOAD")) {

throw new ValidatorException(new FacesMessage(

FacesMessage.SEVERITY_ERROR, "oweh", "ole ole"));

}

}

...

Hinweis: wird „?faces-redirect=true“ genutzt, ist zu ergänzen:context.getExternalContext().getFlash().setKeepMessages(true);

Page 72: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

280Komponentenbasierte Software-Entwicklung

Validierer selbst gestrickt (2/2)

• in index.xhtml<h:panelGrid columns="3" >

<h:outputLabel for="mname" value="Modulname "/>

<h:inputText id="mname" value="#{modul.name}"

validator="#{modul.pruefe}"/>

<h:message for="mname" />

Page 73: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

281

Anmerkungen zu vorherigen Folien

• man kann eigene Validierungsmethoden schreiben

• man könnte auch hier BeanValidation nutzen (folgt später), muss dies aber selbst zu passenden Ausgaben umwandeln

• FacesContext ist der zentrale Zugang zu den Innereien von JSF

• Zugriff bis auf genutzte Servlets mit deren Parametern möglich

• leider auch eine Art Voodoo-Klasse, da fast die gesamte JSF-Steuerung manipulierbar und so keine JSF-Schicht mehr richtig existiert

• FacesContext macht Code-Wiederverwendung mit anderen Technologien fast unmöglich; deshalb hier nicht intensiv betrachtet

Komponentenbasierte Software-Entwicklung

Page 74: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

282Komponentenbasierte Software-Entwicklung

4.4 JSF-Lebenszyklus

JSF-Klassen: typischer GUI-Aufbau mit Events• Hierarchische Baumstruktur der Komponenten, z. B.

– Intern: Wurzel des Komponentenbaums, Container– <h:form> Formular, benötigt zum Daten verschicken– <h:panelGrid> Container mit Tabellendarstellung

• public abstract class UIComponent extends Object implements

StateHolder: UIComponent is the base class for all user interface components in JavaServer Faces. The set of UIComponent instances associated with a particular request and response are organized into a component tree under a UIViewRoot that represents the entire content of the request or response. (Oracle Klassendoku)

• public abstract class UIComponentBase extends UIComponent

• public class UICommand extends UIComponentBase implements

ActionSource2

• public class UIOutput extends UIComponentBase implements

ValueHolder

Page 75: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

283Komponentenbasierte Software-Entwicklung

Analyse von FacesContext (1/4)

<h:form id="f1">

<h:messages id="m1" globalOnly="true"/>

<h:panelGrid id="p1" columns="3" >

<h:outputLabel id="o1" for="mname" value="Modulname "/>

<h:inputText id="mname" value="#{module.modul.name}"/>

<h:message id="m2" for="mname" />

<h:outputLabel id="o2" for="mnr" value="Modulnummer "/>

<h:inputText id="mnr" value="#{module.modul.nr}"/>

<h:message id="m3" for="mnr"/>

<h:commandButton id="c1" value="Abschicken"

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

</h:panelGrid>

<h:commandLink id="anz" action="#{module.anzeigen}" >

<h:outputText value="Zur Modulübersicht"/>

</h:commandLink><br/>

<h:commandLink id="intern"

action="#{module.intern}" >

<h:outputText value="JSFAufbauinfos"/>

</h:commandLink>

</h:form>

Page 76: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

284Komponentenbasierte Software-Entwicklung

Analyse von FacesContext (2/4)

private void baum(UIComponent ui, String leer) {

System.out.println(leer + ui.getId() + ": "

+ ui.getRendererType() +" : "

+ ui.getClass());

List<UIComponent> com = ui.getChildren();

for (UIComponent u : com) {

baum(u, leer + " ");

}

}

public String intern() {

FacesContext ctxt = FacesContext.getCurrentInstance();

UIViewRoot vr = ctxt.getViewRoot();

if (vr != null) {

System.out.println("Root:" + vr.getViewId());

baum(vr, " ");

} else

System.out.println("keine Root");

return ANZEIGEN;

}

Page 77: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

285Komponentenbasierte Software-Entwicklung

Analyse von FacesContext (3/4)

INFO: Root:/index.xhtmlINFO: j_id1: null : class javax.faces.component.UIViewRootINFO: j_idt2: null : class com.sun.faces.facelets.compiler.UIInstructionsINFO: j_idt3: null : class com.sun.faces.facelets.compiler.UIInstructionsINFO: j_idt4: javax.faces.Head : class javax.faces.component.UIOutputINFO: j_idt5: null : class com.sun.faces.facelets.compiler.UIInstructionsINFO: j_idt6: javax.faces.Body : class javax.faces.component.UIOutputINFO: f1: javax.faces.Form : class javax.faces.component.html.HtmlFormINFO: m1: javax.faces.Messages : class javax.faces.component.html.HtmlMessagesINFO: p1: javax.faces.Grid : class javax.faces.component.html.HtmlPanelGridINFO: o1: javax.faces.Label : class javax.faces.component.html.HtmlOutputLabelINFO: mname: javax.faces.Text : class javax.faces.component.html.HtmlInputTextINFO: m2: javax.faces.Message : class javax.faces.component.html.HtmlMessageINFO: o2: javax.faces.Label : class javax.faces.component.html.HtmlOutputLabelINFO: mnr: javax.faces.Text : class javax.faces.component.html.HtmlInputTextINFO: m3: javax.faces.Message : class javax.faces.component.html.HtmlMessageINFO: c1: javax.faces.Button : class javax.faces.component.html.HtmlCommandButtonINFO: anz: javax.faces.Link : class javax.faces.component.html.HtmlCommandLinkINFO: j_idt15: javax.faces.Text : class javax.faces.component.html.HtmlOutputTextINFO: j_idt16: null : class com.sun.faces.facelets.compiler.UIInstructionsINFO: intern: javax.faces.Link : class javax.faces.component.html.HtmlCommandLinkINFO: j_idt17: javax.faces.Text : class javax.faces.component.html.HtmlOutputTextINFO: j_idt18: null : class com.sun.faces.facelets.compiler.UIInstructionsGrundregel: Layout bleibt statisch; Ein- und Ausblenden durch Attribut rendered

Page 78: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

286Komponentenbasierte Software-Entwicklung

Analyse von FacesContext (4/4) - KomponentenbaumUIViewRoot

HtmlMessages

HtmlForm

HtmlPanelGrid

HtmlOutputLabel

HtmlInputText

HtmlMessage

HtmlOutputLabel

HtmlInputText

HtmlMessage

HtmlCommandButton

HtmlCommandLink

HtmlOutputText

HtmlCommandLink

HtmlOutputText

Page 79: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

287Komponentenbasierte Software-Entwicklung

Speichern der Zustandsinformationen (1/2)

• Klassische GUI-Komponenten (und Event-Listener) sind zustandsbasiert; HTTP nicht

• Zustand muss gesichert werden (wie wird in DeploymentDescriptor beschrieben)

– Variante A: auf dem Server (Zuordnung z. B. über Cookies)

• empfohlen; nicht default bei Netbeans

• hohe Speicheranforderung

– Variante B: beim Client<context-param>

<param-name>javax.faces.STATE_SAVING_METHOD</param-name>

<param-value>client</param-value>

</context-param>

• anzuzeigende Seite enthält Zustand in hidden Field

Page 80: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

288Komponentenbasierte Software-Entwicklung

Speichern der Zustandsinformationen (2/2)

Seitenende in generiertem HTML (Ausschnitt):<a id="f1:intern" href="#" onclick="if(typeof jsfcljs ==

'function'){jsfcljs(document.forms['f1'],'f1:intern,

f1:intern','');}return false">JSFAufbauinfos</a>

<input type="hidden" name="javax.faces.ViewState"

id="javax.faces.ViewState"

value="H4sIAAAAAAAAANVXW2wUVRg+O9s7FXrhGlNaAiIYu2W7i0HQSIF

eFndb0i1F4KGcnT3bnTI3Z850BogEHtREEqNBEk0wavDBB3hRn4jxEh6M

JJhI4ouJCTEmxsRLYkxQH9Tzn9mZnd2dbSliopNmembm/875/tt3zl7+E

VaBuo+mp7D8zgmY3U2NpGbIyLd9dLnT73RYW6VBYQcHSG0wjRQQtSUmGm

sQIWiRnDui5LIqaSpsayFFOSwSqeJUZK0eVNUwYh41qe/Fq4+uGVbaMft

cM8dhzB1QerOaVZ2Jy6phKVxg6mpiViT2oaRa1zM1Ke/cWTjvk0Oo0Eu5

crjvbjgkk44FU8Al+KOW8oi1eicXBItKbBZsFjNYz+6pNrq499EU=" />

</form>

</body>

</html>

Page 81: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

289Komponentenbasierte Software-Entwicklung

Hintergrund: Abarbeitung von JSF-Anfragen

Page 82: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

290Komponentenbasierte Software-Entwicklung

Restore View

Komponentenbaum (wieder-)herstellen

• basiert auf nicht sichtbarer Wurzelkomponente

• Komponentenbaum in FacesContext gespeichert

• erster Aufruf:

– JSF-Seite rendern, nicht anzeigen

– ID-Vergabe und damit Aufbau der internen Struktur

– Registrieren von Event-Listenern und Validatoren

– Werte in Komponenten eintragen

• sonst: zugehörigen Komponentenbaum suchen, bzw. wieder aufbauen (beinhaltet auch Eventlistener, Konvertierer und Backing-Beans)

Page 83: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

291Komponentenbasierte Software-Entwicklung

Apply Request Values

UI-Komponenten mit Anfrageparametern aktualisieren

• Request-Parameter auslesen (einschließlich JSF 1.2 nur POST)

• POST-String parsen und filtern

• Werte dann UI-Komponenten zuordnen (noch nicht prüfen)

• nutzt Methode processDecodes() für alle Komponenten

• falls Attribut immediate=„true“, dann (gleich genauer)

– für Aktionselemente (Command): konvertieren und validieren überspringen

– für Eingabeelemente (Input): sofort konvertieren und validieren

Page 84: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

292Komponentenbasierte Software-Entwicklung

Process Validations

Werte konvertieren und validieren

• Jede UI-Komponente validiert und konvertiert den zugeordneten Wert

• nutzt Methode processValidators() der Komponenten

• automatische Konvertierung für viele Typen; Konvertiererselbst erstellbar (ähnlich zu Validierer)

• bei Fehler Fehlermeldung in Fehlerliste eintragen und Modellaktualisierung überspringen; zur Ausgabe

• bei Wertänderung: ValueChangeEvent

• Anmerkung: Werte noch nicht in Beans

Page 85: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

293Komponentenbasierte Software-Entwicklung

Update Model Values

Werte im Modell (Beans) aktualisieren

• Typsicherheit durch vorherige Schritte garantiert

• nutzt Methode processUpdates() der Komponenten

• Werte aktualisieren, durch set-Methoden

• Abbruch bei Fehler

Page 86: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

294Komponentenbasierte Software-Entwicklung

Invoke Applications

Anwendung ausführen

• an das Ereignis gebundene Aktion ausführen, z. B. Action-Methode

• nutzt Methode processApplication() der Komponenten

• arbeitet mit vorher aktualisierten Werten

Page 87: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

295Komponentenbasierte Software-Entwicklung

Render Response

• Rendern durch Spezifikation nicht festgelegt

• Antwort generieren

• aktuellen Stand des zugehörigen Komponentenbaums ausgeben

• rekursiver Baumdurchlauf; jeweils Renderer aufrufen (HTML, XTHML, XUL, ...)

• jede Komponente hat Methode der Form encodeXXX()

• abspeichern des Komponentenbaums

• generierte Seite an Server übergeben, der sie typischerweise an den Browser schickt

Page 88: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

296Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (1/8)

• Man kann PhaseListener schreiben, die über Phasenänderungen informiert werden

• wird in faces-config.xml im Ordner WEB-INF festgehalten (neue JSF Faces Configuration)

<?xml version='1.0' encoding='UTF-8'?>

<faces-config version="2.2"

xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">

<lifecycle>

<phase-listener>controller.ZeichPhasen</phase-listener>

</lifecycle>

</faces-config>

Page 89: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

297Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (2/8) - index.xhtml

<h:form id="form1">

<h:panelGrid id="panel1" columns="3" rules="all">

<h:outputText id="o1" value="neuer Text"/>

<h:inputText id="i1" value="#{analyse.ein}"

required="true"/>

<h:message id="m1" for="i1"/>

<h:outputText id="ow1" value="neue Zahl"/>

<h:inputText id="iw1" value="#{analyse.zahl}"/>

<h:message id="m1w" for="iw1"/>

<h:outputText id="o2" value="alter Text/Zahl"/>

<h:outputText id="o3" escape="false"

value="#{analyse.ein}"/>

<h:outputLabel id="ow3" value="#{analyse.zahl}"/>

<h:commandButton id="c1" value="Übernehmen"

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

</h:panelGrid>

</h:form>

Page 90: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

298Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (3/8) - Bean

@Named

@SessionScoped

public class Analyse implements Serializable{

private String ein;

private int zahl;

public Analyse(){}

public String uebernehmen(){

return "/index.xhtml";

}

public String getEin() {return ein;}

public void setEin(String ein) {this.ein = ein;}

public int getZahl() {return zahl;}

public void setZahl(int zahl) {this.zahl = zahl;}

}

Page 91: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

299Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (4/8) - PhaseListener [1/2]

public class ZeichPhasen implements PhaseListener {

// Hier angeben, in welchen Phasen dieser Listener genutzt

// werden soll, im Beispiel in allen

@Override

public PhaseId getPhaseId() {

return PhaseId.ANY_PHASE;

}

@Override

public void beforePhase(PhaseEvent e) {

if (e.getPhaseId() == PhaseId.RESTORE_VIEW)

System.out.println("===geht los");

System.out.println("before: " + e.getPhaseId());

zeichAnalyse();

}

Page 92: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

300Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (5/8) - PhaseListener [2/2]

@Override

public void afterPhase(PhaseEvent e) {

System.out.println("after: " + e.getPhaseId());

zeichAnalyse();

if (e.getPhaseId() == PhaseId.RENDER_RESPONSE)

System.out.println("===is Schicht");

}

private void zeichAnalyse() {

FacesContext fc = FacesContext.getCurrentInstance();

Analyse a = fc.getApplication()

.evaluateExpressionGet(fc, "#{analyse}",

Analyse.class);

System.out.println("A: "+a.getEin() +" :: "+ a.getZahl());

}

}

Page 93: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

301Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (6/8) - Applikationsstart

INFO: ===geht los

INFO: before: RESTORE_VIEW 1

INFO: A: null :: 0

INFO: after: RESTORE_VIEW 1

INFO: A: null :: 0

INFO: before: RENDER_RESPONSE 6

INFO: A: null :: 0

INFO: after: RENDER_RESPONSE 6

INFO: A: null :: 0

INFO: ===is Schicht

Nutzer macht Eingaben

Page 94: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

302Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (7/8) - erfolgreiche ÜbernahmeINFO: ===geht los

INFO: before: RESTORE_VIEW 1

INFO: A: null :: 0

INFO: after: RESTORE_VIEW 1

INFO: A: null :: 0

INFO: before: APPLY_REQUEST_VALUES 2

INFO: A: null :: 0

INFO: after: APPLY_REQUEST_VALUES 2

INFO: A: null :: 0

INFO: before: PROCESS_VALIDATIONS 3

INFO: A: null :: 0

INFO: after: PROCESS_VALIDATIONS 3

INFO: A: null :: 0

INFO: before: UPDATE_MODEL_VALUES 4

INFO: A: null :: 0

INFO: after: UPDATE_MODEL_VALUES 4

INFO: A: Zaphod :: 42

INFO: before: INVOKE_APPLICATION 5

INFO: A: Zaphod :: 42

INFO: after: INVOKE_APPLICATION 5

INFO: A: Zaphod :: 42

INFO: before: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: after: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: ===is Schicht

Page 95: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

303Komponentenbasierte Software-Entwicklung

JSF-Lifecycle verfolgen (8/8) - falsche EingabeINFO: ===geht los

INFO: before: RESTORE_VIEW 1

INFO: A: Zaphod :: 42

INFO: after: RESTORE_VIEW 1

INFO: A: Zaphod :: 42

INFO: before: APPLY_REQUEST_VALUES 2

INFO: A: Zaphod :: 42

INFO: after: APPLY_REQUEST_VALUES 2

INFO: A: Zaphod :: 42

INFO: before: PROCESS_VALIDATIONS 3

INFO: A: Zaphod :: 42

INFO: after: PROCESS_VALIDATIONS 3

INFO: A: Zaphod :: 42

INFO: before: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: after: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: ===is Schicht

Page 96: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

304Komponentenbasierte Software-Entwicklung

Problem: Abbrüche (1/2)in Analyse :

public String zuruecksetzen(){

ein="";

zahl=0;

return "/index.xhtml";

}

• in index.xhtml<h:commandButton id="c2" value="Zurücksetzen"

action="#{analyse.zuruecksetzen}"/>

• Problem: Validierung läuft trotzdem

Page 97: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

305Komponentenbasierte Software-Entwicklung

Problem: Abbrüche (2/2)

• immediate=„true“ erlaubt Validierung zu überspringen

<h:commandButton id="c2" value="Zurücksetzen"

immediate="true" action="#{analyse.zuruecksetzen}"/>

===geht los

before: RESTORE_VIEW 1

A: Zaphod :: 42

after: RESTORE_VIEW 1

A: Zaphod :: 42

before: APPLY_REQUEST_VALUES 2

A: Zaphod :: 42

after: APPLY_REQUEST_VALUES 2

A: :: 0

before: RENDER_RESPONSE 6

A: :: 0

after: RENDER_RESPONSE 6

A: :: 0

===is Schicht

Page 98: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

306Komponentenbasierte Software-Entwicklung

Nutzung von immediate für Eingabefelder• immediate=true fordert sofortige Validierung und Konvertierung für

diese Komponente<h:inputText id="i1" value="#{analyse.ein}"

immediate="true" validatorMessage="nur 3">

<f:validateLength maximum="3"/>

</h:inputText>

===geht los

before: RESTORE_VIEW 1

A: null :: 0

after: RESTORE_VIEW 1

A: null :: 0

before: APPLY_REQUEST_VALUES 2

A: null :: 0

after: APPLY_REQUEST_VALUES 2

A: null :: 0

before: RENDER_RESPONSE 6

A: null :: 0

after: RENDER_RESPONSE 6

A: null :: 0

===is Schicht

<Return> im Eingabefeld drücken

Page 99: 4. JEE /JSF / EJB / CDIhome.edvsz.fh-osnabrueck.de/skleuker/WS17_KbSE/WS17KbSE_Teil4.pdf · und „Applet“, (serverseitiges Applet) •Web-Server leitet HTTP-Request an Servlet

Prof. Dr. Stephan Kleuker

307Komponentenbasierte Software-Entwicklung

Eineinhalb Schleifen

public String uebernehmen(){

return "/index.xhtml?faces-redirect=true";

}

// wie vorher

INFO: before: INVOKE_APPLICATION 5

INFO: A: Zaphod :: 42

INFO: after: INVOKE_APPLICATION 5

INFO: A: Zaphod :: 42

INFO: ===geht los

INFO: before: RESTORE_VIEW 1

INFO: A: Zaphod :: 42

INFO: after: RESTORE_VIEW 1

INFO: A: Zaphod :: 42

INFO: before: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: after: RENDER_RESPONSE 6

INFO: A: Zaphod :: 42

INFO: ===is Schicht

Ohne Redirect: rein serverseitige Weiterleitung, Client kennt Ziel nicht