michael MOSMANN PRAXISBUCH WICKET PROFESSIONELLE WEB-2.0- ANWENDUNGEN ENTWICKELN
Mosmann Praxisbuch Wicket vbleiben Sie einfach auf dem Laufenden: www.hanser.de/newsletter Sofort anmelden und Monat für Monat die neuesten Infos und Updates erhalten.
Michael Mosmann Praxisbuch Wicket Professionelle Web-2.0-Anwendungen entwickeln
Michael Mosmann, Lübeck Kontakt: michael@mosmann.de Alle in diesem Buch enthaltenen Informationen, Verfahren und Darstellungen wurden nach bestem Wissen zusammengestellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grund sind die im vorliegenden Buch enthaltenen Informationen mit keiner Verpflichtung oder Garantie irgendeiner Art verbunden. Autor und Verlag übernehmen infolgedessen keine juristische Verantwortung und werden keine daraus folgende oder sonstige Haftung übernehmen, die auf irgendeine Art aus der Benutzung dieser Informationen oder Teilen davon entsteht. Ebenso übernehmen Autor und Verlag keine Gewähr dafür, dass beschriebene Verfahren usw. frei von Schutzrechten Dritter sind. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Buch berechtigt deshalb auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften. Bibliografische Information der Deutschen Nationalbibliothek: Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar. Dieses Werk ist urheberrechtlich geschützt. Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches, oder Teilen daraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlages in irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes Verfahren) auch nicht für Zwecke der Unterrichtsgestaltung reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden. 2009 Carl Hanser Verlag München, www.hanser.de Lektorat: Margarete Metzger Copy editing: Jürgen Dubau, Freiburg Herstellung: Irene Weilhart Umschlagdesign: Marc Müller-Bremer, www.rebranding.de, München Umschlagrealisation: Stephan Rönigk Datenbelichtung, Druck und Bindung: Kösel, Krugzell Ausstattung patentrechtlich geschützt. Kösel FD 351, Patent-Nr. 0748702 Printed in Germany ISBN 978-3-446-41909-4
für meine Eltern
0 2
Inhalt Vorwort...XIII 1 Einleitung... 1 1.1 Warum Wicket?...3 1.1.1 Einfach, Konsistent, Offensichtlich...4 1.1.2 Wiederverwendbarkeit...4 1.1.3 Sauber getrennt...5 1.1.4 Sicher...5 1.1.5 Effizient und skalierbar...6 1.1.6 Komplett...6 1.1.7 Eine gute Wahl...6 1.2 Vorbereitung und Installation...7 1.2.1 Java, Maven und Eclipse...7 1.2.2 Versionskontrolle mit Subversion...7 1.3 Grundlagen einer Webanwendung...8 1.3.1 Anwendungsschichten...8 1.3.2 Verzeichnis und Paketstruktur...11 1.3.3 Unit-Tests...12 2 Aufsetzen der Teilprojekte... 15 2.1 Nomenklatur der Teilprojekte...15 2.2 Aufsetzen der Teilprojekte...16 2.2.1 Projektbasis ParentPom...16 2.2.2 Teilprojekt Base...20 2.2.3 Teilprojekte Datenbankkonfiguration...20 2.2.4 Teilprojekt Persistenz...22 2.2.5 Teilprojekt Applikationsschicht...24 2.2.6 Teilprojekt Webapp...24 2.2.7 Teilprojekt ParentPom Abschluss...26 2.3 Erstellen von Eclipse-Projektdateien...27 VII
Inhalt 3 Mit Leben füllen... 29 3.1 Konfiguration mit Spring...29 3.2 Datenbankkonfiguration...30 3.2.1 Teilprojekt dbconfig...30 3.2.2 Teilprojekt dbconfig-test...31 3.2.3 Teilprojekt dbconfig-schema-update...31 3.2.4 Schemagenerierung mit Hibernate...32 3.3 Persistenz...33 3.3.1 Datenbankzugriff Allgemeine Schnittstellendefinition...33 3.3.2 Datenbankzugriff Hilfsklassen...34 3.3.3 Datenbankzugriff User...35 3.3.4 Datenbankzugriff Konfiguration...37 3.3.5 Persistenz-Tests...38 3.3.6 Schema-Update...40 3.4 Anwendungsschicht...41 3.5 Präsentationsschicht...41 3.5.1 Hilfsklasse für Maven-Projekte...41 3.5.2 Wicket Web Application...42 3.5.3 Servlet-Konfiguration...44 3.5.4 Spring-Konfiguration...46 3.5.5 Start der Anwendung...46 4 Die Wicket-Architektur... 49 4.1 Wicket und das HTTP-Protokoll...49 4.2 Struktur...49 4.2.1 WebApplication...50 4.2.2 Session...50 4.2.3 PageMap...50 4.2.4 Page...50 4.2.5 PageStore...51 4.2.6 Component...51 4.3 Request-Behandlung...51 4.3.1 Komponentenphasen...52 4.3.2 Nebenläufigkeit Threads...52 4.4 Komponenten, Modelle, Markup...53 4.4.1 Komponenten...53 4.4.2 Modelle...53 4.4.3 Markup...53 5 Modelle... 55 5.1 Konverter...55 5.2 Einfache Modelle...57 5.2.1 Modelle verändern...58 5.3 Modell-Hilfsklassen...60 5.4 Modelle und Serialisierung...61 5.4.1 DetachableModel Dynamische Modelldaten...61 VIII
Inhalt 5.4.2 Kaskadierung von Modellen...62 5.4.3 Automatische Kaskadierung von Modellen...65 5.4.4 Datenbankzugriffsmodelle...66 5.5 Komplexe Modellklassen...69 5.5.1 Zugriff auf Bean-Properties...69 5.5.2 Die Klasse PropertyModel...72 5.5.3 CompoundPropertyModel...74 5.6 Ausgelagerte Informationen...76 5.6.1 5.6.2 Einfacher Zugriff auf Ressourcen...76 ResourceModel...76 5.6.3 StringResourceModel...78 6 Komponenten... 81 6.1 Basisklasse Component...81 6.1.1 Komponentenbaum...81 6.1.2 Darstellungsphasen...83 6.1.3 Page, Session und Application...84 6.1.4 Komponentenpfad...84 6.1.5 Modelle...84 6.1.6 Feedback...85 6.2 Grundlagen der Vererbung...85 6.2.1 Eine Seite mit eigenen Komponenten...85 6.2.2 Vererbung für Fortgeschrittene...91 6.3 Style, Locale und Variation...94 6.3.1 Markup-Variationen...94 6.4 Sichtbarkeit...99 6.4.1 wicket:enclosure...100 6.4.2 Empfehlung zur Anwendung...101 6.5 Ajax...102 6.5.1 Ajax-Events...103 6.5.2 Einfache Event-Behandlung...104 6.5.3 Automatische Event-Behandlung...105 7 Basiskomponenten... 109 7.1 Gruppierende Komponenten...109 7.1.1 Seiten...109 7.1.2 Panel...117 7.1.3 Fragment...119 7.1.4 Border...120 7.1.5 ComponentBorder...125 7.1.6 WebMarkupContainer...126 7.2 Inhaltselemente...127 7.2.1 Label und MultiLineLabel...127 7.2.2 Lokaler Konverter...129 7.2.3 XML...130 7.2.4 Das wicket:message-tag...131 IX
Inhalt 7.2.5 Image...132 7.3 Links...137 7.3.1 Von A nach B...137 7.3.2 Ajax und Links...138 7.3.3 Link-Tricks...140 7.3.4 Externe Links...141 7.3.5 Popups...141 7.3.6 ResourceLink...143 7.4 7.3.7 Formularlinks...144 Behavior...144 7.4.1 Darf es etwas JavaScript sein?...144 7.4.2 Attribute anpassen...145 7.4.3 Attribute erweitern...147 7.4.4 Ajax und Formulare...148 8 Listen und Tabellen... 149 8.1 Darstellung von Listen...149 8.1.1 RepeatingView...149 8.1.2 RefreshingView...150 8.1.3 ListView...152 8.1.4 PropertyListView...153 8.1.5 ColumnListView...154 8.2 DataProvider...156 8.2.1 DataView...156 8.2.2 GridView...158 8.2.3 DataGridView...159 8.2.4 DataTable...161 8.2.5 DefaultDataTable...162 9 Formulare... 169 9.1 Voraussetzungen...169 9.2 Feedback...170 9.3 Basisklasse für alle Beispiele...171 9.4 Formulare absenden...172 9.4.1 Absenden mit Submit-Button...172 9.4.2 Button-Komponente...173 9.4.3 Submit per Ajax...174 9.4.4 POST und GET...175 9.5 Textfelder...176 9.5.1 Typangabe...178 9.5.2 Automatische Typermittlung...179 9.6 Label...181 9.7 CheckBox...182 9.8 RadioButton...185 9.9 Auswahlfelder...186 9.9.1 Select...186 X
Inhalt 9.9.2 DropDownChoice...188 9.9.3 ListMultipleChoice...190 9.10 Dateien hochladen...192 9.10.1 FileUpload...192 9.10.2 MultiFileUpload...194 9.11 Gültigkeitsprüfung...195 9.11.1 StringValidator...196 9.11.2 Minimum und Maximum...197 9.11.3 E-Mail...197 9.11.4 URL...199 9.11.5 Eigene Validatoren...199 9.12 FormValidator...201 9.12.1 Passwortprüfung...201 9.12.2 Eigene Prüfung...203 9.13 Ajax...205 9.13.1 AjaxFormSubmitBehavior...205 9.13.2 AjaxFormValidatingBehavior...207 9.13.3 AjaxComponentUpdatingBehavior...207 9.13.4 OnChangeBehavior...209 9.13.5 AutoCompleteTextField...210 9.14 AjaxEditableLabel...212 9.15 Erweitertes Feedback...214 9.15.1 Feedback zum Formular...214 9.15.2 Feedback für die Komponente...215 9.15.3 Feedback als Rahmen...216 9.15.4 Feedback als Indikator...217 9.15.5 Feedback per CSS...218 9.16 Generierte Formulare...220 9.17 Verschachtelte Formulare...222 10 Sessions und Security... 225 10.1 Einfache Variante...225 10.1.1 Eine eigene Session-Klasse...225 10.1.2 Geschützte Seiten...226 10.1.3 Strategie...226 10.1.4 WebApplication...227 10.1.5 Seiten...228 10.2 Marker an Komponenten...231 10.3 Elemente ausblenden...233 11 Wicket in der Praxis... 235 11.1 Die Integration von Spring...235 11.2 Navigation...237 11.3 CSS einbinden...244 11.4 Eigene Basiskomponenten...250 XI
Inhalt 11.5 Komponententausch...253 11.5.1 AjaxFallbackConfirmLink...254 11.5.2 Wizard...256 11.6 Suchmaschinenoptimierung...258 11.6.1 Pfad für BookmarkablePages...258 11.6.2 SessionTimeoutPage...262 11.6.3 SEO-Links...264 11.6.4 Servlet-Filter...268 11.6.5 Tracking mit Google Analytics...271 11.7 Ressourcen...274 11.7.1 Dynamisch erzeugte Grafiken...274 11.7.2 Automatisch generierte Thumbnails...276 11.7.3 Download durch Formular...277 11.7.4 Shared Resources...278 11.7.5 RSS-Feed...280 11.8 Links auf Seiten und Ressourcen...282 11.9 Optimierungen...284 11.9.1 Applikation...284 11.9.2 Konverter...284 11.9.3 Debug...284 11.9.4 Ressource...285 12 Fehlersuche... 287 12.1 Häufige Fehlerquellen...287 12.1.1 Komponenten fehlen...287 12.1.2 Komponente ist bereits vorhanden...287 12.1.3 Ajax funktioniert nicht...288 12.2 Unit-Tests...288 13 Anfang oder Ende?... 293 Register... 295 XII
Vorwort Ich beschäftige mich seit meiner frühen Jugend mit der Softwareentwicklung. Angefangen hat das auf einem ZX-Spektrum-Klon in Basic. Im Laufe der Jahre kamen so unterschiedliche Programmiersprachen und Betriebssysteme zusammen. Der Einstieg in die objektorientierte Programmierung kam mit C++. Die ersten Versuche, Anwendungen mit Benutzeroberflächen zu schreiben, habe ich auf einem Amiga unternommen. Die Anwendungen waren klein und der Nutzerkreis beschränkt. Im Juli 1999 fing ich bei Dr. Klein und Co. an und startete mit ersten Anwendungen, die im Internet zur Verfügung gestellt wurden. Das waren Java-Applets, die z.b. Kreditberechnungen ermöglichten. Nicht viel später entstanden die ersten Webanwendungen, die damals als Servlets und mit JavaServer Pages realisiert wurden. Die Anwendungen wurden komplexer und dieses Entwicklungsmodell stieß zunehmend an seine Grenzen. Mangels guter Alternativen entstanden so im Laufe der Jahre einige selbst entwickelte Anwendungsframeworks. Diese linderten zwar die Probleme etwas, beseitigten das grundlegende Problem aber nicht. Die Suche nach Alternativen ging weiter und so landete ich im März 2008 auf der Webseite von Wicket. Ich hatte mir bis dahin so einiges angesehen: GWT, Rails, Thinwire um nur einige zu nennen. Im Gegensatz zu diesen überzeugte mich Wicket von Anfang an. Das ist nun mehr als ein Jahr her und für mich hat sich durch Wicket einiges grundlegend verändert. Webanwendungen zu schreiben ist so einfach geworden, dass man bei neuen Features nicht darüber nachdenkt, wie man sie realisiert, sondern im ersten Moment nur, ob man sie realisiert. Wusste man bei den alten Anwendungen genau, welche Problemstellungen Bauchschmerzen verursachten, sind diese Anforderungen mit Wicket keine Herausforderung und das Entwickeln mit Wicket macht einfach nur Spaß. Die Arbeit kommt vor den Vergnügen. Doch der Spaß sollte nicht lange auf sich warten lassen. In diesem Sinne: Let s have some fun. XIII
Vorwort Danksagung Es gab eine Menge Menschen, die mich direkt und indirekt beim Schreiben dieses Buches unterstützt haben. Daher ist es unmöglich, nicht aus Versehen, den einen oder anderen zu vergessen. Die Reihenfolge sollte auf keinen Fall als Wertung missverstanden werden. Ich danke natürlich meiner Frau, weil sie mich immer wieder angespornt und mir den Rücken frei gehalten hat. Ich danke dem Carl Hanser Verlag und da ganz besonders Frau Metzger, die immer sehr viel geduldiger und ruhiger war als ich. Vermutlich hätte ich sonst bereits das Handtuch geworfen. Dank gebührt auch Dirk Diebel, der einen Blick auf Auszüge dieses Buches werfen durfte und mir bestätigte, dass das nicht ganz unverständlich ist, was ich da zusammengeschrieben habe. Ohne Stephan Lamprecht wäre dieses Buch nie entstanden, weil er nicht nur den Kontakt zum Verlag hergestellt hat, sondern auch als erfahrender Autor immer wieder mit einem Das ist ganz normal meine Seele gestreichelt hat. Vielen Dank an alle Wicket-Entwickler und die Wicket-Community für ein großartiges Framework und die großartige Unterstützung bei Problemen und Fragen. Und zum Schluss möchte ich noch allen danken, die in dieser Auflistung nicht vorkommen, aber mindestens das Gefühl haben dürfen, dass sie mir während dieser Zeit das Leben leichter gemacht haben. Michael Mosmann, August 2009 XIV