Dienstag, 16. November 2010

Tag 2: 9:30 - 12:30: Introducing Wicket

Was für ein Tag 1! Die Müdigkeit noch nicht ganz aus den Augen gerieben geht es nach gutem Frühstück in die erste Session von Tag 2. Nach dem morgentlichen Blick auf den Teller schweift nun der Blick erneut über den Tellerrand hinaus und schaut sich mal an, was Apache Wicket so zu bieten hat.

Wicket ist "yet another web framework", welches alles, was in der Java-Welt aktuell modern ist, verspricht zu leisten.

Veröffentlicht unter der Apache Licence 2.0 liegt Wicket zurzeit in der Version 1.5-M3 vor.

Die zentralen Features im Überblick
  • Java-basiert
  • Code-zentriert
  • Komponenten-orientiert
  • Strikte Trennung zwischen Design und Code
Bis hierhin noch kein Grund sich drei Stunden darüber berichten zu lassen.

Der Vortrag entwickelte sich aber recht interessant. Im Vergleich zu anderen Web Frameworks, welche zum Rendern des Clients auf JSP, JSF oder GSP (Grails) setzen und im gewissen Maße die Programmierung von Logik in der UI-Schicht erlauben, setzt Wicket rein auf HTML. Der Rest (Logik, Validierung, Navigation) findet ausschließlich auf der Java-Seite statt. Die Verbindung zwischen HTML-Seite und Java-Klasse erfolgt über "Tricks" und Namenskonventionen.

Der "Trick" dahinter besteht im Ausnutzen einer Eigenschaft von HTML (beziehungsweise der Browser, die HTML rendern): Alles, was ein HTML-Renderer nicht kennt, wird ignoriert. Dies gilt sowohl für Nicht-HTML-Tags als auch für Nicht-HTML-Attribute.

Und genau hier setzt Wicket an. Wicket definiert ein Attribut namens "wicket:id". Wenn sich eine Wicket-Komponente (s. u.) auf ein HTML-Tag beziehen soll, dann erweitert man dieses HTML-Tag um ein wicket:id-Attribut und gibt ihm einen Wert, den man wiederum in Java referenziert.

Dieses Vorgehen hat den Vorteil, dass ein UI-Designer direkt auf Ebene von HTML und CSS arbeiten und jederzeit das Ergebnis in unterschiedlichen Browsern sehen und testen kann, ohne durch Frameworks oder Servlet Container unterstützt werden zu müssen.

Auf UI-Seite geht es aber trotzdem nicht ganz ohne Wicket-Magie: HTML-Seiten haben das Problem, dass sie von Haus aus keine hinreichend gute Unterstützung für die Zerlegung einer Seite in Teilseiten haben. Externe Bilder, Javascript und CSS können über entsprechende Tags eingebunden werden. Eine HTML-Seite kann zwar in mehrere zerlegt und via <frame> oder <iframe> wieder zusammengebaut werden. Ein Templating (wie beispielsweise von Struts Tiles oder Sitemesh gewohnt) gibt es aber nicht. Diese Lücke versucht Wicket mit den Tags <wicket:child> und <wicket:extend> zu füllen.

Auf Java-Seite konzentriert sich der Entwickler auf die Programmierung der Seitenlogik und der Seitennavigation. Dabei wird die Zugehörigkeit einer Java-Klasse zu einer HTML-Seite über den gemeinsamen Klassen-/Dateinamen geregelt (Convention over configuration).

Die Seitenlogik folgt dem MVC-Pattern. Jede Seitenklasse (Page) und sämtliche Controls auf der Seite sind Wicket-Komponenten, die ineinander gestöpselt werden können und in Summe den Komponentenbaum einer Seite bilden.

Sämtliche Wicket-Komponenten sind wiederum Java-Klassen, die individuell erweitert werden können (durch Vererbung). Alternativ können neue Komponenten durch Implementierung entsprechender Interfaces geschaffen werden.

Sämtlicher Komponenten können Events verarbeiten (z. B. onClick). In den zahlreichen Demos wurde hierfür der Weg über anonymous inner classes verwendet, welche per "new" erzeugt und danach der Komponente bekannt gegeben wird.

Apropos "new": Wicket-Komponenten durchleben zwar ein Lifecycle; es bedarf aber keiner besonderen Factories um sie zu erzeugen oder bei einem "Lifecycle-Manager" anzumelden. Erzeugt werden sie einfech durch "new".

WIcket bietet von Haus aus eine Reihe von Komponenten an:
  • Labels
  • Links
  • Repeaters
  • Forms
  • TextField
  • DropdownChoice
  • Panel
  • DataView
  • DataTable
Die Datenbefüllung/Datenhaltung erfolgt über Implementierungen des Wicket-Interfaces IModel. IModel-Klassen erfüllen mindestens folgende wichtige Funktionen:
  1. Aus Sicht der Page bilden sie ein Delegate zur eikgentlichen Datenquelle und erlauben es der Page über Änderungen in der DAtenquelle automatisch informiert zu werden.
  2. Datenzugriffe werden null-safe, besonders wenn man entlang eines Objektgraphen navigiert (z. B. "person.adresse[0].strasse")
Wicket setzt voraus, dass alles, was an einer Page hängt, auch serialisierbar ist. Wenn nun aber unter einem Model ein Service oder ein DAO hängt, dann dürfen Instanzen davon nicht mitserialisiert werden. Das ist besonders im Umfeld von Spring ein Problem. Wicket löst dies über die Annotation @SpringBean und die Klasse InjectorHolder, welche im weitesten Sinne einen Proxy um den injizierten Service oder das DAO legen und die Nicht-Serialisierung sowie das Rebinding transparent regeln.

In den Demos wurde eine der klassischen Web-Hello-World-Anwendungen gebaut: Ein Shopping-Portal. Die Beispiel zeigte auf elegante Weise die Vorzüge bei der Entwicklung auf Basis von Wicket:
  1. Erstmal eine HTML-Seite bauen.
  2. Dann eine Page programmieren.
  3. Die in der Page auftauchenden Controls (deren Namen) per wicket:id in der HTML-Seite dem jeweiligen HTML-Tag zuordnen.
  4. Page-Navigation (und gf. HTML-Zielseite) ergänzen.
  5. Fertig.
Ein Auszug an weiteren Features
  • Bookmarkable Links
  • URL-Rewriting
  • Strategien zur Vermeidung von Double submit out-of-the-box
  • WicketTester für Komponenten-Test innerhalb von JUnit und ohne Container (!)
  • Wicket Debugger
Wicket unterscheidet darüber hinaus zwischen Development und Deployment mode mit unterschiedlichen Eigenschaften. Dies kann entweder über einen -D-Schalter oder über einen Eintrag in der web.xml bekannt gegeben werden.

Fazit: Unbedingt anschauen!

1 Kommentar:

  1. Machst Du schon schlapp, Jörn? Als ich beim Devoxx war, habe ich mich am ersten Tag auch total verausgabt. Ich glaube heute musst du die BOFs auslassen.

    P.S.: Bringst Du mir ein T-Shirt mit? ;-)

    AntwortenLöschen