Aus Linux-Magazin 10/2006

Google Web Toolkit zum Erstellen dynamischer Webapplikationen

Das Google Web Toolkit ermöglicht die Entwicklung aufwändiger Webanwendungen in Java und generiert daraus automatisch Ajax-Applikationen. Im Hosted-Modus wird die Suche nach Fehlern zum Kinderspiel.

Der Weltmarktführer für Suchanfragen mausert sich auch zu einem Softwareproduzenten. Neben nativen Programmen wie Google Desktop und Google Earth veröffentlicht die Firma im Quartalsrhythmus neue Web-basierte Produkte. Während Google Mail noch im medialen Rampenlicht stand, genießen neuere Applikationen wie Google Reader, Google Calender oder Google Spreadsheet geringere Aufmerksamkeit. Unabhängig davon weisen sie alle ein ähnliches Look&Feel auf und verfügen dank Ajax über eine Oberfläche mit geringer Reaktionszeit.

Dass sich unter der Haube dieser Applikationen ein Google-eigenes Framework verbirgt, war mangels näherer Angaben des Herstellers lange nur zu vermuten. Pünktlich zur Messe Java One im Mai dieses Jahres bestätigte Google diesen Verdacht aber, als der Dienst das Google Web Toolkit (GWT) interessierten Webentwicklern zum kostenlosen Download und Einsatz bereitstellte [1].

Ajax [2], die asynchrone Verarbeitung von HTTP-Requests und -Responses mit Hilfe von Javascript und XML, ist zurzeit Thema Nummer eins unter Webentwicklern. Ajax-Toolkits für Programmiersprachen wie Perl [5], Ruby und PHP [4] schießen aus dem Boden, Google beschreitet mit seinem Framework Neuland: Es basiert auf Java, die aber nur als Generator- und Testsprache dient, schließlich verwendet Ajax auf dem Client Javascript.

Was drin ist

Warum ausgerechnet Java? Der Hauptgrund liegt in der Möglichkeit zur einfachen Fehlersuche: Das GWT ermöglicht es, eine Ajax-Applikation im so genannten Hosted Mode auszuführen und zu testen. Dabei läuft sie als Java-Version innerhalb einer gewöhnlichen Java Virtual Machine.

Beim Programmieren helfen die üblichen Entwicklungsumgebungen und Debugger. Ist die Applikation fertig, übersetzt ein Compiler sie in Javascript. Der dabei erzeugte HTML- und Javascript-Code lässt sich dann auf einem Webserver installieren und läuft im so genannten Web Mode.

Ein spezieller Webbrowser, eine eigene Widget-Klassenbibliothek für Ajax-basierte Oberflächen sowie Javascript-Implementationen von Java-Standardklassen wie »java.lang« und »java.util« bilden die Komponentenarchitektur des GWT-Framework. Darüber hinaus kümmert es sich darum, dass der generierte Javascript-Code zu den gängigen Webbrowsern wie Mozilla, Firefox, Internet Explorer, Opera und Safari passt.

Los geht’s!

Das ungefähr 22 MByte große Paket »gwt-linux-1.0.21.tar.gz« bringt eine Dokumentation und fünf Beispielanwendungen mit. Sie reichen von einem trivialen »Hello«-Programm über eine Widget-Übersicht bis zu einer kleinen E-Mail-Applikation und lassen sich über die in den jeweiligen Verzeichnissen enthaltenen Shellskripte starten.

Die im Folgenden als Anwendungsbeispiel entwickelte GWT-Applikation nutzt einen bestehenden Server-Dienst, um eine einfache Adressendatenbank abzufragen. Der hier verwendete Server basiert der Einfachheit halber auf Ruby on Rails, weil er sich so mit wenigen Zeilen umsetzen lässt – für den Client spielt das keine Rolle. Die fertige Version steht unter [10] zum Download bereit.

