Der StepStone-Bewerbungsgenerator: Technische Umsetzung in GWT

Ein technisch und inhaltlich anspruchsvolles Projekt ist nach einigen Monaten der Entwicklung Ende 2010 sehr erfolgreich zu Ende gegangen: der Online-Bewerbungsgenerator von StepStone unter www.bewerbung.de. Ziel des Projektes war es, dem Nutzer die Möglichkeit zu geben, durch das Ausfüllen eines Online-Formulars in möglichst wenigen Schritten eine formal korrekte und optisch ansprechende Bewerbung zu erstellen. In diesem Artikel soll dargelegt werden, warum und wie GWT in diesem Projekt zum Einsatz gekommen ist, welche Erfahrungen wir gesammelt haben und auf welche Stolperfallen wir getroffen sind. Auf den Backend-Teil der Anwendung wird hier allerdings nicht näher eingegangen.

Technologische Entscheidung

Die Entscheidung über die einzusetzende Technologie fiel auf GWT, weil die zu erstellende Anwendung Programmen sehr ähnlich ist, die bisher zumeist nur als Desktop-Varianten zu finden sind.

Es gibt zahlreiche (kostenpflichtige) Anwendungen zur Erstellung von Bewerbungen, die heruntergeladen und auf dem eigenen Computer installiert werden können. Wichtig für die Anwendung war weniger die Darstellung von Inhalten, sondern vielmehr die Erfassung von Daten, die Modifizierung der Dialoge auf Basis der bisherigen Nutzereingaben sowie die Interaktion mit dem User.

In diesem Bereich kann GWT seine Stärken ausspielen. GWT ermöglicht es, eigene Komponenten zu definieren und wiederzuverwenden sowie Seiten in logische Einheiten zu unterteilen und so viel Entwicklungszeit einzusparen.

Dabei bewegt sich der Entwickler ausschließlich in Java, kann die volle Unterstützung der IDE (Integrated Development Environment) nutzen und wird nicht mit den klassischen JavaScript-Problemen konfrontiert, mit denen er sich sonst bei der Erstellung interaktiver Webseiten beschäftigen muss. Zudem kann der Entwickler auf ein reichhaltiges vorgefertigtes Set an Komponenten zurückgreifen.

Aus Sicht des Users bietet GWT kurze Ladezeiten, schnelles Feedback der Anwendung und ein modernes Benutzer-Interface – eine richtige Web-2.0-Anwendung eben.

Aufbau der Anwendung

Eingesetzte Erweiterungen
Als Erweiterung von GWT wurde im Projekt ein MVP-Framework (Model View Presenter) eingesetzt. MVP ist ein Entwurfsmuster der Software-Entwicklung und aus dem MVC-Framework (Model View Controller) hervorgegangen. Es bietet im Gegensatz zu MVC eine bessere automatisierbare Testbarkeit und eine strengere Trennung der Komponenten im Vordergrund.

Ein weiteres Entwurfsmuster, die Dependency Injection, wurde durch den Einsatz von GIN (GWT INjection) im GWT-Teil der Anwendung integriert. Es dient dazu, die Abhängigkeiten zwischen Komponenten zu minimieren und hat große Vorteile beim Schreiben automatisierter Software-Tests.

Beispiel einer Oberflächen-Komponente
Der Kern-Dialog des Bewerbungsgenerators besteht aus fünf Schritten, die jeweils durch eine eigene Seite abgebildet werden. Jede Seite kann wiederum in verschiedene Sektionen unterteilt sein, die einen bestimmten Kontext abfragen. Die Seite „Lebenslauf“ umfasst beispielsweise die Sektionen „Persönliche Angaben“, „Beruflicher Werdegang & Praktika“, „Bildungsweg“ usw. Jede Sektion kann dabei einzeln auf- und zugeklappt werden. Dieser Seitenaufbau wurde in eigenen GUI-Komponenten für GWT abgebildet.

