5.12 JSF-Erweiterungen RichFaces Ideen • graphische Möglichkeiten in JSF recht schlicht (wesentlich besser als gezeigt!), Erweiterungsbibliotheken sinnvoll • wesentliche Komponentenframeworks: – RichFaces: http://www.jboss.org/richfaces – Primefaces: http://www.primefaces.org/ – IceFaces: http://www.icefaces.org/main/home/ • alternative JSF-Implementierungen (Standard: Mojarra): – Apache MyFaces: http://myfaces.apache.org/ – Apache MyFaces Trinidad (ehemals Oracle ADF-Faces): http://myfaces.apache.org/trinidad/index.html • kritisch: Frameworks nur teilweise kompatibel, gilt auch für Framework mit Implementierung • kritisch: in Details teilweise deutliche Darstellungsunterschiede in verschiedenen Browsern • erweiterte graphische Komponenten • eigene Integration von Ajax (ohne es nutzen zu müssen, es aber zu können) Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 404 Mini-Beispiel: Kalender – Projektstruktur (1/6) 405 <context-param> <param-name>org.richfaces.SKIN</param-name> <param-value>blueSky</param-value> </context-param> • Externe benötigte Bibliotheken • Realisierung der RichFacesKomponenten • Enthält u. a. JSF 2.0 (Mojarra) Prof. Dr. Stephan Kleuker Prof. Dr. Stephan Kleuker Mini-Beispiel: Kalender – web.xml (optional!) (2/6) • Deployment Descriptor web.xml wird geändert Komponentenbasierte SoftwareEntwicklung • RichFaces integriert Frameworks und Bibliotheken – Prototype [http://prototypejs.org] – jQuery [http://jquery.com] – Script.aculo.us [http://script.aculo.us] • benötigte einige weitere externe Bibliotheken • einleitender Artikel: http://www.ibm.com/ developerworks/java/library/j-richfaces/index.html • Leider Version 4 und Version 3.3 nicht vollständig kompatibel (z. B. event="change" statt event="onchanged") 406 <context-param> <param-name>org.richfaces.CONTROL_SKINNING</param-name> <param-value>enable</param-value> </context-param> <listener> <listener-class> com.sun.faces.config.ConfigureListener </listener-class> </listener> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 407 Mini-Beispiel: Kalender – übliche Bean (3/6) Mini-Beispiel: Kalender – index.xhtml 1 (4/6) import java.util.Date; @ManagedBean(name="modul") @RequestScoped public class Modul implements Serializable { private Date start=new Date(); <?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" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> <h:head> <title>Datum auswählen</title> </h:head> public Modul(){} public Date getStart() { System.out.println("getstart "+start+" .."); return start; } public void setStart(Date start) { System.out.println("setstart "+start); this.start = start; } public String show(){ System.out.println("Datum: "+ start); return ""; // unsauber, bleibt auf Seite } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 408 Mini-Beispiel: Kalender – index.xhtml 2 (5/6) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 409 Mini-Beispiel: Kalender - Ablauf (6/6) <h:body> <h:form> <rich:calendar id="cal" value="#{modul.start}" popup="false" datePattern="dd.MM.yyyy"> <a4j:ajax event="change" render="o"/> </rich:calendar> <br/> <h:commandButton action="#{modul.show}" value="Übernehmen"/> <br/> <h:outputLabel value="ausgewählt: "/> <h:outputText id="o" value="#{modul.start}" /><br/> </h:form> </h:body> </html> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 410 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 411 Nutzung von ICEfaces Beispiel: Tabellennutzung – Managed Bean 1 (1/6) @ManagedBean(name = "ice") @SessionScoped // Request reicht nicht public class IceSpielerei implements Serializable { • Freie Komponenten-Bibliothek • http://www.icefaces.org/main/ho me/ • kontinuierliche Weiterentwicklung • kein nahtloser Übergang von 1.x zu 2.x • benötigte jar-Dateien alle im Download (in verschiedenen Verzeichnissen) • ein Schwerpunkt: Google-MapsUnterstützung Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker private String[] eis = {"Vanilla", "Schoko", "Cuba Libre", "Jever", "Scotch"}; private boolean richtung; public String getName() { return "Eis";} public String[] getList() { return eis;} public boolean isRichtung() { return richtung;} public void setRichtung(boolean richtung) { this.richtung = richtung; } 412 Beispiel: Tabellennutzung – Managed Bean 2 (2/6) 413 • Rein formal keine Ergänzungen/Änderungen notwendig, dann aber auch keine Stil-Nutzung möglich • Viele wichtige Konfigurationsmöglichkeiten <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class> com.icesoft.faces.webapp.CompatResourceServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/xmlhttp/*</url-pattern> </servlet-mapping> } Prof. Dr. Stephan Kleuker Prof. Dr. Stephan Kleuker Beispiel: Tabellennutzung – web.xml (3/6) public String sort() { if (richtung) { Arrays.sort(eis); } else { Arrays.sort(eis, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }); } return "./index.xhtml"; } Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung 414 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 415 Beispiel: Tabellennutzung – index.xhtml 1 (4/6) Beispiel: Tabellennutzung – index.xhtml 2 (5/6) <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ice="http://www.icesoft.com/icefaces/component" xmlns:icecore="http://www.icefaces.org/icefaces/core" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <title>Ice Ice Baby</title> <link rel="stylesheet" type="text/css" href="./xmlhttp/css/rime/rime.css"/> </h:head> <h:body styleClass="ice-skin-rime"> <ice:form> <ice:dataTable value="#{ice.list}" var="i" border="2" sortColumn="#{ice.name}" sortAscending="#{ice.richtung}" > Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 416 Beispiel: Tabellennutzung – Ausgabe (6/6) <ice:column> <f:facet name="header"> <ice:commandSortHeader columnName="#{ice.name}" arrow="true" action ="#{ice.sort}"> <ice:outputText value="#{ice.name}"/> </ice:commandSortHeader> </f:facet> <ice:outputText value="#{i}"/> </ice:column> <ice:column> <f:facet name="header"> <ice:headerRow> <ice:outputText value="Preis"/> </ice:headerRow> </f:facet> <ice:outputText value="#{i.length()}"/> </ice:column> </ice:dataTable> <ice:outputText value="#{ice.richtung}"/> </ice:form> </h:body> </html> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 417 Nutzung von PrimeFaces 2 • unterstützt JSF 2, recht junges Projekt ab November 2008 • Dokumentation neuerdings kostenpflichtig • Installationsergänzung in web.xml: <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>Resource Servlet</servlet-name> <servlet-class> org.primefaces.resource.ResourceServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Resource Servlet</servlet-name> <url-pattern>/primefaces_resource/*</url-pattern> </servlet-mapping> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 418 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 419 Beispiel: Editorspielerei (1/4) - Managed Bean Beispiel: Editorspielerei (2/4) - index.xhtml @ManagedBean @SessionScoped public class Text { private String inhalt; public String getInhalt() { return inhalt; } public void setInhalt(String inhalt) { this.inhalt = inhalt; } } Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 420 Beispiel: Editorspielerei (3/4) - h: (Seite lädt neu) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head> <title>Editor</title> </h:head> <h:body> <h:form > <p:editor id="ed" width="600px" height="120px" value="#{text.inhalt}" widgetVar="editor"/> <p:commandButton update="o1,o2" async="true" value="p Uebernehmen" onclick="editor.saveHTML()"/><br/> <h:commandButton value="h Uebernehmen"/><br/> <h:outputText id="o1" escape="true" value="Inhalt: #{text.inhalt}"/><br/> <h:outputText id="o2" escape="false" value="Inhalt: #{text.inhalt}"/> </h:form> </h:body> </html> Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 421 Beispiel: Editorspielerei (4/4) - p: (Aktualisierung) 422 Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 423 Anmerkungen zum Beispiel Versionsänderung • Normalerweise unterstützt p:commandButton Ajax direkt (nur bei p:editor Problem, deshalb Workaround mit widgetVar) • Warum andere Ergebnisse angezeigt werden, ist mir unklar • Versionswechsel 2.0.2 zu 2.2.1 führt zu anderer Darstellung • Ungleichheit p: und h: korrigiert • andere Attribute statt height="120px" nun height="120" • <h:head> immer benötigt • Generell: Genaue Analyse der oft sehr vielen Attribute einer Komponente notwendig • Mischung von h: und p: oft (nicht immer) möglich • Man muss mit Eigenarten der Komponenten leben (bei Großprojekten und Auswahlentscheidungen schwierig) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 424 Polling (1/2) Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 425 Polling (2/2) <?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" xmlns:p="http://primefaces.prime.com.tr/ui"> <h:head> <title>Poller</title> </h:head> <h:body> <h:form> <h:outputText id="o1" value="#{zeit.datum}"/><br/> <h:outputText id="o2" value="#{zeit.anzahl}"/> <p:poll interval="3" update="o1,o2"/> </h:form> </h:body> </html> @ManagedBean @SessionScoped public class Zeit { Komponentenbasierte SoftwareEntwicklung Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 426 private int anzahl; public String getDatum() { anzahl++; return new Date().toString(); } public int getAnzahl() { return anzahl; } } Prof. Dr. Stephan Kleuker 427 Design-Tests JSF - es geht noch weiter • JSF Expression Language – einfacher Zugriff auf Maps, die Umgebungsdaten, wie param, requests, cookies und initParam haben – Nutzung von flash-Variable als Zwischenspeicher • Erweiterung der Expression Language • Möglichkeit GET zu nutzen (und damit Bookmarks) – <h:button> und <h:link> • JSF 2.0 hat klare Regeln wie Ressourcen verwaltet werden (Bilder, Templates, ...) • integrierte, nutzbare JavaScript-API • Viele weitere JavaScript-Möglichkeiten (u. a. h:outputScript) • weitere Möglichkeiten des Event-Handlings, z. B. eigene Klasse reagiert auf Event (z. B. Phasenwechsel) • Ergänzung/Erweiterung des Exception Handlings • Lokalisierung, Mehrsprachlichkeit • Browser stellen identische Inhalte leicht verändert da • technisch überflüssig, aber wichtig für den Zeitgeist: modische Design-Anpassungen • Für IT-Profi: Sisyphus-Arbeit; Test mit unterschiedlichen Browsern • Direkte Hilfsmittel: – Lunascape: ein Browser, bei dem man zwischen drei Maschinen umschalten kann IE (Trident)+Firefox (Gecko)+Chrome, Safari (Webkit) – Windows: USB-portable Browser ohne Installationsnotwendigkeit (verändern keine Einstellungen): Firefox, Chrome, Opera • Capture & Replay mit Selenium zum inhaltlichen Test Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 428 5.13 Testen von Web-Applikationen - Selenium Komponentenbasierte SoftwareEntwicklung Prof. Dr. Stephan Kleuker 429 Prof. Dr. Stephan Kleuker 431 Selenium - Aufzeichnen • Web-Browser nutzen schwerpunktmäßig HTML zur Darstellung • Capture & Replay-Werkzeuge, die hardgecoded Pixel und Klicks verarbeiten, eignen sich meist auch für diese Programme • Einfaches Werkzeug für Web-Applikationen und Firefox ist Selenium (http://seleniumhq.org/) – erlaubt Capture & Replay von Nutzereingaben – ermöglicht Tests von Elementen – erlaubt den Export der aufgezeichneten Tests u. a. in JUnit – basiert auf JavaScript and Iframes Software-Qualität Prof. Dr. Stephan Kleuker 430 Software-Qualität Selenium - Zusicherungen Selenium - Einbindung in JUnit • benötigt: http://release.seleniumhq.org/selenium-remotecontrol/1.0.1/selenium-remote-control-1.0.1-dist.zip Software-Qualität Prof. Dr. Stephan Kleuker 432 Variante: Klassen zur Browsersteuerung (1/2) Software-Qualität 433 Variante: Klassen zur Browsersteuerung (2/2) public class GoogleTest { @Test public void testGoogle1() { private WebDriver driver; // (auch Selenium) //google aufrufen. "http://" nicht vergessen driver.get("http://www.google.de/"); //findet das Eingabefeld fuer Suchbegriffe WebElement element = driver.findElement(By.name("q")); //gibt Suchbegriff "Selenium" ein und bestätigt element.sendKeys("Selenium"); element.submit(); public GoogleTest() {} @Before public void setUp() { //Erzeugt neue Instanz des Browser Treibers //driver = new FirefoxDriver(); driver = new InternetExplorerDriver(); //driver = new HtmlUnitDriver(); //driver = new ChromeDriver(); } // statt "submit" auf "Google-Suche" button zu clicken: // element = driver.findElement(By.name("btnG")); // element.click(); @After public void tearDown() { //beendet Browser driver.quit(); } Software-Qualität Prof. Dr. Stephan Kleuker //Gibt Seitentitel auf Konsole aus //Ueberprueft ob die Seite "Google" im Titel enthaelt Assert.assertTrue(driver.getTitle().contains("Google")); } Prof. Dr. Stephan Kleuker 434 } Software-Qualität Prof. Dr. Stephan Kleuker 435 Grenzen typischer Capture & Replay - Werkzeuge Fazit • Aufzeichnungsprobleme möglich, da nicht alle Events sauber erkannt werden (zu viele, Pixelangabe ungenau) • Gerade bei unterschiedlichen Web-Browsern kann es durch wenige Pixel zu Bedienproblemen kommen • Reaktionszeiten von GUIs müssen beachtet werden • Die Prüfung, ob Texte vollständig angezeigt werden, oder sich GUI-Elemente teilweise überlappen, ist oft nicht möglich • Innovative, jetzt noch unbekannte Bedienelemente (z. B. Multi-Touch) werden meist noch nicht unterstützt • Generell: Automatische Prüfung der Software-Ergonomie nicht möglich (-> Usability-Tests) Software-Qualität Prof. Dr. Stephan Kleuker 436 • GUI-Tests sind generell möglich • GUI-Tests erst planen, wenn GUI relativ festgelegt ist • Werkzeuge kritisch evaluieren, ob sie für Projekt bzw. typische Unternehmensaufgaben geeignet sind • freie GUI-Werkzeuge können auf jeden Fall Einstieg in GUITestansätze sein • Evaluation von kommerziellen Werkzeugen in diesem Bereich oft sinnvoll • generell wird Teststrategie benötigt, was wann getestet wird (botton up, top down, middle out) Software-Qualität Prof. Dr. Stephan Kleuker 437