michael MOSMANNPRAXISBUCHWICKETPROFESSIONELLE WEB-2.0-ANWENDUNGEN ENTWICKELN
Mosmann                    Praxisbuch Wicketv    Bleiben Sie einfach auf dem Laufenden:     www.hanser.de/newsletterSofort...
Michael MosmannPraxisbuch WicketProfessionelle Web-2.0-Anwendungenentwickeln
Michael Mosmann, LübeckKontakt: michael@mosmann.deAlle in diesem Buch enthaltenen Informationen, Verfahren und Darstellung...
für meine Eltern
2
InhaltVorwort................................................................................................................
Inhalt         3     Mit Leben füllen .......................................................................................
Inhalt      5.4.2 Kaskadierung von Modellen..................................................................................
Inhalt               7.2.5 Image.............................................................................................
Inhalt       9.9.2 DropDownChoice............................................................................................
Inhalt         11.5      Komponententausch...................................................................................
VorwortIch beschäftige mich seit meiner frühen Jugend mit der Softwareentwicklung. Angefangenhat das auf einem ZX-Spektrum...
Vorwort          Danksagung          Es gab eine Menge Menschen, die mich direkt und indirekt beim Schreiben dieses Buches...
11 EinleitungIch bin im Frühjahr 2008 auf Wicket aufmerksam geworden. Doch da hatte Wicket bereitseine längere Entwicklung...
1 Einleitung         Listing 1.1 Beispiel.java               public void andererCode()         Für HTML-Quelltexte, Proper...
1.1 Warum Wicket?      Im Folgenden wird diese ausführliche Schreibweise gekürzt. Dabei werden alle Felder mit      den en...
1 Einleitung         Aus der umfangreichen Liste der Möglichkeiten habe ich Wicket ausgewählt. Dabei hat         Wicket zu...
1.1 Warum Wicket?Das ermöglicht sehr leistungsfähige und gleichzeitig effektive Komponenten. Da Kompo-nenten ihre Funktion...
1 Einleitung               Wicket-Anwendungen sind sicher. In Wicket werden nur die Parameter der Nutzerin-               ...
1.2 Vorbereitung und Installation1.2   Vorbereitung und Installation      Um Webanwendungen mit Wicket schreiben zu können...
1 Einleitung         waltungssystem (Version Control System, VCS) wird unumgänglich. Aber auch für den         einzelnen E...
1.3 Grundlagen einer Webanwendung1.3.1.1 Persistenz mit HibernateAlle Anwendungen arbeiten mit Daten. Daten werden klassis...
1 Einleitung        Funktionsweise        Mit Hibernate kann man Klassen und deren Attribute auf Datenbanktabellen abbilde...
1.3 Grundlagen einer Webanwendung1.3.2      Verzeichnis und PaketstrukturEs zeigt sich, dass man nie zu früh anfangen kann...
1 Einleitung        1.3.2.2 Besser als Quickstart        Wicket bietet auf der eigenen Webseite eine „Quickstart“-Funktion...
1.3 Grundlagen einer Webanwendung1.3.3.1 Persistenz-TestsAuch mit Hibernate können Unit-Tests durchgeführt werden. Dabei k...
1 Einleitung14
2      2 Aufsetzen der Teilprojekte      Wir schreiben endlich unsere erste eigene Wicket-Anwendung. Die Strukturen, die i...
2 Aufsetzen der Teilprojekte        die Versionsbezeichnung 1.0-SNAPSHOT lauten (das ist die Grundeinstellung von Ma-     ...
2.2 Aufsetzen der TeilprojekteAuf der Kommandozeile erstellt folgende Befehlssequenz ein passendes Projektverzeich-nis (al...
2 Aufsetzen der Teilprojekte        Wie man erkennen kann, finden sich dort unsere Werte für groupId und artifactId       ...
2.2 Aufsetzen der Teilprojekte         <version>${junit.version}</version>         <scope>test</scope>       </dependency>...
2 Aufsetzen der Teilprojekte        2.2.2    Teilprojekt Base        Im Laufe einer langjährigen Entwicklung sammeln sich ...
2.2 Aufsetzen der Teilprojekte      <parent>        ...      </parent>      <artifactId>${pom.groupId}--dbconfig</artifact...
2 Aufsetzen der Teilprojekte        2.2.3.3 Konfigurationsprojekt für die Testdatenbank        Für den Datenbanktest wird ...
2.2 Aufsetzen der Teilprojekte         <artifactId>${pom.groupId}--dbconfig</artifactId>         <version>${pom.version}</...
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Wicket ASDF
Upcoming SlideShare
Loading in...5
×

Wicket ASDF

2,090

Published on

Published in: Sports
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,090
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Wicket ASDF

  1. 1. michael MOSMANNPRAXISBUCHWICKETPROFESSIONELLE WEB-2.0-ANWENDUNGEN ENTWICKELN
  2. 2. Mosmann Praxisbuch Wicketv Bleiben Sie einfach auf dem Laufenden: www.hanser.de/newsletterSofort anmelden und Monat für Monatdie neuesten Infos und Updates erhalten.
  3. 3. Michael MosmannPraxisbuch WicketProfessionelle Web-2.0-Anwendungenentwickeln
  4. 4. Michael Mosmann, LübeckKontakt: michael@mosmann.deAlle in diesem Buch enthaltenen Informationen, Verfahren und Darstellungen wurden nach bestemWissen zusammengestellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen.Aus diesem Grund sind die im vorliegenden Buch enthaltenen Informationen mit keiner Verpflich-tung oder Garantie irgendeiner Art verbunden. Autor und Verlag übernehmen infolgedessen keinejuristische Verantwortung und werden keine daraus folgende oder sonstige Haftung übernehmen, dieauf 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. freivon Schutzrechten Dritter sind. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbe-zeichnungen usw. in diesem Buch berechtigt deshalb auch ohne besondere Kennzeichnung nicht zuder Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung alsfrei 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 Nationalbiblio-grafie; 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, oderTeilen daraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlagesin irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes Verfahren) – auch nicht für Zwecke derUnterrichtsgestaltung – reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, ver-vielfältigt oder verbreitet werden.© 2009 Carl Hanser Verlag München, www.hanser.deLektorat: Margarete MetzgerCopy editing: Jürgen Dubau, FreiburgHerstellung: Irene WeilhartUmschlagdesign: Marc Müller-Bremer, www.rebranding.de, MünchenUmschlagrealisation: Stephan RönigkDatenbelichtung, Druck und Bindung: Kösel, KrugzellAusstattung patentrechtlich geschützt. Kösel FD 351, Patent-Nr. 0748702Printed in GermanyISBN 978-3-446-41909-4
  5. 5. für meine Eltern
  6. 6. 2
  7. 7. InhaltVorwort..............................................................................................................................XIII1 Einleitung ................................................................................................................. 11.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 ...........................................................................................................61.2 Vorbereitung und Installation...................................................................................................7 1.2.1 Java, Maven und Eclipse ............................................................................................7 1.2.2 Versionskontrolle mit Subversion ..............................................................................71.3 Grundlagen einer Webanwendung ...........................................................................................8 1.3.1 Anwendungsschichten................................................................................................8 1.3.2 Verzeichnis und Paketstruktur..................................................................................11 1.3.3 Unit-Tests .................................................................................................................122 Aufsetzen der Teilprojekte .................................................................................... 152.1 Nomenklatur der Teilprojekte ................................................................................................152.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..........................................................................262.3 Erstellen von Eclipse-Projektdateien......................................................................................27 VII
  8. 8. 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......................................................... 61VIII
  9. 9. Inhalt 5.4.2 Kaskadierung von Modellen.....................................................................................62 5.4.3 Automatische Kaskadierung von Modellen..............................................................65 5.4.4 Datenbankzugriffsmodelle........................................................................................665.5 Komplexe Modellklassen.......................................................................................................69 5.5.1 Zugriff auf Bean-Properties......................................................................................69 5.5.2 Die Klasse PropertyModel........................................................................................72 5.5.3 CompoundPropertyModel ........................................................................................745.6 Ausgelagerte Informationen...................................................................................................76 5.6.1 Einfacher Zugriff auf Ressourcen.............................................................................76 5.6.2 ResourceModel.........................................................................................................76 5.6.3 StringResourceModel ...............................................................................................786 Komponenten......................................................................................................... 816.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 ..................................................................................................................856.2 Grundlagen der Vererbung.....................................................................................................85 6.2.1 Eine Seite mit eigenen Komponenten.......................................................................85 6.2.2 Vererbung für Fortgeschrittene................................................................................916.3 Style, Locale und Variation....................................................................................................94 6.3.1 Markup-Variationen .................................................................................................946.4 Sichtbarkeit ............................................................................................................................99 6.4.1 wicket:enclosure.....................................................................................................100 6.4.2 Empfehlung zur Anwendung..................................................................................1016.5 Ajax......................................................................................................................................102 6.5.1 Ajax-Events............................................................................................................103 6.5.2 Einfache Event-Behandlung ...................................................................................104 6.5.3 Automatische Event-Behandlung ...........................................................................1057 Basiskomponenten.............................................................................................. 1097.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 ............................................................................................1267.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
  10. 10. 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.3.7 Formularlinks ......................................................................................................... 144 7.4 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...................................................................................................................... 186X
  11. 11. Inhalt 9.9.2 DropDownChoice...................................................................................................188 9.9.3 ListMultipleChoice.................................................................................................1909.10 Dateien hochladen................................................................................................................192 9.10.1 FileUpload..............................................................................................................192 9.10.2 MultiFileUpload .....................................................................................................1949.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 .................................................................................................1999.12 FormValidator......................................................................................................................201 9.12.1 Passwortprüfung.....................................................................................................201 9.12.2 Eigene Prüfung .......................................................................................................2039.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 .........................................................................................2109.14 AjaxEditableLabel ...............................................................................................................2129.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 ..................................................................................................2189.16 Generierte Formulare ...........................................................................................................2209.17 Verschachtelte Formulare ....................................................................................................22210 Sessions und Security ........................................................................................ 22510.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......................................................................................................................22810.2 Marker an Komponenten......................................................................................................23110.3 Elemente ausblenden............................................................................................................23311 Wicket in der Praxis............................................................................................. 23511.1 Die Integration von Spring...................................................................................................23511.2 Navigation............................................................................................................................23711.3 CSS einbinden......................................................................................................................24411.4 Eigene Basiskomponenten ...................................................................................................250 XI
  12. 12. 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............................................................................................................................ 295XII
  13. 13. VorwortIch beschäftige mich seit meiner frühen Jugend mit der Softwareentwicklung. Angefangenhat das auf einem ZX-Spektrum-Klon in Basic. Im Laufe der Jahre kamen so unterschied-liche Programmiersprachen und Betriebssysteme zusammen. Der Einstieg in die objektori-entierte Programmierung kam mit C++. Die ersten Versuche, Anwendungen mit Benutzer-oberflächen zu schreiben, habe ich auf einem Amiga unternommen. Die Anwendungenwaren klein und der Nutzerkreis beschränkt.Im Juli 1999 fing ich bei Dr. Klein und Co. an und startete mit ersten Anwendungen, dieim Internet zur Verfügung gestellt wurden. Das waren Java-Applets, die z.B. Kreditbe-rechnungen ermöglichten. Nicht viel später entstanden die ersten Webanwendungen, diedamals als Servlets und mit JavaServer Pages realisiert wurden. Die Anwendungen wurdenkomplexer und dieses Entwicklungsmodell stieß zunehmend an seine Grenzen. Mangelsguter Alternativen entstanden so im Laufe der Jahre einige selbst entwickelte Anwen-dungsframeworks. Diese linderten zwar die Probleme etwas, beseitigten das grundlegendeProblem aber nicht.Die Suche nach Alternativen ging weiter und so landete ich im März 2008 auf der Websei-te von Wicket. Ich hatte mir bis dahin so einiges angesehen: GWT, Rails, Thinwire um nureinige 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 grundlegendverändert. Webanwendungen zu schreiben ist so einfach geworden, dass man bei neuenFeatures 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 Problemstel-lungen „Bauchschmerzen“ verursachten, sind diese Anforderungen mit Wicket keine Her-ausforderung und das Entwickeln mit Wicket macht einfach nur Spaß.Die Arbeit kommt vor den Vergnügen. Doch der Spaß sollte nicht lange auf sich wartenlassen. In diesem Sinne: Let’s have some fun. XIII
  14. 14. 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änd- lich 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 vorkom- men, aber mindestens das Gefühl haben dürfen, dass sie mir während dieser Zeit das Leben leichter gemacht haben. Michael Mosmann, August 2009XIV
  15. 15. 11 EinleitungIch bin im Frühjahr 2008 auf Wicket aufmerksam geworden. Doch da hatte Wicket bereitseine längere Entwicklung hinter sich, denn es wird bereits seit 2005 entwickelt. 2006 wur-de Wicket ein offizielles Apache-Projekt, und im Januar 2007 wurde dann das erste Re-lease als Apache-Projekt veröffentlicht. Seit April 2008 setze ich Wicket mit viel Freude inProjekten ein.Die Idee zu diesem Buch entstand, nachdem ich ein paar Monate mit Wicket gearbeitethatte und die Begeisterung für das Framework immer stärker zunahm. Ich hatte zu demZeitpunkt bereits einiges über Wicket gelesen, vermisste aber oft den Praxisbezug der Bei-spiele und Lösungen.Viele Wege führen nach Rom, aber nicht jeder ist kurz oder schnell. Und so habe ich amAnfang auch das eine oder andere Mal eine falsche Abbiegung genommen, die sich zwarnicht als Sackgasse entpuppte, aber teilweise einen gehörigen Umweg darstellte. DiesesBuch soll als Straßenkarte dienen, damit man sich auf den gut ausgebauten Straßen, dieWicket bietet, zurechtfindet.Wer sollte das Buch lesen?Wer Webanwendungen entwickelt oder entwickeln möchte und dabei auf Java als Pro-grammiersprache setzt, wird nach der Lektüre dieses Buches sehr schnell Webanwendun-gen entwickeln können. Dabei werden alle Aspekte beleuchtet, die für das Erstellen einerWebanwendung wichtig und notwendig sind. Entwickler, die bereits Wicket einsetzen,profitieren von den praxisnahen Beispielen und bewährten Lösungen.KonventionenIn diesem Buch gelten folgende Konventionen: Programmcode, Verzeichnisse und Datei-namen werden innerhalb des normalen Textes als code dargestellt. Quelltexte werden ohnebesondere Überschrift als Codeblock dargestellt: public void javacode()Bei der Auszeichnung mit Überschrift wird ein Dateiname angegeben: 1
  16. 16. 1 Einleitung Listing 1.1 Beispiel.java public void andererCode() Für HTML-Quelltexte, Property- und Markup-Dateien wird dieselbe Formatierung wie für Java-Quelltexte benutzt. Wenn durch die begrenzte Breite des Buches Text umbrochen werden muss und das an dieser Stelle nicht möglich ist, wird das unwillkürliche Zeilenen- de durch ein Leerzeichen und „“ angegeben. Nur wenn das „“-Zeichen an letzter Stelle steht, ist ein unwillkürlicher Zeilenumbruch gemeint. Die nächste Zeile wird dann um zwei Leerzeichen gegenüber dem Zeilenanfang eingerückt: Text=Der Text ist zu lang, als dass er auf eine Zeile passen würde, und beginnt auf der neuen Zeile mit zwei Leerzeichen, die ebenfalls ignoriert werden müssen. Ein -Zeichen mittendrin ist in Ordnung. Da sich viele Dinge immer wiederholen, wird im Laufe des Buches das eine oder andere gekürzt. Damit man erkennen kann, ob gekürzt wurde, erscheinen an der entsprechenden Stelle drei Punkte: ... Wenn solche Kürzungen vorgenommen wurden, ist es ebenso wahrscheinlich, dass nur leichte Anpassungen an bereits bestehenden Quelltexten vorgenommen wurden. Diese werden der besseren Übersichtlichkeit halber entsprechend hervorgehoben: ... das stand hier schon doch das ist neu ... Kommandos, die in der Konsole eingeben werden müssen, sind von Natur aus nie mehr- zeilig. Es gelten daher dieselben Regeln zum Umbruch wie bei Quelltexten. Allerdings beginnen Kommandos immer mit einem Dollarzeichen, es sei denn, sie kommen innerhalb des Textes vor. Dann ergibt sich die Bedeutung aus dem Text: $ kommando Java Alle Felder einer Klasse starten mit einem Unterstrich. Wenn eine Klasse als Bean benutzt wird, dann erfolgt der Zugriff auf das Feld durch eine passende set- und get-Methode. Listing 1.2 BeispielBean.java public class BeispielBean { String _titel; public String getTitel() { return _titel; } public void setTitel(String titel) { _titel=titel; } }2
  17. 17. 1.1 Warum Wicket? Im Folgenden wird diese ausführliche Schreibweise gekürzt. Dabei werden alle Felder mit den entsprechenden Typangaben aufgeführt und exemplarisch die Methodennamen für die ersten Felder angegeben. Listing 1.3 BeispielBean.java (gekürzt) public class BeispielBean { String _titel; getTitel(),setTitel(),... } Importanweisungen werden nur aufgeführt, wenn die zu importierende Klasse nicht aus dem Beispielprojekt oder aus dem Wicket-Framework stammt und sich auch nicht in den Java-Standardbibliotheken befindet (z.B. import java.io.Serializable;). Die Kür- zung wird durch ... gekennzeichnet. Markup Für die Darstellung von Komponenten nutzt Wicket einen Template-Mechanismus. Dabei kann einer Komponente eine HTML-Datei zugeordnet werden, in der alle nötigen Struktu- ren für die Darstellung enthalten sind. Diese Datei wird im folgenden Markup genannt. Version Das Buch bezieht sich auf die Wicket-Version 1.4, die mit dem Erscheinen dieses Buches in einer finalen Version verfügbar sein wird. Die Beispiele können begrenzt auch auf Wi- cket 1.3 übertragen werden. Wenn man nicht durch andere Abhängigkeiten gezwungen ist, Wicket noch in einer alten Version einzusetzen, sollte man spätestens jetzt den Schritt wa- gen und auf Wicket in der Version 1.4 migrieren. Online Da die Entwicklung von Wicket immer weiter geht, veröffentliche ich auf der Seite http://www.wicket-praxis.de/blog/ fortlaufend Erfahrungen und Tipps aus der praktischen Arbeit. Wenn Sie mit mir in Kon- takt treten wollen, genügt eine E-Mail an: michael@mosmann.de.1.1 Warum Wicket? Für das Entwickeln von Webanwendungen stehen eine ganze Reihe von Frameworks und Technologien bereit. Die Auswahl fällt schwer, da man die meisten Anforderungen mit einer ganzen Reihe von Technologien umsetzen könnte. Wenn man dann die zu verwen- dende Programmiersprache auf Java eingrenzt, bleiben trotzdem noch einige Frameworks übrig, die um die Gunst der Programmierer wetteifern. 3
  18. 18. 1 Einleitung Aus der umfangreichen Liste der Möglichkeiten habe ich Wicket ausgewählt. Dabei hat Wicket zunächst mit recht einfachen Mitteln mein Interesse geweckt: Es gibt eine sehr einfache und schnelle Möglichkeit, ein Testprojekt aufzusetzen. Die- ses kann sofort gestartet werden und zeigt ein minimales Grundgerüst einer Wicket- Anwendung. Die bestehende Anwendung kann einfach verändert werden, was zu einem sehr schnel- len Erfolgserlebnis führt. Die Lernkurve für die ersten Gehversuche ist sehr gering. Nachdem ich auf diese Weise sehr schnell einen ersten Eindruck gewinnen konnte, habe ich mich eingehender mit Wicket beschäftigt. Nach einer kurzen Einarbeitungsphase und einigen kleinen Beispielanwendungen war ich mir sicher, dass ich Wicket für meine zu- künftigen Webprojekte einsetzen werde. Die Kriterien, die für Wicket sprechen, habe ich an eine Übersicht auf der Webseite des Wicket-Projektes 1 angelehnt, beschränke mich aber hier auf die für mich besonders wichtigen Aspekte. 1.1.1 Einfach, Konsistent, Offensichtlich Ich empfehle als Einstieg eine kleine Beispielanwendung, die man sich über die „Quick- start“-Funktion 2 generieren lassen kann. Anhand dieser Anwendung kann man einige der folgenden Punkte recht schnell nachvollziehen: Alles kann in Java realisiert werden. Das Grundprinzip erinnert an Swing und ist leicht zu verstehen. Es müssen keine Konfigurationsdateien erstellt werden. Wicket-Anwendungen können einfach für Suchmaschinen optimiert werden. Hervorragende Unterstützung bei der Fehlersuche durch ausführliche Informationen im Entwicklungsmodus. Wicket benötigt keine speziellen Vorbereitungen oder Vorarbeiten. Wicket ist einfach nur Java. Wicket-Anwendungen können über Unit-Tests getestet werden. Es ist für mich einer der größten Vorteile, dass alles in Java ausgedrückt werden muss. Es gibt nur eine Stelle, an der ein Fehler auftreten kann: im Code. Mit den sehr ausführlichen Fehlermeldungen kann der Fehler sehr schnell eingegrenzt und behoben werden. 1.1.2 Wiederverwendbarkeit Wicket ist zwar nicht das einzige Framework, bei dem man auch bei Komponenten auf Vererbung zurückgreifen kann, doch das einzige, bei dem das sehr einfach umzusetzen ist. 1 http://wicket.apache.org/introduction.html 2 http://wicket.apache.org/quickstart.html4
  19. 19. 1.1 Warum Wicket?Das ermöglicht sehr leistungsfähige und gleichzeitig effektive Komponenten. Da Kompo-nenten ihre Funktionalität vollständig in sich kapseln, kann man sie innerhalb derselbenAnwendung beliebig oft nutzen, sodass komplexe Anwendungen sehr schnell realisiertwerden können. Wicket-Komponenten können auch anwendungsunabhängig entwickeltwerden. Alle notwendigen Daten und Informationen können in eine Java-Bibliothek ausge-lagert und dann in verschiedensten Projekten eingesetzt werden. Dazu muss die Bibliotheknur in das Projekt eingebunden werden. Auf diese Weise profitiert man sogar in allennachfolgenden Wicket-Projekten von der eigenen Entwicklungsarbeit, da man oft fast alleallgemeinen Komponenten wiederverwenden kann. So entsteht auch hier eine Bibliothekvon Lösungen, wie man sie aus anderen Bereichen der Anwendungsentwicklung kennt.1.1.3 Sauber getrenntWer Wicket zum ersten Mal testet und vorher schon Erfahrungen mit JSP, JSF oder ähnli-chen Ansätzen gemacht hat, wundert sich, dass im Markup (HTML-Schnipsel, die zurKomponente gehören und für die Darstellung wichtig sind) keine Code-Bestandteile zufinden sind. Dieser Punkt irritiert so stark, dass er immer wieder z.B. in Mailinglisten the-matisiert wird. Während der Arbeit mit Wicket offenbart dieses Konzept seine Vorteile: Im Markup befinden sich nur Referenzen auf Komponenten, aber kein Code oder spe- zielle Logik. Die Komplexität und der Funktionsreichtum der Anwendung werden nur durch Java als Programmiersprache und nicht durch eine in ihrer Ausdruckstärke ein- geschränkten Auszeichnungssprache begrenzt. Programmcode entsteht auf diese Weise nur an einer Stelle und in einer Sprache. Die Markup-Dateien für die Komponenten können mit einfachen Textprogrammen oder mit HTML-Editoren bearbeitet werden. Da Wicket keine besondere Notation er- fordert, gehen bei der Bearbeitung keine Informationen verloren, sodass die Gestaltung der Vorlagen z.B. durch einen Webdesigner angepasst werden kann. So wird die Ar- beitsteilung zwischen Entwickler und Gestalter gut unterstützt. Im Zweifelsfall muss nur die versehentlich gelöschte Bezeichnung der Komponente wiederhergestellt wer- den. Auf alle positiven Skalierungseffekte im Entwicklungsprozess durch die Nutzung von Java als Programmiersprache und den darauf aufsetzenden unterstützenden Werkzeu- gen kann bei der Entwicklung von Anwendungen mit Wicket zurückgegriffen werden. Die Komponentenarchitektur unterstützt diesen Aspekt zusätzlich.1.1.4 SicherJe nach verwendetem Framework sind Webanwendungen mehr oder weniger anfällig fürCode-Injection 3-, XSS 4- und andere Attacken.3 http://en.wikipedia.org/wiki/Code_injection4 http://en.wikipedia.org/wiki/Cross-site_scripting 5
  20. 20. 1 Einleitung Wicket-Anwendungen sind sicher. In Wicket werden nur die Parameter der Nutzerin- teraktion in der URL kodiert. Der Zustand der Anwendung wird serverseitig gespei- chert, sodass eine Kodierung dieser Information in URL-Parameter nicht notwendig ist. Das Einschleusen von Schadcode über manipulierte Parameter ist somit weitestgehend ausgeschlossen. Möchte man den Zustand einer Anwendung durch URL-Parameter steuerbar gestalten, muss man diese Möglichkeit explizit bereitstellen. Da Wicket-Anwendungen vollständig in Java realisiert werden, stehen alle Sicherheits- aspekte der Java-Plattform zur Verfügung. 1.1.5 Effizient und skalierbar Jede Abstraktion oder Zwischenschicht zieht ein anderes Laufzeitverhalten nach sich. Wie stark die Einschnitte in den verschiedenen Bereichen sind, hängt von der eingesetzten Lösung ab. Wicket gehört zu den leichtgewichtigen Lösungen. Der architekturelle Überbau hat dabei kaum Auswirkungen auf die Gesamtperformance. Da Wicket vollständig in Java realisiert wurde, können zudem zusätzlich zu den klassischen Lösungsansätzen für die Lastverteilung in Webanwendungen andere, auf die Lastverteilung von Java-Anwendun- gen spezialisierte Produkte eingesetzt werden (z.B. Terracotta 5). 1.1.6 Komplett Webanwendungen können vollständig mit den in Wicket enthaltenen Komponenten umge- setzt werden. Man muss also nicht in Vorleistung gehen und sich ein eigenes Anwen- dungsgerüst schaffen. Es ist allerdings derart einfach, eigene Anpassungen vorzunehmen, eigene Komponenten zu entwickeln oder einfach fremde Komponenten zu benutzen, dass man sich schnell an die erweiterten Möglichkeiten gewöhnt und rückblickend feststellen muss, wie reduziert bisherige Lösungen und die damit realisierten Anwendungen waren. 1.1.7 Eine gute Wahl Mit Wicket zu arbeiten macht Spaß. Die Komplexität von mit Wicket realisierbaren An- wendungen übersteigt die Komplexität solcher Anwendungen, die mit anderen Webtech- nologien umgesetzt werden können, bei Weitem. Die Komponentenarchitektur gewährleis- tet dennoch eine große Übersichtlichkeit, sodass der Einarbeitungsaufwand sehr viel ge- ringer ist, was sich gerade bei der Anpassung von bestehenden Anwendungen positiv be- merkbar macht. Wer Webanwendungen entwickelt, sollte Wicket also unbedingt ausprobieren. 5 http://www.terracotta.org/6
  21. 21. 1.2 Vorbereitung und Installation1.2 Vorbereitung und Installation Um Webanwendungen mit Wicket schreiben zu können, bedarf es weniger Vorraussetzun- gen. Im Prinzip reichen Java und ein Texteditor. Wenn man ernsthaft Webanwendungen entwickeln möchte, kommt man aber um ein etwas komplizierteres Setup nicht herum. Da- für bekommt man dann aber auch eine Menge an nützlichen Funktionen und Hilfsmitteln. 1.2.1 Java, Maven und Eclipse Java Für Wicket benötigt man ein Java Development Kit (JDK) ab Version 5. Eine Java Runti- me Environment (JRE) reicht zum Entwickeln nicht aus. Unter Windows laden Sie die Installationsdateien einfach von der Javaseite 6 von Sun herunter und starten die Installa- tion. Unter Linux sollte man Java über das integrierte Paketmanagement installieren. Apache Maven Damit man den Java-Compiler nicht immer von Hand in der Kommandozeile starten muss, haben sich im Laufe der Zeit unterschiedliche Ansätze und Lösungen für dieses Problem entwickelt. In diesem Buch und auch sonst bevorzuge ich Maven für das Build-Manage- ment. Für die Installation lädt man das passende Archiv von der Apache-Maven-Seite 7 herunter und folgt den Installationsanweisungen auf der Seite. Eclipse Für das Buch empfehle ich als Entwicklungsumgebung Eclipse 8. Dafür gibt es zwei Grün- de: Eclipse ist kostenlos. Maven-Projekte können sehr einfach in Eclipse importiert werden. Alle definierten Abhängigkeiten werden dabei in die Eclipse-Projekte übernommen. Ich empfehle für dieses Buch Eclipse IDE for Java EE Developers ab Version 3.4. Ein Plugin für Maven kann installiert werden. Das ist aber nicht notwendig, weil Maven die Eclipse-Projekte ohne fremde Hilfe erzeugt. 1.2.2 Versionskontrolle mit Subversion Ein regelmäßiges Backup ist ein gutes Ruhekissen. Auf diese Weise kann man jederzeit einen älteren Zustand wiederherstellen. Spätestens, wenn man mit mehreren Entwicklern an einem Projekt arbeitet, funktioniert das Backup-Prinzip nicht mehr. Ein Versionsver- 6 http://java.sun.com/javase/downloads/index.jsp 7 http://maven.apache.org/ 8 http://www.eclipse.org/ 7
  22. 22. 1 Einleitung waltungssystem (Version Control System, VCS) wird unumgänglich. Aber auch für den einzelnen Entwickler bringt der Einsatz eines VCS erhebliche Vorteile. Man kann in der Entwicklung gefahrlos verzweigen und diesen Entwicklungszweig wieder mit dem Haupt- zweig zusammenführen. Man kann Dinge ausprobieren und jederzeit wieder auf einen älte- ren (nicht nur den letzten) Stand zurücksetzen. Subversion hat sich als Standard etabliert und kann über Plugins recht gut in Eclipse integriert werden. Empfehlungen Für die Arbeit an einem Projekt empfiehlt es sich unter Windows, sowohl das Eclipse- Plugin 9 als auch das Windows Explorer-Plugin TortoiseSVN 10 zu installieren. Unter Linux kann man alle Aufgaben über die Kommandozeile durchführen und sollte daher Subver- sion über die Paketverwaltung installieren. Da das Eclipse-Plugin eine eigene Subversion- Bibliothek mitbringt, ist darauf zu achten, dass die Subversion-Client-Version in beiden Fällen dieselbe ist, da sich das Ablageformat teilweise unterscheidet und der ältere Client dann nicht mehr auf die Daten zugreifen kann, wenn der neuere Client sie erst einmal in das neuere Format konvertiert hat. Wer keinen eigenen Subversion-Server aufsetzen möchte, kann auch auf Subversion- Hosting-Angebote 11 zurückgreifen.1.3 Grundlagen einer Webanwendung Wicket ist im Gegensatz zu Grails oder Rails kein Framework, das alle Aspekte einer Webanwendung, z.B. den Datenbankzugriff, in einem Paket bündelt. Wir müssen uns da- her selbst um die notwendigen Bibliotheken bemühen, was uns aber vor keine großen Her- ausforderungen stellen wird. 1.3.1 Anwendungsschichten Das Buch hat den Anspruch, alle wesentlichen Aspekte der Entwicklungen von Weban- wendungen abzubilden. Dazu gehört neben der Präsentationsschicht, bei der Wicket zum Einsatz kommt, die Schicht der Anwendungslogik (Business Logic) und die der Datenhal- tung (Persistenz) (siehe den Wikipedia-Eintrag zur Drei-Schichten-Architektur 12). Da auch die Präsentationsschicht vollständig in Java realisiert wird, ist die Anbindung an die ande- ren Applikationsschichten besonders einfach. Das Zusammenfügen der verschiedenen Anwendungsschichten geschieht nicht mehr durch Programmcode, sondern durch den Ein- satz eines Dependency Injection 13-Frameworks. 9 http://subclipse.tigris.org/ 10 http://tortoisesvn.tigris.org/ 11 http://www.svnhostingcomparison.com/ 12 http://de.wikipedia.org/wiki/3-Tier#Drei-Schichten-Architektur 13 http://de.wikipedia.org/wiki/Dependency_Injection8
  23. 23. 1.3 Grundlagen einer Webanwendung1.3.1.1 Persistenz mit HibernateAlle Anwendungen arbeiten mit Daten. Daten werden klassisch in Datenbanksystemenabgelegt. Relationale Datenbanksysteme bilden Daten in Tabellen ab, die miteinander ver-knüpft werden können. In den Spalten einer Tabelle werden die verschiedenen Attributeeines Datensatzes abgelegt, jede Zeile steht für einen eigenständigen Datensatz.Objektorientierte Sprachen können mit Objekten und Beziehungen von Objekten unterein-ander arbeiten. Die Datenhaltung in Tabellen unterscheidet sich derart von den Möglich-keiten objektorientierter Datenhaltung, dass die Modelle nicht automatisch aufeinanderabbildbar sind. Es gibt Speziallösungen, die Objekte und deren Beziehung in einer Objekt-datenbank 14 abbilden können. Diese Speziallösungen konnten sich bis heute aus verschie-denen Gründen nicht durchsetzen.Daher wurde für die Anbindung von relationalen Datenbanksystemen OR-Mapper 15 ent-wickelt, die es sowohl für verschiedene Programmiersprachen als auch für unterschiedlicheDatenbanksysteme gibt. Diese OR-Mapper übernehmen die Transformation der unter-schiedlichen Modelle ineinander. Dabei wird meist ein Objekt auf eine Tabelle und dieEigenschaften des Objekts auf die Spalten einer Tabelle abgebildet. Diese Methode ist beider Abbildung von komplexen Objektbeziehungen natürlich limitiert, hat gegenüber denSpeziallösungen aber den entscheidenden Vorteil, dass auf bewährte Technologien zurück-gegriffen werden kann.Für die Datenbankanbindung in Java gibt es JDBC mit den entsprechenden datenbankab-hängigen Treibern. Der Zugriff erfolgt in Tabellenform. Im Prinzip sind damit alle Anfor-derungen an eine Datenbankschnittstelle erfüllt. Die Anbindung an eigene Applikationenist dennoch recht kompliziert und mit vielen Fallstricken versehen.Eine objektorientierte Darstellung der Daten und deren Transformation in die Tabellen-struktur der Datenbank hat auf Seiten der Anwendungsentwicklung zu wesentlich schnelle-ren Ergebnissen geführt. Außerdem kann der Zugriff auf die Daten in Abhängigkeit vonder Datenbank optimiert werden. OR-Mapper stellen daher neben der Transformation derDaten meist grundlegende Datenbankoperationen zur Verfügung.Warum Hibernate?In diesem Buch und auch sonst empfehle ich Hibernate als Persistenz-Framework. DieWahl fiel auf Hibernate, weil es einfach zu benutzen und am Markt etabliert ist. Es zeich-net sich ähnlich wie Wicket durch eine gute Java-Integration aus. Natürlich kann man je-des andere Persistenz-Framework mit Wicket benutzen. Wicket bietet keine besondereHibernate-Integration, sodass die aufgezeigten Lösungsvorschläge auch auf andere Frame-works abgebildet werden können.14 http://de.wikipedia.org/wiki/Objektorientierte_Datenbank15 http://de.wikipedia.org/wiki/Objektrelationale_Abbildung 9
  24. 24. 1 Einleitung Funktionsweise Mit Hibernate kann man Klassen und deren Attribute auf Datenbanktabellen abbilden. Be- ziehungen untereinander können ebenso abgebildet werden. Hibernate sorgt dabei für die Transformation der Daten und Abhängigkeiten in ein für die Datenbank verständliches Format. Die Informationen, auf welche Tabelle und auf welchen Spalten die Objekte abge- bildet werden, können sowohl in der Klasse selbst (per Annotation) als auch in gesonder- ten Konfigurationsdateien abgelegt werden. Der Zugriff auf die Daten kann über eine ob- jektorientierte Alternative zu SQL (HQL) oder über eine Schnittstelle erfolgen. Die Trans- formation in Objekte erfolgt transparent. 1.3.1.2 Dependency Injection mit dem Spring-Framework In klassischen objektorientierten Anwendungen ist jedes Objekt selbst dafür verantwort- lich, die Abhängigkeiten aufzulösen sowie die notwendigen Ressourcen zu erzeugen und zu verwalten. Dazu muss jedes Objekt über Informationen seiner Umgebung verfügen. Dependency Injection verlagert die Verantwortung für das Finden und Verwalten von Res- sourcen und Abhängigkeiten aus dem Objekt in ein Framework. Das Framework erzeugt über Konfigurationsdateien oder Metainformationen in den Klassen die Anwendungs- module und löst die definierten Abhängigkeiten auf. Dieses Vorgehen reduziert die Ab- hängigkeit der Klasse zur Umgebung und zu konkreten Umsetzungen der abhängigen Mo- dule. Warum Spring? Das Spring-Framework wurde aus ähnlichen Gründen wie Hibernate ausgewählt. Und ähn- lich wie bei Hibernate kann auch dieser Aspekt durch ein anderes Framework abgebildet werden. Wie gut die Ergebnisse in diesem Buch dann übertragbar sind, hängt sehr stark von dem verwendeten Framework ab. Spring benutzt für die Konfiguration XML-Dateien. In diesen Dateien werden die Objekte mit Namen versehen und die Konfiguration der Attribute vorgenommen. Die Abhängigkei- ten von Objekten können über Referenzen und deren Übergabe in Attribute vorgenommen werden. Eine Anwendung lädt über Funktionen des Frameworks eine Spring-Konfigura- tion und kann dann über den Namen auf die Objekte bekannten Typs zugreifen. Spring ist somit einfach in jede Java-Anwendung integrierbar. 1.3.1.3 Anwendungslogik und Präsentation mit Wicket Die Architektur von Wicket folgt dem Model-View-Controller 16-Ansatz (Modell-Präsen- tation-Steuerung). Das Modell beinhaltet die darzustellenden Daten, der Controller über- nimmt die Steuerung der Interaktionsmöglichkeiten, und in der Präsentationsschicht wer- den diese Daten dann dargestellt. 16 http://de.wikipedia.org/wiki/MVC10
  25. 25. 1.3 Grundlagen einer Webanwendung1.3.2 Verzeichnis und PaketstrukturEs zeigt sich, dass man nie zu früh anfangen kann, seine Softwareprojekte gut zu struktu-rieren. Ich lege daher für jede Anwendungsschicht mindestens ein eigenständiges Teilpro-jekt an. Das verkürzt den Entwicklungszyklus und verbessert die Übersichtlichkeit.1.3.2.1 Projektverwaltung mit MavenFür das Erstellen der Teilprojekte und die Abhängigkeitsverwaltung setze ich Maven ein.Maven ist dabei ein Build-Tool mit vielfältigen Möglichkeiten. Alternativen zu Mavensind z.B. Ant 17 mit Ivy 18 oder Buildr 19. Build-Tools sind hauptsächlich für das Erstellender ausführbaren Programme aus vorhandenen Quelltexten zuständig. Das Aufgabenspekt-rum hat sich spätestens seit Maven in der Version 1.0 grundlegend erweitert und umfasstseither vor allem auch die Abhängigkeitsverwaltung. Weitere Funktionalitäten können fastbeliebig durch Plugins erweitert werden und reichen vom Erstellen von Dokumentations-seiten bis zum Deployment der Anwendung auf Produktivsystemen.Das Grundprinzip von Maven ist einfach. In einem Verzeichnis gibt es ein vorgeschriebe-nes Verzeichnislayout für ein Projekt: pom.xml src main java resources test java resourcesDazu benötigt Maven neben einer sehr einfach gehaltenen Projektdefinitionsdatei(pom.xml), die minimale Informationen zum Projekt enthält, die notwendigen Java-Quelltexte in standardisierten Verzeichnissen. Maven sucht dann für das Erstellen des Pro-jekts z.B. im Verzeichnis src/main/java nach Java-Dateien und kompiliert diese. Insrc/test/java befinden sich Unit-Tests, die beim vollständigen Erstellen der Anwen-dung ausgeführt werden. In den jeweiligen resource-Verzeichnissen befinden sich alleanderen Dateien (Grafiken, Texte etc.).In der Projektdefinitionsdatei können auch die Abhängigkeiten zu den anderen Teilprojek-ten oder zu anderen Bibliotheken eingestellt werden, wobei Maven diese Abhängigkeitenselbstständig auflöst und die referenzierten Bibliotheken automatisch aus einem Verzeich-nis herunterlädt und lokal vorhält. Wurde eine Bibliothek bereits einmal heruntergeladen,greift Maven auf die in einem lokalen Verzeichnis abgelegte Version zurück.Über Plugins ist es außerdem möglich, die Webanwendung direkt aus dem Projektver-zeichnis heraus starten zu können. Auf diese Weise können sogar Anpassungen an der lau-fenden Anwendung vorgenommen werden.17 http://ant.apache.org/18 http://ant.apache.org/ivy/19 http://incubator.apache.org/buildr/ 11
  26. 26. 1 Einleitung 1.3.2.2 Besser als Quickstart Wicket bietet auf der eigenen Webseite eine „Quickstart“-Funktion, die ein einfaches Wi- cket-Anwendungsgerüst erstellt, das sofort lauffähig ist. Für einen ersten Test sollte man sich mit „Quickstart“ ein Testprojekt erstellen lassen. Allerdings empfehle ich, dieses Pro- jekt für eigene Entwicklungen nicht weiter zu verwenden. Dafür gibt es verschiedene Gründe. Der Wichtigste für mich: Das Projekt benutzt angepasste Einstellungen, die so nicht nötig sind und vom Standard abweichen. Außerdem ist es hilfreich, wenn man alle Anpassungen, die man im Laufe des Entwick- lungsprozesses vorgenommen hat, selbst durchführt. Dann kann man z.B. dokumentieren, was die Anpassung bewirkt, was sich neben der besseren Dokumentation des eigenen Pro- jekts positiv auf die Fehlersuche auswirkt. 1.3.3 Unit-Tests Irren ist menschlich. Doch Fehler in Anwendungen sind ärgerlich. Fehler in der eigenen Anwendung kann man aber vermeiden. Denn je komplexer die Anwendungen werden, desto mehr Zeit benötigt man, um selbst triviale Fehler einzugrenzen. Eine Methode, die Anzahl der Fehler mit jedem Entwicklungsschritt nachhaltig einzudämmen, nennt sich „Test Driven Development“. Dabei geht es im Prinzip darum, für jede Zeile Programm wieder ein Programm zu schreiben, das die Funktionsfähigkeit und das Ergebnis überprüft. Was sich im ersten Moment etwas „verrückt“ anhört, stellt sich nach kurzer Zeit als un- glaublich entlastendes Instrument dar. Wenn das Teilprojekt mit den automatisch ablau- fenden Tests erstellt werden konnte, kann man sich ziemlich sicher sein, dass es genauso stabil läuft wie vor der letzten Anpassung. Unit-Tests (Modul- bzw. Komponententests) unterscheiden sich vom normalen Programm- code nur dadurch, dass die Namen der Klassen meist mit „Test“ anfangen und die Metho- den der Klasse z.B. „testIrgendetwas“ heißen. Wenn man mit Maven ein Projekt kompi- liert, dann werden die nach dieser Nomenklatur erstellten Klassen und Funktionen ausge- führt. Wenn dann in so einem Test ein Fehler auftritt und der Test somit fehlschlägt, kann das ganze Projekt nicht gebaut werden und wird daher auch nicht für andere Projekte, die dieses Teilprojekt eingebunden haben, zur Verfügung gestellt. So kann sichergestellt wer- den, dass alle Abhängigkeiten in einem fehlerfreien Zustand sind. Wenn in einem Test Fehler auftreten, kann man die Suche nach der Ursache sehr stark ein- schränken. Denselben Fehler innerhalb einer laufenden Anwendung zu isolieren, ist sehr viel aufwendiger. Außerdem bietet ein gut formulierter Test einen hervorragenden Sicher- heitsfallschirm für den Fall, das man z.B. Optimierungen vornimmt oder die Funktionalität erweitert. Wenn die Tests nach einer solchen Anpassung immer noch funktionieren, kann man fast davon ausgehen, dass auch die Anwendung, die auf diese Funktionen aufbaut, immer noch funktioniert.12
  27. 27. 1.3 Grundlagen einer Webanwendung1.3.3.1 Persistenz-TestsAuch mit Hibernate können Unit-Tests durchgeführt werden. Dabei kann eine temporäreDatenbank benutzt werden, die nur zur Laufzeit des Tests vorhanden ist und keinerlei Da-ten enthält. Das bedeutet, dass Nebeneffekte durch bereits bestehende Daten ausgeschlos-sen werden können. Somit kann man alle Datenbankoperationen (z.B. Löschen) ohne dieGefährdung von Produktivsystemen testen.1.3.3.2 User-Interface-TestsMit Wicket können Teile von Wicket-Anwendungen und -Komponenten getestet werden.Auch wenn die Testbarkeit sicher mit Einschränkungen behaftet ist, geht die Testabde-ckung und die Einfachheit beim Erstellen eigener Test weit über das hinaus, was mit ande-ren Frameworks realisierbar ist. Das macht Wicket in diesem Bereich einmalig.ZusammenfassungInteressanterweise unterscheidet sich unsere Auswahl nur unwesentlich von den Bibliothe-ken, die auch Grails benutzt, sicherlich auch, weil wir ebenso wie das Grails-Projekt aufetablierte Standards setzen. Auch wenn der Aufwand für das Aufsetzen eines Projektesungleich höher ist, bewahren wir so die Flexibilität, die es uns erlauben würde, z.B. einanderes Persistence-Framework einzusetzen. Allerdings ist zu beachten, dass diese Auf-wände nur einmal in einem Projekt anfallen und damit selten eine große Rolle spielen. 13
  28. 28. 1 Einleitung14
  29. 29. 2 2 Aufsetzen der Teilprojekte Wir schreiben endlich unsere erste eigene Wicket-Anwendung. Die Strukturen, die im Folgenden erstellt werden, sollten sich durch leichte Modifikationen auf andere Projekte anwenden lassen. In den folgenden Abschnitten erstellen wir zuerst das notwendige Grundgerüst mit allen Abhängigkeiten zu externen Bibliotheken und eigenen Teilprojekten. Im zweiten Schritt hauchen wir dem Ganzen Leben ein. Als Erstes sollte man sich für dieses Projekt ein Verzeichnis anlegen, in dem künftig alle Teilprojekte und sonstige Daten beheimatet sind. Es empfiehlt sich, auf Leerzeichen in den Verzeichnisnamen zu verzichten, sonst kann es zu unnötigen Komplikationen kommen.2.1 Nomenklatur der Teilprojekte Maven benutzt für das Auflösen von Abhängigkeiten drei Informationen, die in einem Pro- jekt angegeben werden müssen: groupId: Bezeichnet eine Gruppe, in der die Artefakte zusammengefasst werden. Die Gruppen- ID hat eher organisatorische Gründe und ist leider ungeeignet, Namenskollisionen zu vermeiden. Im Dateinamen der fertigen Bibliothek kommt dieser Bezeichner nicht vor, sodass es zu Dateinamenskollisionen kommen kann, wenn aus unterschiedlichen Grup- pen Artefakte mit derselben Versionsnummer und artifactId benutzt werden. artifactId: Diese ID gibt dem Projekt seinen Namen. Diese ID findet sich später auch im Datei- namen der erzeugten Bibliothek und im Projektnamen in Eclipse wieder. version: Version des Projekts. Eine gute Versionierung sollte eigentlich bei 0.1 anfangen. Ich persönlich finde es akzep- tabel, in diesem Buch bei Version 1.0 anzufangen. Allerdings wird bis zur Fertigstellung 15
  30. 30. 2 Aufsetzen der Teilprojekte die Versionsbezeichnung 1.0-SNAPSHOT lauten (das ist die Grundeinstellung von Ma- ven). Dieses Versionierungsschema empfiehlt sich aus zwei Gründen. Zum einen wird auf diese Weise das Teilprojekt als „in Arbeit“ gekennzeichnet und sorgt zum anderen bei Maven dafür, dass beim Auflösen dieser Abhängigkeiten regelmäßig geprüft wird, ob eine Version mit einem neueren Zeitstempel existiert. Wenn man allein an einem Projekt ent- wickelt, wird sich da kein Unterschied bemerkbar machen. Wenn man aber im Team ent- wickelt und ein Continuous-Build-System 1 zum Einsatz kommt, ist nur so gewährleistet, dass man die aktuellste Version eines Teilprojektes benutzt. Da die groupId aus oben genannten Gründen nicht zur Strukturierung von Projekten he- rangezogen werden kann, handhabe ich die Bezeichnung der Projekte wie folgt: In groupId schreibe ich den Domainnamen des Projekts in umgekehrter Reihenfolge. Wenn es ein Unterprojekt für eine existierende Domain ist, hänge ich ein „pro- jekt.<projektname>“ an. Der Wert in artifactId fängt mit dem Wert aus groupId an und wird, gefolgt von „--“, um einen Namen für dieses Teilprojekt ergänzt. Der Verzeichnisname für dieses Teilprojekt entspricht dem Wert in artifactId. Für dieses Beispiel benutze ich als groupId den Wert „de.wicketpraxis“. Ein Teilpro- jekt hat demzufolge als artifactId den Wert „de.wicketpraxis--teilprojekt“. Das Verzeichnis, in dem alle Daten dieses Teilprojektes enthalten sind, hat ebenso diesen Na- men.2.2 Aufsetzen der Teilprojekte Beim Erstellen der Teilprojekte arbeiten wir uns von der Basis an aufwärts, wobei die höchste Schicht die Präsentationsschicht ist, in diesem Fall also Wicket. Ziel ist es, am Ende ein vollständiges Projekt mit allen notwendigen Teilprojekten zu erhalten. Im zwei- ten Schritt wird für jede Schicht eine beispielhafte Funktionalität realisiert, die das Funk- tionieren und das Zusammenspiel der verschiedenen Schichten veranschaulicht. 2.2.1 Projektbasis ParentPom Als erstes benötigen wir ein Maven-Projekt, in dem alle teilprojektübergreifenden Einstel- lungen und Abhängigkeiten abgelegt werden. Dazu legen wir ein Projekt unter de.wicketpraxis–-parentPom an. Der Name parentPom wurde gewählt, weil in diesem Teilprojekt übergreifende Einstellungen vorgenommen werden können. Außerdem kann zum Schluss die ganze Anwendung über dieses Projekt erstellt werden, weil die Teilpro- jekte entsprechend konfiguriert wurden. 1 http://www.theasolutions.com/tutorials/scrum_agile.jsp16
  31. 31. 2.2 Aufsetzen der TeilprojekteAuf der Kommandozeile erstellt folgende Befehlssequenz ein passendes Projektverzeich-nis (alles gehört in eine Eingabezeile und wurde nur zur besseren Übersicht mehrzeiliggeschrieben): $ mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=de.wicketpraxis -DartifactId=de.wicketpraxis--parentPomDabei legt Maven erfreulicher Weise gleich ein Verzeichnis passend zur artifactId an.In diesem Verzeichnis finden sich folgende Verzeichnisse: src main java resources test java resourcesIn main/java finden sich die Quelltexte der Anwendung. In main/resources wird allesabgelegt, was in diesem Projekt sonst noch an Daten benutzt wird. Dazu gehören z.B. Bil-der oder Konfigurationsdateien. Unter test/java werden die Quelltexte für die Unit-Testsabgelegt, die in dem Test auf die Ressourcen unter test/resources zurückgreifen kön-nen. Programmcode und Daten aus dem test-Ordner werden nicht in der Bibliotheksdateiweitergegeben.Jetzt kann man mit $ mvn installauf der Kommandozeile das Projekt erstellen lassen. Wenn alles richtig konfiguriert wurdeund alle Tests erfolgreich abgeschlossen werden konnten, erscheint am Ende die Ausgabe: ... [INFO] ---------------------------------------------------------------- [INFO] BUILD SUCCESSFUL [INFO] ---------------------------------------------------------------- ...In dem generierten Projektverzeichnis befindet sich außerdem die Projektdatei pom.xmlmit folgendem Inhalt: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.wicketpraxis</groupId> <artifactId>de.wicketpraxis--parentPom</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>de.wicketpraxis--parentPom</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project> 17
  32. 32. 2 Aufsetzen der Teilprojekte Wie man erkennen kann, finden sich dort unsere Werte für groupId und artifactId wieder. Außerdem sind noch zwei Bereiche von besonderem Interesse. Der Parameter „packaging“ ist auf dem Wert „jar“ gesetzt, was bedeutet, dass aus diesem Projekt eine normale Bibliothek in einer JAR-Datei erzeugt wird. Der zweite interessante Aspekt ist im Bereich dependencies zu finden. Dort wird eine Bibliothek als Abhängigkeit definiert, die für das Ausführen der Unit-Tests vorhanden sein muss. Man kann auch hier wieder die drei relevanten Parameter für die Adressierung die- ser Abhängigkeit erkennen. Zusätzlich ist der Parameter scope aufgeführt, bei dem der Wert test darauf hinweist, dass diese Bibliothek nur für die Unit-Tests benutzt wird. Jetzt passen wir die Projektbeschreibungsdatei wie folgt an: Listing 2.1 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion> <groupId>de.wicketpraxis</groupId> <artifactId>de.wicketpraxis--parentPom</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - Parent Pom)</name> <url>http://wicketpraxis.de</url> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId>18
  33. 33. 2.2 Aufsetzen der Teilprojekte <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>${slf4j.version}</version> </dependency> </dependencies> <properties> <junit.version>3.8.1</junit.version> <slf4j.version>1.4.2</slf4j.version> </properties> </project>Diese Projektdefinition wird nachher von allen anderen Teilprojekten referenziert und de-finiert somit die Grundeinstellung für alle Teilprojekte. Folgende Anpassung habe ich vor-genommen: An der Stelle, wo <project ...> steht, habe ich die Darstellung aus Platzgründen gekürzt. Die Angaben an dieser Stelle entsprechen den automatisch generierten. Der Parameter packaging muss für dieses Teilprojekt auf pom gesetzt werden. Die Platzhalter wie z.B. ${pom.groupId} werden durch die aktuell definierten Inhalte ersetzt. Damit erspart man sich einerseits Schreibaufwand und kann andererseits be- stimmte Informationen an einer Stelle bündeln (z.B. die Versionen für die Abhängig- keiten im Bereich properties). Mit dem Compiler-Plugin (maven-compiler-plugin) wird die Java-Version auf 1.5 gesetzt. Damit benötigt die Anwendung mindestens ein Java 5 oder Java 6. Außerdem wird die Kodierung für die Quellcodedateien auf UTF-8 gesetzt. Das Maven-Resource-Plugin (maven-resources-plugin) sorgt dafür, dass alle Res- sourcendateien mit UTF-8-Kodierung eingebunden werden. Es empfiehlt sich, mithilfe des Maven-Source-Plugins (maven-source-plugin) auch die Quelltexte zum Projekt in ein Archiv packen zu lassen. So kann man später in der Entwicklungsumgebung sehr einfach auf die passenden Quelltexte zugreifen, ohne dass man das Projekt geöffnet haben muss. Für dieses Projekt benutzen wir junit für die Unit-Tests. Es muss mindestens eine Bib- liothek für Unit-Tests definiert sein, sonst können Projekte nicht gebaut werden. Java bietet ein integriertes Logging-Framework. Außerdem gibt es noch von Apache das log4j-Logging-Framework. Das slf4j-Projekt bietet die Möglichkeit, jederzeit das verwendete Framework austauschen zu können, ohne dass man Anwendungscode an- passen muss. Außerdem bietet slf4j eine praktische Schnittstelle, um parametrisierte Log-Ausgaben generieren zu können.Damit ist dieses Teilprojekt fertig gestellt. Jetzt müssen wir dieses Projekt als Basisprojektin alle weiteren Teilprojekte einbinden. Davor sollten wir es kurz mit mvn install erstel-len. 19
  34. 34. 2 Aufsetzen der Teilprojekte 2.2.2 Teilprojekt Base Im Laufe einer langjährigen Entwicklung sammeln sich immer mehr Funktionen, die kei- nem Projekt direkt zugerechnet werden können, sich aber einer ungemeinen Nützlichkeit im Projektalltag erfreuen. Damit diese Funktionen sich gar nicht erst in den Untiefen eines Projekts verlieren, empfehle ich, ein Teilprojekt anzulegen, in dem solche allgemeinen Funktionen dann eine passende Heimat haben. Dieses Teilprojekt erstellen wir wieder mit: $ mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=de.wicketpraxis -DartifactId=de.wicketpraxis--base Die generierte Projektdatei wird vollständig ersetzt, da wir viele Einstellungen bereits in dem übergeordneten Projekt getroffen haben und diese deshalb nicht noch einmal angege- ben werden müssen. Listing 2.2 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion> <parent> <groupId>de.wicketpraxis</groupId> <artifactId>de.wicketpraxis--parentPom</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>${pom.groupId}--base</artifactId> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - Base)</name> </project> Damit die nötigen Informationen vom Basisprojekt übernommen werden können, muss es wie im Bereich parent referenziert werden. 2.2.3 Teilprojekte Datenbankkonfiguration Für die Datenbankanbindung werden drei Teilprojekte angelegt. Auch wenn der Aufwand im ersten Moment übertrieben wirkt, ist nur durch die Teilung eine saubere Abhängig- keitsstruktur erreichbar. Das erklärt sich sehr viel besser, wenn wir nachher diese Projekte einbinden und nutzen. 2.2.3.1 Konfigurationsprojekt für die Produktivdatenbank Wir legen ein Teilprojekt mit der artifactId de.wicketpraxis--dbconfig an. Wir passen die Projektdatei an und fügen die Abhängigkeiten für den Datenbanktreiber ein. Als Produktivdatenbank soll eine MySQL-Datenbank zum Einsatz kommen. Daher wird die Bibliothek für diesen Datenbanktreiber eingebunden. Listing 2.3 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion>20
  35. 35. 2.2 Aufsetzen der Teilprojekte <parent> ... </parent> <artifactId>${pom.groupId}--dbconfig</artifactId> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - DB Config)</name> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies> <properties> <mysql.version>5.1.6</mysql.version> </properties> </project>2.2.3.2 Konfigurationsprojekt Schema-UpdateHibernate bietet die Möglichkeit, aus der konfigurierten Datenbankzugriffschicht automa-tisch das Datenbankschema zu erzeugen. Dabei nimmt Hibernate ebenfalls datenbankspe-zifische Optimierungen vor, auf die man durchaus zurückgreifen sollte. Wenn man nichtgerade über umfangreiches datenbankspezifisches Wissen verfügt, dürfte das Know-howaus dem Hibernate-Projekt zu den besseren Ergebnissen führen.Auf die automatische Schemagenerierung greifen wir bei der Testdatenbank ebenfalls zu-rück. Dieses Projekt dient nur dazu, andere Zugangsdaten für die Datenbank bereitzustel-len, die mit anderen Rechten ausgestattet die entsprechenden Tabellen anlegen kann.Außerdem können wir so verhindern, dass diese Zugangsdaten auf Produktivsystemen auf-tauchen.Wir erstellen das Teilprojekt mit der artifactId de.wicketpraxis--dbconfig-schema-update. Wir definieren eine Abhängigkeit zum Projekt mit der Produktdaten-bankkonfiguration, sodass derselbe Datenbanktreiber benutzt wird.Listing 2.4 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion> <parent> ... </parent> <artifactId>${pom.groupId}--dbconfig-schema-update</artifactId> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - DB Config Schema Update)</name> <dependencies> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>${pom.groupId}--dbconfig</artifactId> <version>${pom.version}</version> </dependency> </dependencies> </project>Wenn sich der Datenbanktreiber ändern sollte, muss natürlich in beiden Fällen die noch zuerstellende Konfiguration angepasst werden. 21
  36. 36. 2 Aufsetzen der Teilprojekte 2.2.3.3 Konfigurationsprojekt für die Testdatenbank Für den Datenbanktest wird auf eine Datenbank zurückgegriffen, die ohne Installation aus- kommt und innerhalb einer beliebigen Java-Anwendung gestartet werden kann. Es ist aber ebenso praktikabel, auch während der Entwicklung auf diese Datenbank statt auf eine loka- le MySQL-Installation zurückzugreifen. Damit erspart man sich Installations- und Konfi- gurationsaufwand. Wir erstellen das Teilprojekt mit der artifactId de.wicketpraxis– -dbconfig-test und passen die Projektdatei an. Listing 2.5 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion> <parent> ... </parent> <artifactId>${pom.groupId}--dbconfig-test</artifactId> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - DB Config Test)</name> <dependencies> <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>${hsqldb.version}</version> </dependency> </dependencies> <properties> <hsqldb.version>1.8.0.1</hsqldb.version> </properties> </project> Ich benutze die HSQL-Datenbank für die Testumgebung. Es können natürlich beliebige andere Datenbanken benutzt werden, für die Hibernate Unterstützung anbietet. 2.2.4 Teilprojekt Persistenz Nachdem wir nun alle Datenbankkonfigurationsprojekte angelegt (aber noch nicht konfi- guriert) haben, legen wir nun das Teilprojekt (artifactId de.wicketpraxis-- persistence) an, das den Datenbankzugriff regelt. Diese Projektdatei wird etwas um- fangreicher, denn wir müssen die anderen Teilprojekte einbinden. Listing 2.6 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ... > <modelVersion>4.0.0</modelVersion> <parent> ... </parent> <artifactId>${pom.groupId}--persistence</artifactId> <name>${pom.groupId}--${pom.artifactId} (Wicket Praxis - Persistence)</name> <dependencies> <dependency> <groupId>${pom.groupId}</groupId>22
  37. 37. 2.2 Aufsetzen der Teilprojekte <artifactId>${pom.groupId}--dbconfig</artifactId> <version>${pom.version}</version> </dependency> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>${pom.groupId}--dbconfig-test</artifactId> <version>${pom.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>${pom.groupId}--dbconfig-schema-update</artifactId> <version>${pom.version}</version> <scope>test</scope> </dependency> <!-- Base --> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>${pom.groupId}--base</artifactId> <version>${pom.version}</version> </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${springframework.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springframework.version}</version> <scope>test</scope> </dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>${hibernate-annotations.version}</version> </dependency> </dependencies> <properties> <springframework.version>2.5.6</springframework.version> <hibernate.version>3.2.6.ga</hibernate.version> <hibernate-annotations.version>3.3.1.GA</hibernate- annotations.version> </properties> </project>Im ersten Abschnitt der Abhängigkeitsverwaltung (dependencies) werden die Daten-bankkonfigurationsprojekte eingebunden. Dabei werden die Konfigurationen für die Da-tenbanktests und die Schemaaktualisierung nur für die Unit-Tests eingebunden (<sco-pe>test</scope>). Die Schemaaktualisierung wird wie ein Unit-Test gestartet, sodassdann auf diese Konfiguration zurückgegriffen werden kann. 23

×