Beim zu diesem Zweck entwickelten Service MyAddress handelt es sich um eine einfache Datenbank (siehe Listing 1), die Vornamen, Nachnamen und E-Mail-Adressen verwaltet. Zum Datenaustausch dient das in vielen Ajax-Applikationen verwendete JSON-Format (Javascript Object Notation, [3]). Es erzeugt im Gegensatz zu XML mangels Auszeichnungs-Tags weniger Overhead und reduziert damit die Antwortdauer der Ajax-Anwendung.

Listing 1: PostgreSQL-Tabelle
für MyAddress

01 CREATE TABLE myaddress."names"
02 (
03   id serial NOT NULL,
04   firstname varchar(50) NOT NULL,
05   lastname varchar(100) NOT NULL,
06   email varchar(128) NOT NULL,
07   CONSTRAINT id PRIMARY KEY (id)
08 )
09 WITHOUT OIDS;
10 ALTER TABLE myaddress."names" OWNER TO myaddress;

Um mit Ruby on Rails die zu einem Nachnamen gehörende Adresse aus der Datenbank zu holen und ins JSON-Format zu verpacken, genügt der Zehnzeiler aus Listing 2. Zeile 6 liest darin den Nachnamen aus einem HTTP-Request, um in Zeile 7 die passende Adresse aus der Datenbank zu ermitteln. Zeile 8 konvertiert die zurückgelieferten Adressen ins JSON-Format.

Listing 2:
»NameController«

01 class NameController < ApplicationController
02   scaffold :name
03   def find_names_to_json
04     # make sure not to send html but text/plain
05     @headers["Content-Type"] = "text/plain; charset=utf-8"
06     search_name = @params['lastname']
07     names = Name.find(:all, :conditions => ['lastname like ?', search_name])
08     render_text names.to_json
09   end
10 end

Das Kommando »ruby scriptserver start« ruft den MyAddress-Service auf. Der interne Entwicklungsserver von Ruby On Rails stellt den Service über Port 3000 auf »localhost« bereit. Eine Abfrage geschieht optional auch im Browser unter »http://localhost:3000/name/«.

Ein weiterer Vorteil von Ruby On Rails beim Erstellen der Server-Applikation: Dank Scaffolding lässt sich die Datenbank bequem über ein generiertes Eingabeformular bearbeiten (Abbildung 1). Sind die ersten Datensätze eingegeben, liest man sie im Webbrowser über die URL »http://localhost:3000/name/find_names_to_json?lastname= Name« aus.

Abbildung 1: Der Webservice im Beispiel liefert die Datensätze auch direkt im Browser.

Abbildung 1: Der Webservice im Beispiel liefert die Datensätze auch direkt im Browser.

Projektrahmen vollständig und frei Haus

Nun zur Entwicklung des GWT-Projekts, das den Webservice nutzt. Der Kommandozeilenaufruf »projectCreator« erzeugt den Projektrahmen einer Applikation. Der Parameter »-out« legt das Zielverzeichnis fest, »-eclipse« erzeugt das Projekt für die Nutzung mit der Eclipse-IDE:

projectCreator -eclipse Myaddress_GWT -out myaddress_gwt

Die Klassen, Skripte und Konfigurationsdateien erzeugt das Kommandozeilenwerkzeug »applicationCreator«:

applicationCreator -eclipse MyAddress_GWT -out myaddress_gwt de.wartala.client.UMyAddress

Wenn alle nötigen Dateien existieren, ist das GWT-Projekt mit Eclipse über »Import | Existing Projects into Workspace« in den Package Manager zu importieren (Abbildung 2). In der Projektstruktur dient die XML-Konfiguration eines Moduls als Ausgangspunkt. Der »applicationCreator« hat anhand des gewünschten Ziel-Package eine Modul-Konfiguration mit einem so genannten Entry Point angelegt (Listing 3). Er zeigt auf die Java-Klasse, die die Applikation beim Start im Hosted-Modus aufruft. Sie findet sich auch in der HTML-Datei wieder, die den Rahmen für die Oberfläche des Clients implementiert.

Abbildung 2: Das Google Web Toolkit erstellt optional Eclipse-Dateien, die die IDE als Projekt importieren kann. So lässt sich die IDE zum Entwickeln von Ajax-Seiten nutzen.

