Anzeige
Anzeige
Artikel

Einführung in das Framework Apache Wicket: Java mit Leichtigkeit

Komponentenbasierte Web-Frameworks für Java gibt es viele. Die meisten glänzen jedoch weniger durch einen leichtgewichtigen, objektorientierten Ansatz mit Kontrolle über den erzeugten HTML-Code, sondern durch langwierige XML-Konfiguration und komplizierte Komponentenmodelle. Das Open-Source-Framework Apache Wicket ändert dies.

7 Min.
Artikel merken
Anzeige
Anzeige

Der Kern des schlanken Frameworks verschreibt sich der Manipulation von Markup (XML/XHTML) durch Java. Ein wohldurchdachtes Komponentenmodell ermöglicht die Programmierung von Webanwendungen analog zu GUIs mit der vollen Kontrolle über den erzeugten Code. Viele mitgelieferte Komponenten ermöglichen dabei den schnellen Aufbau einer funktionalen Oberfläche. Dieser Artikel gibt eine kurze Einführung in Apache Wicket anhand einiger Beispiele. Der komplette, lauffähige Code steht über den Softlink am Ende des Artikels zum Download bereit.

Java + HTML = Wicket

Anzeige
Anzeige

Ein einfaches Beispiel soll den Aufbau einer Webanwendung mit Wicket verdeutlichen. Eine Anwendung in Wicket besteht immer aus einem Application-Objekt, das die Konfiguration festlegt, und mehreren Seiten für verschiedene Ansichten. Für eine Seite sind zwei Dateien notwendig: eine Java-Klasse und der HTML-Code. Dem „Convention over Configuration“-Ansatz [1] folgend, ist der Name der Klasse die Basis für den Namen des Markup-Dokuments.

JAVA ExampleApplication.java

public class ExampleApplication extends WebApplication {
	public Class getHomePage() {
		return HelloWorld.class;
	}
}

Listing 1

JAVA HelloWorld.java

public class HelloWorld extends WebPage {
	public HelloWorld() {
		add(new Label("message", "Hello, World!"));
	}
}

Listing 2

HTML HelloWorld.html

<html>
<body>
<h1 wicket:id="message">[My message]</h1>
</body>
</html>

Listing 3

Für die Applikationsklasse „ExampleApplication“ reicht es aus, eine Einstiegsseite festzulegen, die als Startseite dargestellt wird. Basis für alle Seiten ist die Klasse „WebPage“, die Komponenten werden im Konstruktor mittels „add(…)“ zur Seite hinzugefügt. Die Komponente „Label“ wird zur Darstellung von Text verwendet – in diesem Fall „Hello, World!“. Die ID „message“ ordnet das Label einem Tag mit dem „wicket:id“-Attribut gleichen Werts zu. Der Inhalt des Tags wird bei der Ausgabe durch die gerenderte Komponente ersetzt. Die zugehörige Markup-Datei „HelloWorld.html“ ist gültiges HTML und kann direkt im Browser betrachtet werden. Dies ist in Wicket generell der Fall und vereinfacht die Entwicklung und Zusammenarbeit beim Design der Oberfläche.

Anzeige
Anzeige
Webapplikationen in Java
Eine Webapplikation wird in Java durch einen so genannten
Servlet-Container (z. B. Tomcat oder Jetty) ausgeführt und in ein
spezielles Paket geschnürt (WAR).Eine Datei „web.xml“ definiert die vorhandenen Ressourcen einer
Webapplikation, wie z. B. Servlets, Filter und Weiteres. Durch den
Einsatz eines speziellen Build-Tools wie Maven oder Ant passiert der
Aufbau der benötigten Dateistruktur automatisch.

Die meisten Web-Frameworks sind an das bekannte MVC-Framework Struts [2] angelehnt, das nur eine Separation zwischen Applikationsfluss und Darstellung erreicht, sich jedoch bei der Programmierung sehr an den Request-/Response-Zyklus von HTTP anlehnt. Die Entwicklung einer nur ansatzweise GUI-ähnlichen Webapplikation mit einem solchen Framework ist nur mit großem Aufwand möglich.

Anzeige
Anzeige

Komponenten als Bausteine der Oberfläche

Komponenten sind wiederverwendbare Objekte, die zu einer komplexen Web-Oberfläche zusammengesetzt werden können. Die Programmierung von Webapplikationen wird so deutlich vereinfacht, da das Verhalten in den Komponenten gekapselt wird und die Logik nicht an den Request-/Response-Zyklus gebunden ist. Eigene Komponenten können in Wicket im Gegensatz zu anderen Frameworks wie JavaServer Faces mit wenig Aufwand selbst erstellt werden. Das objektorientierte Design, das auch Vererbung von Markup vorsieht, ermöglicht zudem die Erweiterung bestehender Komponenten.

Ein Beispiel mit bleibendem Zustand und mehr Action

