
| Ajax Asynchronous JavaScript and XML. Ajax ist ein Konzept, das den asynchronen Austausch von XML-Nachrichten zwischen Client und Server erlaubt, ohne dass eine Web-Seite komplett neu geladen werden muss. |
| GWT Google Web Toolkit. Eine Java-Entwicklungsumgebung zur Erstellung von Web-Anwendungen auf Basis von Ajax. |
| Widgets Grafische (Software-) Komponenten wie z. B. Buttons, Textfelder und Checkboxen. |
| RPC Remote Procedure Call. Mechanismus zur Kommunikation mit einem Server über ein Netzwerk. |
| JVM Java Virtual Machine. Programm, in dem Java-Programme ausgeführt werden. Eine JVM ist vom Betriebssystem abhängig, während das Java-Programm unabhängig vom Betriebssystem ist. |
Weiterführende Links
Das Google Web Toolkit zur Entwicklung von Ajax-Anwendungen ist auf den Google Web-Seiten [4] erhältlich: Als zip-File für Windows oder als tar.gz-File für Linux. Nach dem Extrahieren des Archivs kann die Entwicklung beginnen.
Das SDK besteht aus dem GWT Compiler, der JavaScript aus üblichem Java Code erzeugt. Dazu greift er auf eine Klassenbibliothek zurück, die ebenfalls mitgeliefert wird. Zusätzlich beinhaltet das Paket eine Laufzeitumgebung zum Testen der Anwendung und eine Reihe von Beispielen zur Demonstration der Funktionalitäten.
Der GWT Compiler ist das Kernstück des Toolkits und generiert JavaScript aus Java Code. Dazu muss der implementierte Java Source Code kompatibel mit J2SE 1.4.2 sein. Das heißt, dass Java 5 Features nicht unterstützt werden.
Einige Besonderheiten ergeben sich außerdem durch Einschränkungen der Sprache JavaScript. z. B. sind JavaScript-Anwendungen "Single Threaded", so dass das Java-Schlüsselwort "synchronized" keinen Effekt hat. Es gibt auch einige Einschränkungen bezüglich der Datentypen.
So wird z. B. ein Java "long" in eine JavaScript-Gleitkommazahl mit zwei Stellen Präzision umgewandelt. Das Java Exception Handling kann verwendet werden, jedoch lässt sich kein Stacktrace aus einer Exception extrahieren.
Die GWT-Laufzeitumgebung besteht aus einer kleinen Untermenge der Standard Java Laufzeitumgebung mit den Paketen java.lang und java.util. Dies liegt daran, dass die übersetzten Anwendungen im Browser lauffähig sein müssen und Google nicht die komplette JRE Runtime-Bibliothek in JavaScript nachbauen wollte bzw. konnte.
Der Entwickler sollte sich deshalb frühzeitig anhand der mitgelieferten API-Referenz darüber informieren, welche Funktionalitäten der Standard VM genutzt werden können.
Das Google Web Toolkit stellt dem Entwickler außerdem die folgenden zwei Skripte zur Verfügung:
Mit dem ersten Skript wird die JavaScript-Übersetzung durchgeführt. Es werden Dateien erstellt, die die Ausführung der Anwendung client-seitig im Browser ohne eine JVM ermöglichen. Anwendungen laufen dann im so genannten "Web Mode".
Das zweite Skript sorgt für die Ausführung der Anwendung in einer (eingeschränkten) JVM. Der Java Code wird also nicht in JavaScript übersetzt, sondern als gewöhnlicher Byte Code ausgeführt. Dieser Modus ist sinnvoll bei der Entwicklung, da das Debugging erleichtert wird und die Zeit zum Übersetzen wegfällt.
GWT-Anwendungen sind in client- und server-seitigen Code unterteilt. Der Client Code wird von dem GWT Compiler in JavaScript übersetzt und unterliegt deshalb den bereits beschriebenen Einschränkungen. Die zu übersetzenden Sourcen werden in dem Paket my_package.client abgelegt.
Des Weiteren gibt es die serverseitige Komponente. Sie unterliegt keinen Einschränkungen und kann auf sämtliche Java Bibliotheken zugreifen. Serverseitig kommen Servlets zum Einsatz, die die Ajax Requests des Clients bearbeiten. Sie werden im my_package.server-Paket abgelegt.
![]() |
| Abb. 1: Beispiel zur automatischen Vervollständigung mit dem GWT. |
Im Folgenden wird beispielhaft auf die wichtigsten Komponenten einer GWT-Anwendung eingegangen. Erstellt wird eine HTML-Seite mit einer Text-Box.
Gibt der Benutzer in diese einen Buchstaben ein, wird - asynchron - eine Liste von Auswahlmöglichkeiten vom Browser geladen (siehe Abbildung 1).
Um das Grundgerüst einer GWT-Anwendung zu erstellen, liefert das Framework ein Tool namens "Application Creator" mit. Durch den Aufruf des Befehls applicationCreator com.mycompany.client.MyApplication werden sämtliche Dateien erstellt, die zur Ausführung eines "Hello World"-ähnlichen Programms benötigt werden. Auf diese Weise erhält man schnell die Basis für weitere, individuelle Implementierungen.
Hilfreich ist dabei die Option -eclipse, über die ein Eclipse-Projekt mit entsprechenden Launch- und Debug-Konfigurationen erstellt werden kann.
Jedes Modul (bzw. Projekt in der Eclipse IDE) verfügt über eine zentrale Konfigurationsdatei. Abbildung 2 zeigt eine einfache Konfiguration. Die Klasse User muss eingebunden werden, da sie die Basisfunktionalität des Toolkits beinhaltet. Über das Element <entry-point> wird die Klasse angegeben, die beim Starten des Moduls ausgeführt wird. Schließlich wird noch das Servlet deklariert, das die Requests des Clients beantwortet.
<module>
<inherits name="com.google.gwt.user.User"/>
<entry-point class="de.ordix.client.AutoCompleteTextBoxAsync"/>
<servlet path="/AutoCompletionServlet"
class="de.ordix.server.AutoCompletionServlet"/>
</module>
|
| Abb. 2: Konfiguration eines Moduls. |
Um eine HTML-Datei mit Ajax-Funktionalität auszustatten, muss das mit dem GWT erstellte Modul bekannt gegeben werden:
<meta name="gwt:module" content="mein_paket.MyApplication">
Zusätzlich wird die GWT JavaScript-Bibliothek benötigt:
<script language="javascript" src="gwt.js"></script>
Schließlich muss noch ein Platzhalter angegeben werden, in dem die mit Ajax ausgestattete, grafische Komponente eingefügt werden soll. Google nennt diese Komponenten "Widgets". Eine Möglichkeit zur Definition eines Platzhalters ist die Vergabe einer ID, wie in Abbildung 3 zu sehen ist.
<table> <tr> <td id="slot"></td> </tr> </table> |
| Abb. 3: Platzhalter für Widgets setzen. |
Das Modul wird gestartet, sobald die HTML-Seite samt JavaScript Code vom Browser geladen ist. Zunächst wird die Methode onModuleLoad ausgeführt (siehe Abbildung 4). In dieser Methode wird ein neues Widget instanziiert und in die HTML-Seite eingebunden. Das RootPanel repräsentiert hierbei die HTML-Seite.
//Methode, die beim Starten des Moduls ausgeführt wird.
public void onModuleLoad() {
//Instanziierung eines Widgets
final AutoCompleteTextBoxAsync box = new AutoCompleteTextBoxAsync();
//Widget platzieren
RootPanel.get("slot").add(box);
}
|
| Abb. 4: Einstiegspunkt des Moduls. |
Damit der Client mit dem Server kommunizieren kann, wird von Google ein "Remote Procedure Call"-Mechanismus bereitgestellt. Dazu muss clientseitig das Interface RemoteService mit der Deklaration der gewünschten Methode implementiert werden (siehe Abbildung 5).
public interface AutoCompletionDataService extends RemoteService {
public String[] getData(String match);
}
|
| Abb. 5: Implementierung des RemoteService. |
Die Methode getData soll auf Basis der Benutzereingabe ein Array an Auswahlmöglichkeiten zurückliefern. Die Benutzereingabe wird als Argument String match übergeben. Diese Auswahl wird dann im Zuge der automatischen Vervollständigung angezeigt.
Zusätzlich muss clientseitig noch ein weiteres Interface implementiert werden, das über Namenskonvention (hier AutoCompletionDataService mit Suffix Async) mit dem RemoteService in Beziehung steht. Dieses Interface signalisiert, dass es sich um einen asynchronen Aufruf handelt. Deshalb hat die Methode getData in diesem Interface auch keinen Rückgabewert, sondern das Argument AsyncCallback (siehe Abbildung 6).
public interface AutoCompletionDataServiceAsync {
void getData(String match,AsyncCallback callback);
}
|
| Abb. 6: Implementierung der asynchronen Schnittstelle. |
Dieses Argument wird zu einem späteren Zeitpunkt mit dem Ergebnis des Methodenaufrufs gefüllt.
Serverseitig wird dann die Methode getData implementiert. Dies geschieht durch ein Servlet, das von der GWT-Klasse RemoteServiceServlet erbt. RemoteServiceServlet ist ein übliches HttpServlet, das auf den RPC-Mechanismus abgestimmt wurde.
Grafische Komponenten werden im Google Web Toolkit als "Widgets" bezeichnet. Dem Entwickler werden eine Reihe von Widgets zur Verfügung gestellt. Es gibt unter anderem Textboxen, Checkboxen, Textareas, Tabellen usw. Auch eigene Widgets können implementiert werden. Ein Widget kann einen Listener implementieren, der auf Events horcht (siehe Abbildung 7).
public class TextBox implements KeyboardListener {} |
| Abb. 7: Verwendung eines KeyboardListeners. |
Die Events werden durch den Benutzer ausgelöst, z. B. durch einen Mausklick oder einen Tastendruck. Hat der Entwickler bereits Erfahrung mit Swing gesammelt, wird er sich mit den Google Widgets schnell zurechtfinden.
Diverse Methoden können implementiert werden, um auf die ausgelösten Ereignisse zu reagieren. Abbildung 8 zeigt die Methode, die beim Loslassen einer Taste ausgeführt wird. Sie überprüft, ob sich mindestens ein Buchstabe im Textfeld befindet und baut dann die Auswahlliste neu auf. Dazu wird ein asynchroner XMLHTTP Request durchgeführt, der in der Methode getCompletionItems durchgeführt wird.
//Wenn die Taste losgelassen wird:
public void onKeyUp(Widget widget, char key, int modifier) {
if (this.getText().length() > 0 ) {
//Hole die Auswahlliste auf Basis des eingegebenen Textes
getCompletionItems(this.getText());
}
|
| Abb. 8: Reaktion auf Events. |
Abbildung 9 zeigt die Schritte zur Durchführung eines asynchronen XMLHTTP Request. Entscheidend ist der Aufruf der Methode getData, die vom RemoteServiceServlet implementiert wurde. Als Argument wird einmal das Suchmuster übergeben und ein Objekt der Klasse AsyncCallback. AsyncCallback beinhaltet zwei Methoden:
Diese beiden Methoden dürfen keinen Rückgabewert haben, da es sich um einen asynchronen Request handelt und der Rückgabewert erst zu einem späteren Zeitpunkt zur Verfügung steht. Das Ergebnis des Requests wird deshalb in Form des Arguments result vom Framework übergeben. Die Methode updateChoices sorgt schließlich für den Neuaufbau der Auswahlliste.
public void getCompletionItems(final String match) {
AutoCompletionDataServiceAsync dataService = (AutoCompletionDataServiceAsync)
GWT.create(AutoCompletionDataService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) dataService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "/AutoCompletionServlet”;
endpoint.setServiceEntryPoint(moduleRelativeURL);
dataService.getData(match,new AsyncCallback(){
public void onSuccess(Object result){
updateChoices((String[])result,match);
}
public void onFailure (Throwable caught){
Window.alert("Unable to get data from server: "+caught.toString());
}
});
}
|
| Abb. 9: Durchführung des XMLHTTP-Requests. |
Die generellen Vor- und Nachteile von Ajax-Anwendungen wurden bereits in der letzten Ausgabe der ORDIX News dargelegt. Im Folgenden führen wir nun die Vor- und Nachteile des Google Web Toolkits für Sie auf.
Das Google Web Toolkit ermöglicht es, schnell und komfortabel Ajax-Anwendungen zu programmieren und zu debuggen. Es gibt viele Hilfestellungen und Bibliotheken, auf die der Entwickler zurückgreifen kann. Trotz des Beta Stadiums macht das Toolkit einen guten Eindruck. Es gibt bereits eine Reihe von Dokumentationen und Tipps im Internet. Problematisch ist die Integration der erstellten Servlets in andere Frameworks wie z. B. Struts. Man darf gespannt sein, wie sich die Akzeptanz des Toolkits entwickelt und welchen Einfluss es auf die Web-Programmierung nehmen wird.
Jens Stahl (info@ordix.de).