Abbildung 2: Das Google Web Toolkit erstellt optional Eclipse-Dateien, die die IDE als Projekt importieren kann. So lässt sich die IDE zum Entwickeln von Ajax-Seiten nutzen.

Listing 3: Entry-Point-Klasse
des Clients

01 import com.google.gwt.core.client.EntryPoint;
02 import com.google.gwt.user.client.ui.RootPanel;
03 import com.google.gwt.user.client.ui.TabPanel;
04 
05 /**
06  * Entry point classes define <code>onModuleLoad()</code>.
07  */
08 public class MyAddress implements EntryPoint {
09 
10   /**
11    * This is the entry point method.
12    */
13   public void onModuleLoad() {
14     TabPanel tp = new TabPanel();
15     MyAddressRequester myJson = new MyAddressRequester();
16     tp.add(myJson.initializeMainForm(), "Lastname");
17     tp.selectTab(0);
18     RootPanel.get().add(tp);
19   }
20 }

Die wichtigsten Zeilen sind die Verweise auf die Modul-Klasse und auf die Javascript-Bibliothek des GWT-Framework:

<meta name='gwt:module' content='de.wartala.MyAddress'>
<script language="javascript" src="gwt.js"></script>

Nach dem Start ruft die Applikation zuerst die Methode »onModuleLoad()« auf. Sie baut die Widgets der GUI-Bibliothek auf und instanziiert weitere Klassen, im Beispiel »MyAddressRequester«. Die Methode sendet den Request an den MyAddress-Service, nimmt die Antworten entgegen und füllt mit ihnen die Oberflächenelemente.

Die Methode »initializeMainForm()« baut die Oberfläche und setzt Attribute und Events, ähnlich wie beim Einsatz von AWT oder Swing. Das GUI besteht im Beispiel aus einer Suchschaltfläche, einem Eingabefeld sowie einer »FlexTable«. Als einziger Event kommt ein »ClickEvent« zum Einsatz, den ein Klick auf »Search« auslöst. Die Reaktion darauf implementiert die innere Klasse »SearchButtonClickListener«.

Ein »onClick()«-Event stößt den Ajax-Teil der Applikation an und setzt einen asynchronen HTTP-Request an den Service ab, der sein Ergebnis dem entsprechenden Response-Handler anvertraut. »JSONResponseTextHandler« implementiert als weitere innere Klasse die Methode »onCompletion()«, die zum Einsatz kommt, wenn der asynchrone HTTP-Request etwas zurückliefert.

Da der Service ein JSON-Objekt zurückgibt, muss dieses erst dekodiert und in seine Bestandteile zerlegt werden. Ersteres erledigt »JSONParser.parse(responseText)«, Letzteres die Methode »displayJSONObject()«, die ihrerseits die Aufgaben an die Methode »updateAddressTable()« delegiert. Sie baut das Ergebnis dann in Form einer Tabelle auf, wobei sie die Werte aus der JSON-Antwort in die entsprechenden Zeilen und Spalten einträgt.

Nun kommt das Kommandozeilenskript »MyAddress-shell.sh« zum Einsatz. Abbildung 3 zeigt das Frontend im Hosted Mode. Nach Eingabe eines Nachnamens erscheinen die vom Service gelieferten Daten in der Tabelle.

Abbildung 3: Das Google Web Toolkit bietet einen Hosted Mode mit speziellem Webbrowser, in dem Fehler systematisch aufzuspüren sind.

Abbildung 3: Das Google Web Toolkit bietet einen Hosted Mode mit speziellem Webbrowser, in dem Fehler systematisch aufzuspüren sind.

Jagd nach Fehlern

Der Vorteil des Hosted Mode zeigt sich, wenn wirklich ein Programmfehler auftritt – er lässt sich im Java-Code leichter aufspüren als im übersetzten Javascript. Der Parameter »-eclipse« beim Aufruf von »projectCreator« legt neben den projektspezifischen Daten eine Datei mit der Endung ».launch« an. Dank der darin konfigurierten Parameter lässt sich die Anwendung mit Eclipse ausführen und mit Hilfe von Breakpoints und anderer Helfer debuggen (Abbildung 5).