Komponenten können neben ihrem Verhalten auch einen Zustand in Form von Instanzvariablen besitzen. Der Zustand wird über verschiedene Aufrufe hinweg serverseitig gespeichert – um die Details kümmert sich Wicket. Als Beispiel soll eine einfache Komponente für ein Rating dienen, die später um Ajax-Fähigkeiten (mit Fallback) erweitert wird, ohne eine Zeile JavaScript zu schreiben. Die Rating-Komponente speichert die Anzahl der Abstimmungen mit den vergebenen Punkten und hat jeweils einen Link für „mögen“ („like“) und „nicht mögen“ („dislike“).

Anzeige
Anzeige

JAVA Rating.java

public class Rating extends Panel {
	int votes = 0;
	int score = 0;
	public Rating(String id) {
		super(id);
		add(new Label("rating", new PropertyModel(this, "rating")));
		add(new Label("votes", new PropertyModel(this, "votes")));
		add(new Link("like") {
			public void onClick() { votes++; score++; }
		});
		add(new Link("dislike") {
			public void onClick() { votes++; }
		});
	}
	public double getRating() {
		return votes > 0 ? score / (double)votes * 10 : 0;
	}
	public int getVotes() { return votes; }
}

Listing 4

HTML Rating.html

<html>
<style>
div.rating { font-size: 3em } div.votes { font-size: 0.8em }
</style>
<body>
<wicket:panel>
<div class="rating" wicket:id="rating">7.1</div>
<div class="votes"><span wicket:id="votes">67</span> ratings</div>
<div class="links">
	<a href="#" wicket:id="like">Like</a> |
	<a href="#" wicket:id="dislike">Dislike</a>
</div>
</wicket:panel>
</body>
</html>

Listing 5

Grundlage für die Rating-Komponente ist in diesem Fall die Klasse „Panel“, die andere Komponenten aufnehmen kann und eigenes Markup besitzt. Dieses wird in der HTML-Datei zwischen den „<wicket:panel>“-Tags angegeben, der Rest der Datei dient der Vorschau. Wie jede Komponente benötigt sie selber einen Bezeichner, den sie als „id“ im Konstruktor übergeben bekommt und an den Konstruktor der Superklasse „Panel“ weitergibt. Die beiden Labels „rating“ und „votes“ rendern das Gesamt-Rating und die Anzahl der Stimmen. In diesem Fall ist der Wert der Labels kein String, sondern ein so genanntes Model.

Für das Verhalten des Ratings sorgen die anonym implementierten „onClick()“-Methoden der Link-Komponenten. Die entsprechende Methode wird bei Klick eines Links im Browser aufgerufen und verändert in diesem Beispiel den Zustand und die Darstellung der Rating-Komponente. Wie das Beispiel zeigt, werden im Java-Code keinerlei Parameter des Requests abgefragt, denn die für einen Link generierte URL teilt Wicket mit, welcher Link auf der Seite geklickt wurde. Da sie für jede Instanz der Komponente auf einer Seite eindeutig ist, kann eine Komponente ohne Probleme auch mehrmals auf einer Seite genutzt werden.

Models binden Komponenten an Daten

Die vorab erwähnten Models sind ein wichtiges Konzept von Wicket, um Komponenten an Daten zu binden. Der Wert eines Models wird erst bei der Darstellung der Seite bestimmt. Im Falle des im Beispiel verwendeten „PropertyModel“, wird als Wert die Eigenschaft eines Objekts benutzt (Eigenschaften entsprechen Getter- und Setter-Methoden in JavaBeans-Namenskonventionen: „rating“ bezeichnet also „getRating()“). Durch die Kapselung des Datenzugriffs ermöglichen Models die Integration mit anderen Ebenen einer Anwendung (z. B. Geschäfts- und Persistenz-Schicht).

Anzeige
Anzeige

Abwärtskompatibles Ajax ohne „J“ mit Wicket

Um der Rating-Komponente eine Abstimmung mittels Ajax zu ermöglichen, bei der die Seite nicht neu geladen werden muss, reicht es vollkommen aus, den Java-Code etwas abzuändern:

JAVA Rating.java

	public Rating() {
		final Label ratingLabel;
		add(ratingLabel = new Label("rating", new PropertyModel(this, "rating")));
		ratingLabel.setOutputMarkupId(true);
		final Label votesLabel;
		add(votesLabel = new Label("votes", new PropertyModel(this, "votes")));
		votesLabel.setOutputMarkupId(true);
		add(new AjaxFallbackLink("like") {
			public void onClick(AjaxRequestTarget target) {
				votes++; score++;
				if(target != null) {
					target.addComponent(ratingLabel);
					target.addComponent(votesLabel);
				}
			}
		});
		add(new AjaxFallbackLink("dislike") {
			public void onClick(AjaxRequestTarget target) {
				votes++;
				if(target != null) {
					target.addComponent(ratingLabel);
					target.addComponent(votesLabel);
				}
			}
		});
	}

Listing 6

