Remote Procedure Calls mit GWT
Um im später zu JavaScript kompilierten Java-Code auf einen Remote Service zugreifen zu können, muss zunächst ein eigenes Service Interface entwickelt werden, welches das Marker Interface RemoteService erweitert. Da dieses Interface aus Architektursicht dem Client zugehörig ist, wird es auch im Package de.flavor.gwt.client platziert:public interface DemoService extends RemoteService {public String[] getData(int column);}
Wie Sie sehen können, gibt unser Interface einen Array von Strings zurück. Diese Elemente werden später die Zeilen der hinzugefügten Spalten sein. Als Nächstes muss die Funktion des Service implementiert werden. Dies geschieht durch Erweiterung eines GWT RemoteServiceServlets und der Implementierung des erzeugten Service Interface:
public class DemoServiceImpl extends RemoteServiceServlet implements DemoService {public String[] getData(int column) {... Zufällige Daten erzeugen ...}}
Da diese Implementierung nur platzraubend ist, wurde sie hier entfernt; interessierte Leser können dies im Quellcode auf der Heft-CD nachsehen. Um nun aus unserem bestehenden Java-Code tatsächlich einen Remote Call auszuführen, muss nun nur noch ein asynchrones Interface für unseren Service erstellt werden. Durch dieses Interface kann später ein Callback-Handler angegeben werden, der dann die Antwort vom Server verarbeitet, sobald diese vorliegt. Dieses Interface ist dem Service Interface sehr ähnlich, es erweitert jedoch nicht die Schnittstelle RemoteService, hat keinen Rückgabewert, jedoch einen zusätzlichen Übergabe-Parameter vom Typ AsyncCallback:
public interface DemoServiceAsync {public void getData(int column, AsyncCallback callback);}
Nun muss der Service nur noch in der Konfigurationsdatei der Applikation, DemoApplication.gwt.xml, eingetragen werden und kann fortan benutzt werden. Diese Datei befindet sich im Package de.flavor.gwt und wird um folgenden Eintrag ergänzt:
<servlet path="/getdata" class="de.flavor.gwt.DemoServiceImpl"/>
Um nun aus dem ClickHandler des ADD-Buttons einenRemote Call zu initiieren, wird die statische Methode GWT.create() benutzt:
DemoServiceAsync dataService = (DemoServiceAsync) GWT.create(DemoService.class);ServiceDefTarget endpoint = (ServiceDefTarget) dataService;endpoint.setServiceEntryPoint("/getdata");
Dabei wird das Service-Interface an die Methode übergeben und die Rückgabe auf unser asynchrones Interface gecastet. Der Endpoint des Service wird nun mit dem Pfad des Servlets initialisiert, somit weiß GWT, an welche Adresse die Anfrage zu richten ist. Nun muss noch ein AsyncCallBack-Objekt erstellt werden, bevor die Anfrage abgesetzt werden kann. Die beiden Methoden onSuccess() und onError() werden je nach Ausgang der Anfrage aufgerufen. Im Success-Fall erstellen wir eine neue Spalte für das horizontale Panel, im Fehlerfall geben wir die Fehlermeldung in einem Pop-up aus (Listing 4). Die Grafiken im Kasten „GWT-Demo-Applikation“ zeigen einige Screenshots dieser Demo-Applikation.
Listing 4----------------------------------------------------------------------------------------AsyncCallback callback = new AsyncCallback() {public void onSuccess(Object result) {String data[] = (String[]) result;int theColumn = Integer.parseInt(data[0]) - 1;VerticalPanel p = (VerticalPanel) columns.get(theColumn);for (int i = 1; i < data.length; i++) {Label l = new Label(data[i]);l.setHeight("20");p.add(l);p.setCellHeight(l, "20");}}public void onFailure(Throwable caught) {PopupPanel popup = new PopupPanel(true);popup.add(new Label(caught.getMessage()));popup.setPopupPosition(10, 10);popup.setStyleName("popup");popup.show();}};dataService.getData(columns.size(), callback);
Die Applikation startet ohne Inhaltsspalten und baut sich dann durch Klicken der ADD-/REMOVE-Buttons auf und ab. Bei jedem Hinzufügen einer Spalte wird dabei ein AJAX Request zum Server abgesetzt. Siehe die folgenden Abbildungen.
Fazit zu GWT
Sie haben sicherlich gemerkt, dass wir keinerlei JavaScript-Code schreiben mussten, und selbst unsere HTML-Kenntnisse wurden nicht zu sehr herausgefordert. Natürlich hätte der dynamische Teil der Applikation noch in einen schickeren HTML-Rahmen sitzen können, wir konnten aber auch so ein ganz respektables (und vor allem sehr flexibles) UI in sehr kurzer Zeit erstellen.Erstaunlicherweise haben die Erstellung des UI sowie die Entwicklung der AJAX-Anfragen in purem Java-Code stattgefunden, und die Arbeit mit GWT war insgesamt sehr angenehm. Sobald man die Grundzüge verstanden hat und weiß, wie CSS zur Formatierung der Elemente einzusetzen ist, kann man mit GWT recht schnell gute Ergebnisse erzielen.
Im Gegensatz zu DWR eignet sich GWT jedoch nicht, um bestehende Webapplikationen nachträglich mit AJAX-Features auszurüsten. Dafür sind die Konzepte von GWT (Kompilieren von Java zu JavaScript) zu sehr von traditionellen Webentwicklungskonzepten entfernt. Ein weiterer Punkt, der bei einigen Lesern Skepsis auslösen wird, ist die Tatsache, dass GWT zwar kostenlos ist, jedoch nicht Open Source. Der Java-to-JavaScript Compiler wird beispielsweise als Binary geliefert, und schon so mancher Entwickler hat sich dazu im GWT-Forum skeptisch geäußert.
Ein weiterer Wermutstropfen ist, dass GWT allein für Windows und Linux zur Verfügung steht ... Mac OS X-User sind momentan (Stand 25. September 2006) noch außen vor.
Quo vadis AJAX & Java?
Wir haben hier zwei derzeit relevante AJAX-Toolkits, DWR und GWT, vorgestellt. DWR hat den Vorteil, dass es sich einfach in bestehende Java-Webapplikationen integrieren lässt, allerdings muss der Entwickler immer noch einiges an JavaScript-Code selbst entwickeln, und vor allem JSF-Entwickler sollten vorsichtig sein, da die JSF-Erweiterung von DWR nicht in den standardisierten JSF Lifecycle integriert ist.GWT verfolgt im Gegensatz zu DWR den Ansatz, dass der Entwickler sehr wenig bis überhaupt kein JavaScript entwickeln muss, um AJAX nutzen zu können. Die Erstellung von UIs war erstaunlich einfach, und auch das Hinzufügen von AJAX-Aufrufen ging problemlos vonstatten. Dank dem Hosted Mode kann man Veränderungen rasch wieder testen und bekommt so viel häufiger Feedback.
Der fehlende Support für Mac OS X ist nur ein kleiner Wermutstropfen, viel eher ins Gewicht fällt, dass Teile des GWT nicht Open Source sind und wichtige Elemente als Binaries ausgeliefert werden. Jeder muss für sich entscheiden, ob er damit einverstanden ist. Spannend sind die beiden Toolkits auf jeden Fall, und ich kann Ihnen nur zum Ausprobieren der beiden Projekte raten!