Abbildung 4: Unter den 20 vordefinierten GWT-Widgets kümmern sich die Panels ums Layout. Zusätzlich lassen sich beliebige eigene Widgets entwickeln.

Abbildung 4: Unter den 20 vordefinierten GWT-Widgets kümmern sich die Panels ums Layout. Zusätzlich lassen sich beliebige eigene Widgets entwickeln.

Abbildung 5: Der Eclipse Debug Mode erleichtert die Fehlersuche gegenüber dem manuellen Durchsuchen von Javascript erheblich. Derartige Tools stehen reinen Javascript-Entwicklern nicht zur Verfügung.

Abbildung 5: Der Eclipse Debug Mode erleichtert die Fehlersuche gegenüber dem manuellen Durchsuchen von Javascript erheblich. Derartige Tools stehen reinen Javascript-Entwicklern nicht zur Verfügung.

Neben der Fehlersuche über Eclipse erlaubt das GWT-Framework auch Unit-Tests der eigenen Klassen. Einsprungspunkt ist die Klasse »GWTTestCase«, die die Junit-Integration umsetzt. Das Kommandozeilen-Tool »junitCreator« generiert alle nötigen Dateien inklusive der eigentlichen Test-Klasse:

junitCreator.cmd -junit eclipse/plugins/org.junit_3.8.1/junit.jar -eclipse myaddress_gwt2 -out myaddress_gwt2 de.wartala.myaddress.test.MyAddressTest

Die erzeugten Dateien dienen im Hosted ebenso wie im Web Mode zum Testen, und zwar sowohl innerhalb von Eclipse als auch über die Kommandozeile. Läuft die Applikation fehlerfrei, macht das Skript »Projektname-compile.sh« aus der Java-Applikation eine Javascript-Version. Es kopiert und generiert alle nötigen Dateien im Unterordner »www« des beim Aufruf von »junitCreator.cmd« aktuellen Verzeichnisses.

Die GWT-Java-Klassenbibliothek

Das Google Web Toolkit bietet einiges mehr als im Beispiel gezeigt. 20 Widgets stehen zur Verfügung, die Dokumentation zeigt in der Widget-Galerie [6] einen Überblick. Neben den HTML-Äquivalenten zu Checkboxen und Radiobuttons sind besonders die Layout-Manager (Panels) von Nutzen (Abbildung 4). Sie nehmen wie unter AWT und Swing Widgets auf und gruppieren sie nach Wunsch. Um zum Beispiel Schaltflächen untereinander anzuordnen, bietet sich das Widget »VerticalPanel« an.

GWT unterstützt auch das Erstellen neuer Widgets, [7] und [8] bieten Beispiele und Tipps zu diesem Thema. Um das Framework hat sich in kurzer Zeit bereits eine rege Community gebildet, die über Google Groups [9] Fragen zum Thema diskutiert. (csc)

Infos

[1] Google Web Toolkit: [http://code.google.com/webtoolkit]

[2] Ajax: [http://de.wikipedia.org/wiki/Ajax_(Programmierung)]

[3] JSON: [http://www.json.org]

[4] Ajax und PHP: [http://www.ajax-info.de/uebersicht-ajax-frameworks/php-frameworks]

[5] Ajax und Perl: [https://www.linux-magazin.de/Artikel/ausgabe/2005/12/perl/perl.html]

[6] GWT-Widget-Galerie: [http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.UserInterface.WidgetGallery.html]

[7] GWT-Widget-Bibliothek: [http://gwt-widget.sourceforge.net]

[8] Gwtpowered.org: [http://gwtpowered.org]

[9] GWT-Gruppe bei Google Groups: [http://groups.google.com/group/Google-Web-Toolkit]

[10] Beispielserver- und -client aus diesem Artikel: [https://www.linux-magazin.de/Service/Listings/2006/10/gwt]

Der Autor

Ramon Wartala ist Software Engineer bei AOL Deutschland in der Abteilung Development & Architecture und beschäftigt sich außer mit dem Internet als solchem in seiner Freizeit gerne mit seiner Frau.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben