Erinnerung: Eine Komponentenarchitektur-Variante • Datenbank als zentrale Kommunikationsplattform • Ansatz 1: alle Komponenten kennen Entitäten-Modell • Ansatz 2: Datenzugriffsschicht kapselt Datenbank Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 217 Ansatz 1: Alle kennen Entitäten-Modell (1/2) • Datenbank als zentrale Kommunikationsplattform • Entitäten sind bekannt, jede Komponente kann zugreifen • Benötigt Komponente weitere Eigenschaft einer Entität wird keine Spalte sondern Tabelle ergänzt (auch 1:1, 1:C, nutzt Primärschlüssel) • Sehr einfache Architektur • Sehr gut Komponenten an- und ausschaltbar • Keine Benachrichtigung bei Änderungen (sichtbar beim nächsten Lesen) • Stark eingeschränkte Wiederverwendbarkeit • Keine echte Informationskapselung • Wartbarkeit nimmt mit Systemgröße enorm ab Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 218 Ansatz 1: Alle kennen Entitäten-Modell (2/2) • Beispiel: Komponenten Produktverwaltung, Bestellsystem (sieht neue Produkte und Änderungen bei nächsten Aufruf) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 219 Ansatz 2: Kapselung mit Datenzugriffsschicht (1/2) • Kein direkter Zugriff auf Tabellen • Ermöglicht auch Benachrichtigungen (Observer) • Zerlegung in wiederverwendbare Komponenten • Unterschiedliche Varianten von Kommunikationen möglich – Nutzung einer zentralen Zugriffskomponente, die DB kapselt und Observer verwaltet – Nur Data Access Objects können miteinander reden – Komponentenschnittstellen unabhängig von der DB – Selbst gemeinsame Datenbank ist optional Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 220 Ansatz 2: Kapselung mit Datenzugriffsschicht (2/2) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 221 Überwachungsmethoden (1/3) @Entity public class Mitarbeiter { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int minr; private String name; private void p(String s){System.out.println(s);} @PrePersist public void prePersit() {p("prePersist");} @PostPersist public void postPersist() {p("postPersist");} @PreRemove public void preRemove() {p("preRemove");} @PostRemove public void postRemove() {p("postRemove");} @PreUpdate public void preUpdate() {p("preUpdate");} @PostUpdate public void postUpdate() {p("postUpdate");} @PostLoad public void postLoad() {p("postLoad");} // Hinweis: Rollback bei einer Runtime Exception ... Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 222 Überwachungsmethoden (2/3) public static void main(String[] args) { EntityManagerFactory emf = Persistence .createEntityManagerFactory("PrePostPU"); EntityManager em = emf.createEntityManager(); Mitarbeiter m = new Mitarbeiter("Olga"); prePersist Mitarbeiter m2 = new Mitarbeiter("Otto"); prePersist EntityTransaction ta = em.getTransaction(); prePersist ta.begin(); postPersist em.persist(m); postPersist em.persist(m2); postPersist em.persist(new Mitarbeiter("Urs")); preUpdate ta.commit(); postUpdate ta.begin(); Mitarbeiter mm = em.find(Mitarbeiter.class, m.getMinr()); mm.setName("Anna"); em.persist(mm); ta.commit(); Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 223 Überwachungsmethoden (3/3) ta.begin(); em.remove(m); ta.commit(); em.close(); // notwendig für neuen Kontext em = emf.createEntityManager(); for (Mitarbeiter m3 : em.createQuery( "SELECT m FROM Mitarbeiter m" , Mitarbeiter.class) .getResultList()) System.out.println(m3.getMinr() + ": " + m3.getName()); em.close(); emf.close(); preRemove postRemove postLoad postLoad 2: Otto 3: Urs } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 224 5. JavaServer Faces (JSF) 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 Grundlagen Einführendes nulltes Beispiel Validierung JSF mit JPA und JNDI Funktionale Erweiterung Ausblick: Nutzung CDI und SessionBeans Sicherheit Weitere JSF-Möglichkeiten JSF-Lebenszyklus Templates und Komponenten Nutzung von Ajax JSF-Erweiterungen Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 225 Literatur • D. Geary, C. Horstmann, Core JavaServer Faces, 3. Auflage, Prentice Hall, USA, 2010 • 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) • K. Ka Iok Tong, Beginning JSF 2 APIs and JBoss Seam, Apress, Berkeley, USA, 2009 • Standard: Sun, JSR 314: JavaServer Faces 2.0, 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 226 5.1 Grundlagen verschiedene Ziele von JSF-Applikationen • Software, die Web als zusätzlichen Nutzen hat (z. B. WebPrä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! Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 227 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 228 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 229 Typische Entwicklungsplattformen (Ausschnitt) .Net / Microsoft • ASP.Net (Active Server Pages, gute Abstraktion, zunächst zu wenig Web-Server (IIS)) • Silverlight (Browser-PlugIn) für RIA, mittlerweile auch lokal • Oberflächen basierend auf WPF (Windows Presentation Forum, vektorbasiert, anfänglich zu langsam) Java • Servlets, JSP, JSF [später genauer], angegeben mit steigenden Abstraktionsgrad sehr weit verbreitet • verschiedene neue Frameworks (z. B. Apache Wicket) • GWT (Google Widget Toolset), SW einmal in Java schreiben, dann individuell für Browser in Javascript übersetzen • JavaFX , eigene Sprache nutzt im Browser JRE • Meinung: Silverlight und JavaFX gegenüber Flash(Nachfolger) immer im Nachteil Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 230 Client HTTP-Response mit HTML-Datei im Body EJBContainer HTTP-Request WebContainer Konzept eines Seitenaufrufs Application Server • HTML (Hypertext Markup Language) – Auszeichnungssprache mit festgelegten tags zum Aufbau der Ausgabe • Ebene 3/4 typisch TCP/IP, Session Ebene 5: HHTP, Darstellungsebene 6: HTML, Programmebene 7: JVM Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 231 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 232 Web-Server mit Container nutzen • Servlet: Wortkreation aus den Begriffen „Server“ und „Applet“, (serverseitiges Applet) • Web-Server leitet HTTPRequest an Servlet weiter • Servlet kann Antwort (HTML-Code) berechnen • Servlet kann AnfrageInformationen und Serverumgebung nutzen • Servlet kann mit anderen Servlets kommunizieren Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker Container 233 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. AJAXEinbettung • Hinweis: wir betrachten nur Grundkonzepte (-> mehr evtl. Semesteraufgabe) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 234 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) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 235 Konzeptübersicht Web-Seite in XHTML Input-Komponente beschrieben in XHTML event Web-Seite in XHTML leitet auf Folgeseite Output-Komponente beschrieben in XHTML liest Modell ... ... Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker Java-Programm im Container im Server 236 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 zurückgestellt 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 237 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 238 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 239 Nulltes JSF-Beispiel (2/11) - Start index.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://java.sun.com/jsf/html"> <h:head> <title>Moduleingabe</title> </h:head> <h:body> <h: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> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 240 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/jsf/html" xmlns:f ="http://java.sun.com/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 EventHandling (Methodenaufruf) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 241 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://java.sun.com/jsf/html"> <h:head> <title>Modulausgabe</title> </h:head> <h:body> <h: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 SoftwareEntwicklung Prof. Dr. Stephan Kleuker 242 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(name="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; } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 243 Nulltes JSF-Beispiel (6/11) - Managed Bean [2/3] public String uebernehmen(){ return "./ausgabe.xhtml"; } public String eingeben(){ return "./index.xhtml"; } //Manövrieren 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; } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 244 Nulltes JSF-Beispiel (7/11) - Managed Bean [3/3] @Override 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 Prof. Dr. Stephan Kleuker 245 Nulltes JSF-Beispiel (8/11) - web.xml [1/2] • Konfigurationsdatei für Servlets (hier benötigt) • sun-web.xml ist Glassfish-spezifische Konfiguratonsdatei <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.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 SoftwareEntwicklung Prof. Dr. Stephan Kleuker 246 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> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>faces/index.xhtml</welcome-file> </welcome-file-list> </web-app> in sun-web.xml steht u. a. <context-root>/JSFSpielerei2</context-root> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 247 Nulltes JSF-Beispiel (10/11) - Projektstruktur Applikation in Web-Archives (war-Files) gepackt (gibt Strukturregeln) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 248 Nulltes JSF-Beispiel (11/11) - Ergebnis Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 249 Basisprinzip der Applikationssteuerung • Im Controller: Aufruf einer Methode ohne Parameter vom Rückgabetyp String <h:commandButton value="Abschicken" action="#{modul.uebernehmen}"/> • Im Modell: public String uebernehmen(){ return "./ausgabe.xhtml"; } • Methode kann natürlich abhängig von Variablen unterschiedliche Seiten liefern • Beachten: Navigation kann in den Tiefen des Codes verschwinden ( -> Konstanten nutzen, Architektur) • Hinweis: wir werden noch Varianten kennenlernen Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 250 Lebensdauer von Informationen (scope) None Request Session Application nur für einen nur aktuelle Aufruf (auch für Seite Weiterleitung) für eine NutzerSitzung solange Zeit aktuelles Deployment läuft • Anmerkung: Obwohl es verlockend ist, viele Informationen in Session oder Application zu legen, ist dies wg Performance verboten (wird gespeichert, evtl. passiviert, hat wilde Referenzen, Zugriff muss ggfls. synchronisiert werden) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 251 Scope-Beispiel (1/5) - Bean-Klasse //@ManagedBean(name = "modul") //@RequestScoped Modul als einfache Klasse (wichtig!) public class Modul implements Serializable { ...// wie vorher @ManagedBean(name = "moduln") @NoneScoped public class ModulNone extends Modul{} @ManagedBean(name = "modulr") @RequestScoped public class ModulRequest extends Modul{} @ManagedBean(name = "moduls") @SessionScoped public class ModulSession extends Modul{} @ManagedBean(name = "modula") @ApplicationScoped public class ModulApplication extends Modul{} Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 252 Scope-Beispiel (2/5) - Ausschnitt index.xhtml <h:form> <h:panelGrid columns="3" > <h:outputLabel for="mnamen" value="Modulname "/> <h:inputText id="mnamen" value="#{moduln.name}"/> <h:message for="mnamen" /> <h:outputLabel for="mnrn" value="Modulnummer "/> <h:inputText id="mnrn" value="#{moduln.nr}"/> <h:message for="mnrn" /> <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> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 253 Scope-Beispiel (3/5) - Ausschnitt ausgabe.xhtml <h:form> <h:messages globalOnly="true"/> <h:outputText value="Modulname n: "/> <h:outputText id="mnamen" value="#{moduln.name}"/> <br/> <h:outputText value="Modulnummer n: "/> <h:outputText id="mnrn" value="#{moduln.nr}"/><br/> <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> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 254 Scope-Beispiel (4/5) - Ein Nutzer, zwei Klicks Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 255 Nutzer 2 Nutzer 1 Scope-Beispiel (5/5) - Zwei Nutzer Zeit Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 256 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 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 257 Manövrieren vor JSF 2.0 - faces-config.xml 1/2 <?xml version='1.0' encoding='UTF-8'?> <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"> <navigation-rule> <from-view-id>/index.xhtml</from-view-id> <navigation-case> <from-outcome>ANZEIGEN</from-outcome> <to-view-id>/ausgabe.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/ausgabe.xhtml</from-view-id> <navigation-case> <from-outcome>EINGEBEN</from-outcome> <to-view-id>/ index.xhtml </to-view-id> </navigation-case> </navigation-rule> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 258 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"; } ... Komponentenbasierte Software} Entwicklung Prof. Dr. Stephan Kleuker 259 Manövrieren vor JSF 2.0 - faces-config.xml 2/2 <managed-bean> <managed-bean-name>modul</managed-bean-name> <managed-bean-class>entities.Modul</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-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-config.xml bleibt trotzdem wichtig Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 260 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; – Entwicklungsumgebungen erlauben dann einfache Suche und Änderung (Refactoring) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 261 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"; } } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 262 Standardattribut rendered (2/3) - JSF-Seite <?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://java.sun.com/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> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 263 Standardattribut rendered (3/3) <?xml version='1.0' encoding='UTF-8'?> oder in <faces-config version="1.2" ...> faces-config.xhtml <managed-bean> <managed-bean-name>mo</managed-bean-name> <managed-bean-class>entities.Mojo</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 264 Strukturierung mit panelgrid / Kommentare • mit h:panelgrid kö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 --%> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 265