Am Klassendiagramm kann man die Funktionsweise im Groben ablesen. Das AccordionPanelWidget kann verschiedene weitere Widgets aufnehmen und dient als Verteiler von Fehlern und zur Anordnung der Unter-Widgets. Die Section ist einer der Bereiche, die auf- und zugeklappt werden können. Sie hat jeweils einen eigenen Bereich zur Darstellung der Fehler und kann beliebige Unter-Widgets enthalten.

Oberflächen mit UIBinder
UIBinder ist eine von Google eingeführte Technik, die es erlaubt, eine Webseite in HTML und CSS zu schreiben und GWT-Widgets in die Seite zu integrieren. Dies bietet sich insbesondere an, wenn es sich um weitgehend statische Bereiche der Anwendung handelt. Hier ist der Einsatz dieser Technik von Vorteil, da Elemente wie Texte und Bilder nicht aufwändig in Java-Code zusammengesetzt werden müssen. Dabei ist jedoch zu beachten, dass der UIBinder Probleme mit Seiten hat, die viele GWT-Elemente enthalten. Intern wird beim Rendern der Seite aus der HTML-Seite ein JavaScript-Objekt erstellt, das als Konstruktor-Parameter alle in der Seite enthaltenen Elemente erhält. Je nach JavaScript-Interpreter (also von Browser zu Browser unterschiedlich) kann es hierbei zu einem Überschreiten der maximalen Anzahl an Übergabeparametern kommen.

Kommunikation mit dem Server

An bestimmten Stellen der Anwendung muss der GWT-Client Daten mit dem Server austauschen. Daten in GWT-Anwendungen sind zunächst flüchtig und können ohne Übermittlung an den Server nicht dauerhaft in einer Datenbank oder in der Session gespeichert werden: Die Daten gehen beispielsweise bei einem Klick auf den Reload-Button im Browser verloren, solange sie nicht an bestimmten Stellen an den Server übermittelt und in der Session bzw. in der Datenbank gespeichert werden. Im Projekt wurde daher jeweils beim Seitenwechsel, bei der Validierung (Extra-Button) und auch beim Speichern eine Datenübertragung an den Server und damit auch in die Session eingebunden.

Die Übertragung geschieht in GWT per AJAX, ohne dass die Seite neu geladen wird. Für den Endanwender am Browser ist dieser Vorgang jedoch nicht spürbar: Es gibt im Browser kein sichtbares Anzeichen dafür, dass im Hintergrund gerade Informationen übermittelt werden bzw. wurden. Erst wenn der Entwickler z.B. ein Warten-Rädchen und/oder eine Meldung wie "Speichern erfolgreich" einbindet, erfährt der Nutzer, dass Daten ausgetauscht worden sind. Bei klassischen Web-Anwendungen hingegen erhält der User ein deutliches visuelles Feedback ohne Zutun des Entwicklers anhand des Ladebalkens im Browser.

Ein wichtiges Design-Merkmal der Anwendung ist, wie häufig der GWT-Teil der Anwendung mit dem auf dem Server laufenden Teil kommuniziert. Werden die Daten bei jeder Feldänderung an den Server übermittelt, entsteht dabei ein großer Kommunikations-Overhead, was bei der Dimensionierung der Server-Infrastruktur beachtet werden muss. Im Fall dieser Anwendung wurde entschieden, die Daten portionsweise an den Server zu übermitteln. Dabei werden die Daten aus allen Feldern der Seite eingesammelt und in einem sog. Data Transfer Object (DTO) gebündelt. Dieses wird dann an den Server übertragen. Die Datenübermittlung erfolgt entweder durch einen Klick auf den Validieren-Button, durch Drücken des Speichern-Buttons oder beim Wechsel auf die nächste Seite.

Neben diesen Möglichkeiten der Server-Kommunikation, die auf jeder Seite zur Verfügung stehen, werden weitere Elemente je nach Auswahl des Nutzers im Dialog nachgeladen. So gibt es beispielsweise auf der Seite „Anschreiben“ die Sektion „Stärken und Fähigkeiten“. Hier muss der User zunächst eine Branche auswählen. Diese Auswahl führt dazu, dass eine umfangreichere Liste mit Stärken und Fähigkeiten, die zu dieser Branche passen, vom Server nachgeladen und schließlich im Browser dargestellt wird.