Die beiden Labels müssen für die Verwendung mit Ajax eine HTML-ID zugewiesen bekommen. Dies übernimmt die Eigenschaft „setOutputMarkupId“. Die Komponente „AjaxFallbackLink“ ist ein erweiterter Link, der den Klick via Ajax übermittelt, falls JavaScript zur Verfügung steht. Ansonsten verhält er sich als Fallback wie die normale Link-Komponente. Mit dem „AjaxRequestTarget“-Objekt, das bei der Behandlung des Klicks in der „onClick(…)“-Methode zur Verfügung steht, können Komponenten registriert werden, die per Ajax neu gerendert werden sollen. Der benötigte JavaScript-Code wird von Wicket automatisch erzeugt. Über das „AjaxRequestTarget“-Objekt kann aber auch eigenes JavaScript ausgeführt werden.

Testgetriebene Webentwicklung mit Wicket

Wer seine Webanwendung testgetrieben entwickeln möchte, kann dies mit Wicket auch für die Benutzeroberfläche ohne viel Aufwand tun. Für Unit-Tests stellt Wicket die Klasse „WicketTester“ bereit, mit der Seiten und Komponenten getestet werden können. Hier kommt Wicket der unmanaged-Ansatz zugute, bei der eine Instanziierung von Komponenten und Seiten jederzeit möglich ist. Ein einfacher Test für die Rating-Komponente könnte wie folgt aussehen:

Anzeige
Anzeige

JAVA RatingTests.java

public class RatingTests extends TestCase {
	public void testRender() {
		WicketTester tester = new WicketTester();
		Rating rating = (Rating) tester.startPanel(Rating.class);
		tester.clickLink("panel:like");
		assertEquals("like increments score", 1, rating.score);
		tester.assertLabel("panel:votes", "1");
		tester.assertLabel("panel:rating", "10");
		tester.clickLink("panel:dislike");
		assertEquals("score not incremented", 1, rating.score);
		tester.assertLabel("panel:votes", "2");
		tester.assertLabel("panel:rating", "5");
	}
}

Listing 7

Die „WicketTester“-Klasse simuliert in diesem Unit-Test das Klicken der Links und überprüft die angezeigten Werte auf Richtigkeit. Oftmals kann die Entwicklung einer kompletten Webapplikation zunächst testgetrieben durchgeführt und erst später auf einem Servlet-Container ausgeführt werden. Das im Gegensatz zu PHP oder Ruby langsame Develop/Deploy bei der Entwicklung einer Webanwendung mit Java kann so kompensiert werden. Zudem erreicht die Software erfahrungsgemäß eine höhere Qualität mit weniger Defekten und besserem Design.

Fazit

Wicket ermöglicht die Entwicklung eigener Komponenten bei voller Kontrolle über den erzeugten HTML-Code; Ajax-Features können ohne Programmierung von JavaScript implementiert werden. Zudem ermöglichen Hilfsklassen und das einfache Programmiermodell die testgetriebene Entwicklung.

Zusätzlich löst Wicket noch viele weitere Probleme, etwa durch umfangreiche Möglichkeiten zur Lokalisierung bis auf Markup-Ebene, Integration in Application-Frameworks wie Spring [4], Benutzung von Speaking-URLs, Bereitstellung dynamisch generierter Ressourcen (JavaScript, Grafiken) und Vorbereitung für Clustering. Weitere Informationen zu Wicket liefert die Projekt-Website. Auf WicketStuff.org werden Komponenten und Integrationen außerhalb des offiziellen Projekts veröffentlicht, außerdem findet sich dort eine Live-Demo mit vielen Beispielen.

Anzeige
Anzeige

Wer bislang dachte, dass Java für Webapplikationen unnötig komplex ist und keine Vorteile bietet, sollte sich Apache Wicket auf jeden Fall genauer ansehen. Vielleicht ist Wicket auch ein guter Grund, sich einmal wieder mit Java auseinanderzusetzen und die nächste Webapplikation mit diesem Framework umzusetzen.

Mehr zu diesem Thema
Fast fertig!

Bitte klicke auf den Link in der Bestätigungsmail, um deine Anmeldung abzuschließen.

Du willst noch weitere Infos zum Newsletter? Jetzt mehr erfahren

Anzeige
Anzeige
2 Kommentare
Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

DerPapst

Net schlecht, der Artikel, könnte aber ein *bisschen* ausführlicher sein.

Antworten
Oliver

Und wie sieht das ganze mir Spring Boot aus ?

Antworten

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!
Hallo und herzlich willkommen bei t3n!

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team von mehr als 75 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Schon jetzt und im Namen der gesamten t3n-Crew: vielen Dank für deine Unterstützung! 🙌

Deine t3n-Crew

Anleitung zur Deaktivierung
Artikel merken

Bitte melde dich an, um diesen Artikel in deiner persönlichen Merkliste auf t3n zu speichern.

Jetzt registrieren und merken

Du hast schon einen t3n-Account? Hier anmelden

oder
Auf Mastodon teilen

Gib die URL deiner Mastodon-Instanz ein, um den Artikel zu teilen.

Anzeige
Anzeige