JAXenter.de

Das Portal für Java, Architektur, Cloud & Agile
X

W-JAX-Countdown heute: Stefan Zörner über zeitgemäße Architekten und Architekturen.

Komponentenorientierte Webentwicklung, die Spaß macht!

Tutorial: World Wide Wicket

Martin Dilger

Wie schon viele Male zuvor versuchte Herr K., seinen verdienten Feierabend mit einem guten Film aus seiner Onlinevideothek zu verbringen. Und wie immer ärgerte er sich über die langsame Weboberfläche seines Anbieters. Im Ärger kam Herrn K. eine Idee: Wieso nicht einmal selbst zum Anbieter werden und anderen dieses Ärgernis ersparen? Da Herr K. bisher nur wenig Erfahrung mit der Entwicklung von Webanwendungen hat, muss ein passendes Framework gefunden werden, um schnell und einfach eine performante, wartbare und funktionale Webanwendung entwickeln zu können.

Im vorliegenden Artikel wollen wir die Fortschritte von Herrn K. bei der Entwicklung seiner eigenen Onlinevideothek begleiten. Herr K. hat als regelmäßiger Leser des Java Magazins bereits eine Vielzahl an Frameworks kennen gelernt. Das vielversprechendste davon scheint Apache Wicket [4] zu sein.

Wicket bietet ein einfach zu erlernendes API, eine klare Trennung von Layout und Implementierung, die Möglichkeit, komponentenorientiert zu entwickeln und obendrein AJAX-Support, ohne selbst JavaScript entwickeln zu müssen. Also ideale Voraussetzungen für Herrn K.

Die ersten Schritte

Herr K. entscheidet sich für einen schnellen Einstieg und verwendet Apache Maven [5]  als Build-System. Maven bietet den Vorteil, dass die einzelnen Bibliotheken nicht manuell heruntergeladen werden müssen und bereits ein fertiger Archetype für Wicket-Projekte existiert. Hier [6] gibt es einen Generator, der sogar das Maven-Kommando hierfür bereits vorbereitet.

mvn archetype:create -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart 
-DarchetypeVersion=1.4.9 -DgroupId=de.pentasys.k -DartifactId=video

Obendrein bekommt Herr K. sogar den Jetty-Webserver geschenkt, der im Archetype bereits über das Maven-Jetty-Plug-in eingebunden ist. Der Webserver kann über das Kommando mvn jetty:run gestartet werden und lauscht auf dem Port 8080.

Herr K. betrachtet den generierten Archetype und findet erstaunlich wenig, was zum Betrieb einer Wicket-Anwendung nötig ist. Zunächst findet er nur eine einzige XML-Datei im gesamten Projekt, die für Java-Webanwendungen obligatorische web.xml (Listing 1).

<filter>
<filter-name>pentasys.video</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>de.pentasys.k.VideoStoreApplication</param-value>
</init-param>
</filter>

Der Wicket-Filter erhält als Parameter den vollqualifizierten Namen einer Applikationsklasse, die freundlicherweise gleich mit generiert wurde (Herr K. hat hier bereits einige Klassennamen angepasst):

public class VideoStoreApplication extends WebApplication{
public Class<HomePage> getHomePage() {
return HomePage.class;
}
}

Über die Applikationsklasse kann die Anwendung zentral konfiguriert werden. Sie definiert zunächst nichts weiter als die Methode getHomePage(), die die Einstiegsseite der Applikation liefert. Des Weiteren findet Herr K. die Klasse HomePage selbst (Listing 2).

public class HomePage extends WebPage {
public HomePage() {
add(new Label("message"
"If you see this message, " +
"K's Video Store is properly configured"));
}
}

Obwohl Herr K. bisher keine Erfahrung mit Wicket besitzt, scheint intuitiv klar, wie das Framework funktioniert. Die Klasse HomePage definiert ein neues Label im Konstruktor, das mit der Methodeadd()hinzugefügt wird. Doch Herrn K. fehlt noch ein wichtiger Aspekt, und zwar die Stelle, an der das Layout einer Wicket-Anwendung definiert wird.

Herr K. stöbert daraufhin noch ein wenig im generierten Archetype und stößt auf die Datei HomePage.html, die im selben Package wie die Klasse HomePage liegt und denselben Bezeichner hat (Listing 3).

<html xmlns:wicket="http: //wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<head>
<title>PENTASYS AG - K's Video Store Application</title>
</head>
<body>
<strong>K's Video Store Application</strong>
<br/><br/>
<span wicket:id="message">message will be here</span>
</body>
</html>

Herr K. sieht erfreut, dass es sich hier um ein reines HTML-Template ohne Taglibs, Scriptlets oder sonstige Logik handelt. Ein <span/>-Element im Template besitzt das Attribut wicket:id, das auf den Wert "message" gesetzt wird. Dies entspricht genau der ID, mit dem das Label in der HomePage-Klasse hinzugefügt wurde. Sofort erschließt sich Herrn K. die Funktionsweise. Der Inhalt des<span/>-Elements wird durch die Java-Komponente mit der entsprechenden ID ersetzt.

Verlassen wir kurz Herrn K. und rekapitulieren die bisher gewonnenen Erkenntnisse.

Wicket-Komponenten bestehen aus nichts anderem als Java-Klassen und zugehörigen HTML-Templates (und evtl. zusätzlichen CSS und/oder JavaScript-Dateien). Die HTML-Templates müssen sich im gleichen Package wie die Java-Klassen befinden und den gleichen Bezeichner tragen. Komponenten können ineinander geschachtelt werden (mit der Methode add()und der Vergabe einer ID). Die Java-Komponentenhierarchie spiegelt sich in der Tag-Hierarchie des HTML-Templates wider. Die Zuordnung von Java-Komponenten zu HTML-Tags erfolgt über das Attribut wicket:id. Natürlich müssen nur diejenigen HTML-Tags eine ID erhalten, die auch tatsächlich mit einer Java-Komponente verknüpft werden sollen.

Herr K. ist mittlerweile auf das erste Problem gestoßen. Er ist ein hervorragender Entwickler aber leider auch ein lausiger Designer. Zum Glück befindet sich in seinem Bekanntenkreis Herr D., ein erfolgreicher Webdesigner. Herr K. skizziert kurz seine Vorstellung auf einem Blatt Papier und schickt den Entwurf an Herrn D.. Kurz darauf erhält er ein fertiges HTML-Template inkl. CSS-Styling, das er nun als Grundlage für die weitere Entwicklung verwendet.

Der nächste Schritt für Herrn K. besteht nun darin, die fachlichen Domänenobjekte für seine Videothek zu definieren. (Die Klasse Customer ist exemplarisch in Listing 4 dargestellt).

public class Customer implements Serializable {
private String name;
private Adress adress;
private String email;
private CustomerType type;

public Customer(){
}

public Customer(String name, String email, CustomerType type, Adress adress) {
this.email = email;
this.name = name;
this.adress = adress;
this.type = type;
}
/*
Getter und Setter
*/
}

Alle Domänenklassen sind einfache Pojos und für Herrn K. selbsterklärend. Die einzige Besonderheit: jede Domänenklasse implementiert das Serializable-Interface. Warum das notwendig ist, wird im Kasten Wicket und Serialisierung genauer erläutert.

 

Kommentare

Ihr Kommentar zum Thema

Als Gast kommentieren:

Gastkommentare werden nach redaktioneller Prüfung freigegeben (bitte Policy beachten).

Übersicht zu diesem Beitrag