Ähnlich verhält es sich mit der Folgeseite, auf der der User den Text des Anschreibens editieren kann. Alle Texte werden beim „Betreten“ der Seite dynamisch vom Server ermittelt, wobei die bis hierhin eingegebenen Daten in die Texte eingehen und die Inhalte und verfügbaren Textvarianten bestimmen.

Teilen von Code zwischen Client und Server
Eine sehr nützliche Eigenschaft beim Einsatz von GWT besteht in der Möglichkeit, die gleiche Klasse, die in GWT verwendet wird (also im Browser des Nutzers), auch auf der Server-Seite zu verwenden. Dies gilt besonders dann, wenn der Entwickler beide Teile in Java schreibt. Dabei muss er einige Regeln beachten, da GWT nur eine Teilmenge der in Java verfügbaren Datentypen in JavaScript abbilden kann, wie dieser Überblick zeigt. Die dort beschriebenen Datentypen kann man natürlich wieder zu eigenen Klassen zusammenfassen. Verwendet man allerdings Libraries, in denen andere Elemente Verwendung finden, kommt es in JavaScript zu Laufzeitfehlern. Diese sind mitunter nicht einfach zu finden, da der JavaScript-Interpreter abstürzt, ohne viele Informationen auszugeben.

Wenn man von dieser Möglichkeit gebraucht macht, sollte man also stets die Sicherheit der verwendeten Daten und der Logik im Auge behalten.

GWT: Nicht mehr um den Browser kümmern?

GWT verspricht dem Entwickler, dass er sich nicht mehr um die Eigenarten von verschiedenen Browsern kümmern muss. Web-Entwickler haben seit vielen Jahren Probleme mit dem unterschiedlichen Verhalten der verschiedenen Web-Browser, wobei hier besonders häufig der Internet Explorer von Microsoft durch nicht standardkonformes Verhalten in Erscheinung tritt.

Diesem Versprechen kommt GWT zwar nach, aber nicht vollständig: Im Projekt traten auch immer wieder kleinere Probleme in dieser Hinsicht auf. So muss der Entwickler z.B. einen iFrame einbinden, in dem der Internet Explorer seine History-Daten ablegen kann. Ohne diesen iFrame funktioniert die Anwendung im Internet Explorer überhaupt nicht, sondern es kommt schon beim Initialisieren der GWT-Anwendung zu einem Fehler.

Ein weiterer etwas kritischer Punkt ist das unterschiedliche Verhalten hinsichtlich leerer Werte von Elementen in Eingabeformularen.

Hat man beispielsweise eine Select-Box mit einem leeren Wert, kommt beim Auslesen in GWT manchmal Null und manchmal ein leerer String oder auch der String „Null“ an. Hier müssen also alle Fälle getestet und beachtet werden. Da man in GWT das Layout mit herkömmlichem CSS definiert, sind diese Probleme jedoch in gewisser Weise natürlich auch unabhängig von GWT.

Fazit

Für die Entwicklung dieser serviceorientierten Seite war der Einsatz von GWT eine sehr gute Wahl. Es hat sich gezeigt, dass – wie auch das Komponenten-Beispiel oben erkennen lässt – GWT eine saubere und durchdachte Software-Architektur erfordert. Hierin besteht sicherlich ein Unterschied zu klassischen Oberflächen-Projekten in HTML und CSS.

Die Herausforderungen im Zusammenhang mit dem UIBinder waren allerdings recht groß und aufwändig zu lösen. Hinsichtlich der Browser-Kompatibilität nimmt GWT dem Entwickler schon ein gutes Stück Arbeit ab, dennoch ist es immer noch unerlässlich, in allen gängigen Browsern zu testen.

Weitere Informationen

GWT: Evolution der Internet-Anwendung
Dynamische Internet-Anwendungen: GWT im Projekteinsatz
Dynamische Internet-Anwendungen: GWT aus Entwicklerperspektive
Sicherheitsaspekte in GWT-Anwendungen: Anwendungslogik und Manipulationen