Google ja AJAX ning tore aeg

Google AJAX framework ehk GWT (Google Web Toolkit | http://code.google.com/webtoolkit/ ) on Google poolt välja antud AJAXI API (nagu nimigi vihjab), mis peaks AJAX-it kasutavate aplikatsioonid tegemist hõlbustama. Asja omapära on selles, et kirjutatakse koodi Javas, mis hiljem kompileeritakse JavaScriptiks.

Sai siis otsustatud, et teeks ühe reallife testimise antud jubinaga. Ülesandeks oli GWT-d kasutades teha olemasolevale süsteemile (J2EE +JSP) interaktiivne andmete uuendamine.

Asi sai siis kätte võetud ja alustatud algusest peale, puhtalt lehelt. GWT õpetuste järgi on küllaltki kerge esialgu järje peale saada. Kõvasti aitavad kaasa ka GWT tööriistad, mis valmistavad ette Eclipse-i projekti koos vajalike skriptide/failidega ja samuti genereerivad kõik vajamineva uue aplikatsiooni ehitamiseks. Loodud failide hulgas on skriptid koodi jooksutamiseks nii hosted mode-is kui kompileerimiseks. On ka ette antud “Hello World!” näide, mida oli alustuseks väga mõnus näppida.

HTML-i muutmine GWT-s on umbes nagu teada-tuntud Java enda Swingiga töötamine. Klopsid paar Widgetit kokku, lisad vajaliku informatsiooni ning paned kõik paneelile. HTML-i ise kirjutama ei pea, loomulikult, kui on vaja, siis saab HTML-i widget-i teha ja sinna sisse koodi kirjutada. Väike näide:

[java]
//Make a html table 4×2
HTMLTable table = new Grid(4,2)
//Make a text lable
Label label = new Label();
//Put some text on the lable
label.setText(“Kasutajanimi:”);
//maybe even some css
label.setStyleName(“input”);
//fill the table first field with the lable
table.setWidget(0,0,label);
//put the table on the rootpanel
RootPanel.get().add(table);
[/java]

Vastavalt vajadusele ja tahtmisele on võimalik HTML-i muuta ka DOM puu kaudu. Seda läheb vaja, kui lehe muutmise asemel oleks vaja näiteks infot lehelt kätte saada. JavaScriptiga võrreldes on süntaks ja kasutus vägagi sarnased. Näituseks:
[java]
//element = document.getElementById(id);
Element el2 = DOM.getElementById(“defsrvcnt”);
//str = element.value;
String value = DOM.getAttribute(el2,”value”);
[/java]

Ei tohi ka ära unustad HTML event-e, mis omavad implementatsiooni ka GWT-s.

[java]
button.addClickListener(new ClickListener()
{
public void onClick(Widget sender)
{
//Click…
}
});
[/java]
Iseenesest ei midagi rasket… kui alustatakse nullist uut projekti. Aga nagu ennist kirjas, siis meie soov oli lisada olemasolevale projektile GWT maagiat. See ülesanne tegi olukorra tsipa keerulisemaks, kuigi mitte ületamatult raskes.

Kõigepealt, et midagi üldse tööle saada, pidi mõnevõrra muutma genereeritud skriptide sees leiduvaid path-e. See aga osutus aga mõnevõrra keerulisemaks, kui võib arvata. Nimelt koostab GWT kasutatavad path-id skriptidest saadud info ja Java klasside nimede kaudu, kusjuures teatud kohtades on kasutusel “<package_name>.client.<MyClassName>” ja teistes lihtsalt “<package_name>.<MyClassName>”. Selline süsteem tekitas mõnda aega segadust, aga mõningase katsetamise ja muutmise tulemusena sai see tõke ületatud ning tagasi vaadates, ei tundu see asi enam nii segasena.

Järgnesid veel paar pisemat probleemi, nagu näiteks projekti server kasutas vana JRE1.3-e, kuid GWT tahab edukaks tööks JRE1.4 või uuemat. Kuna serveri tarkvara ei ole võimalik meist olenematutel põhjustel muuta, siis sai Ant-i skriptis teha uus task, mis jooksutas GWT kompilaatorit uuemas Javas. Ka Ant ise tuli jooksma panna uuemas JRE-s.
Siis oli veel .jsp ja GWT genereeritava JavaScripti vaheline suhtlemine, mille lahenduseks oleks kasutada hidden välju mõne väärtuse edastamiseks võis siis JSON http://www.json.org abiga tervet objekti.

AJAX-i rakenduse kirjutamiseks GWT abil tuleb kõigepealt ehitada järgmised interface-id:

[java]
public interface MyAjaxService extends RemoteService
{
public String myFirstMethod( String str );
}

public interface MyAjaxServiceAsync
{
public void myFirstMethod(
String str,AsyncCallback callback );
}
[/java]

Mõlemad küllaltki sarnased, kuid siiski erinevad. Esimene on interface, mis defineerib serveris/endpoint-is välja kutsutavad meetodid ja teine on sellest tuletatud. Tasub tähele panna, et teine interface-i nimi on sama, mis esimesel, kuid postfix-iga Async. Peale selle, Async interface-i meetodi return tüüp on alati void ning viimane sissevõetav argument on AsyncCallback. Järgmiseks siis serveripoolne ülesehitus:

[java]
public class MyAjaxTestService
extends RemoteServiceServlet implements MyAjaxService
{
public String myFirstMethod(String str)
{
//do stuff…
}
}
[/java]

Server implemendib esimest interface-i, implementatsioon on siinkohal sõltuv juba arendaja enda fantaasiast. Kliendipoolne ülesehitus:

[java]
public class MyClassName implements EntryPoint
{
public void onModuleLoad()
{
//..Stuff
}
}
[/java]

Selline stub on tegelikult igasuguse GWT kliendi alguseks, mis kirjeldab, kas sellest saab AJAX-i aplikatsioon või tehakse tööd ainult widget-itega. Antud nimega klass/EntryPoint on defineeritud ka tollel .html-i failis, mis antud klassi hakkab kasutama. Sidumine käib meta tagi abil, kusjuures klassinimi on koos package’ nimega (antud juhul package nimi tühi, ehk siis seda ei ole ): <meta name=’gwt:module’ content=’MyClassName’> oleks siis antud juhul korrektne.
Kuid AJAX-iga suhtlemiseks kliendi poole pealt peab veel natukene implementeerima GWT protokolli:

[java]
MyAjaxServiceAsync myService =
(MyAjaxServiceAsync) GWT.create(MyAjaxService.class);
ServiceDefTarget endpoint =
(ServiceDefTarget) myService;
endpoint.setServiceEntryPoint(
“http://localhost:888/gwtEndpoint/ajax”);

AsyncCallback callback = new AsyncCallback()
{
public void onSuccess(Object result)
{
//…YeY!
}

public void onFailure(Throwable caught)
{
//…NeY!
}
};
myService.myFirstMethod(str, callback);
[/java]

Kood küllaltki iseseletuv. “onSuccess” ja “onFailure” on siis need meetodid, mille kaudu muudetakse html-i vastuse saamisel, ja neist sõltub, kas tulemuseks on lihtne sõnum ekraanil või ehitatakse dünaamiliselt uus leht.

Märkida tuleb veel, et AJAX-i kliendil ja serveril on üks teatud piirang üksteise suhtes paiknemisel. Nimelt AJAX-i klient saab teha päringuid ainult serverisse, mis asub samas domeenis, kus klientki. Samas meie tegevuse käigus, põhjustatud eelpool nimetatud JRE1.3 probleemist, sai pandud endpoint samasse masinasse ainult teise tarkvaralisse serverisse jre1.4 sees jooksma. Sellise konfiguratsiooniga tekkis probleeme Firefox-il ning Mozilla-l, kes mõlemad ei tahtnud kuidagi ühendust saada. Samas IE7.0 ja Opera 8 ei kurtnud ning töötasid kenasti.

Kokkuvõtteks ütleks, et vaatamata mõnele väikesele tagasilöögile, ei ole millegi tõsise üle kurta. GWT-ga on mugavam AJAX-it ehitada, kui kõike käsitsi tehes. Vägagi kerge on ehitada JavaScripti põhist dünaamilist veebiliidest, eriti Swing-i tundjatele. Muidugi GWT poolt genereeritud JavaScripti ei hakka enam keegi muutma, sest selle lugemine ja arusaamine on teadus omaette. Närima jääb see, et path-id pannakse paika mudides klassi nime ja muutes skripte. Tunnen puudust ühest universaalsest kohast, kus saaks märkida “siit võtan, sinna panen” valikud. Veel vajaks märkimist, et saavutamaks platvormist sõltumatust, genereerib GWT 4 erinevat versiooni kompileeritud JavaScript-ist, ehk siis 4-le erinevale browser-i mootorile.

Aga üleüldiselt jäi positiivne tunne ja kuna GWT on veel noor (rahvale välja antud 16 Mai, 2006), siis on lootust, et asi läheb ainult paremaks.

Leave a Reply