Máte rádi all-in-one řešení? A proč se ptám? Protože Google Web Toolkit je právě jedním z all-in-one řešení. Určitě jsou frameworky, které zvládají jednotlivé stavební kameny GWT lépe, ale GWT je unikátní právě ve smíchání všeho potřebného k tvorbě Rich Internet Applications na platformě Java.

Myšlenka Google Web Toolkit (zkráceně GWT) je jednoduchá. Poskytněme framework, ve kterém si uživatel bude moci jednoduše vytvořit webovou aplikaci složenou ze znovupoužitelných UI komponent (renderovaných jako HTML) a logiky (ve formě JavaScriptu) na straně webového prohlížeče a asynchronního volání serverové logiky skrze AJAX. To vše na platformě Java s využitím jazyka, knihoven a vývojových nástrojů této platformy.

Pojďme se podívat, co má Google Web Toolkit pod kapotou a co z něj činí kompaktní řešení.

GWT architektura

GWT architektura
GWT architektura

Systém Google Web Toolkit se skládá z pěti stavebních kamenů:

  • kompilátor Javy do JavaScriptu
  • emulace Java platformy
  • komponenty pro tvorbu uživatelského rozhraní
  • vývojový shell
  • asynchronní implementace vzdáleného volání

Kompilátor Javy do JavaScriptu

Jestliže má některá z pěti základních komponent klíčovou roli, pak je to kompilátor Javy do JavaScriptu. Zdrojové kódy aplikace postavené na GWT se vyvíjí v Javě a tu je potřeba pro webový prohlížeč přeložit do JavaScriptu.

Emulace Java platformy

Emulace Java platformy představuje jednak podporu syntaxe a konstruktů jazyku na úrovni verze 1.4 a jednak části základního API z balíčku java.lang a java.util. Zmíněné Java API, například java.lang.String, je tedy reimplementováno v JavaScriptu. Díky tomu kód napsaný v Javě a přeložený do JavaScriptu může běžet v prostředí prohlížeče

Komponenty pro tvorbu uživatelského rozhraní

UI komponenty se dají rozdělit do dvou hlavních skupin – widgets a panels. Widgets je skupina základních UI komponent, jako jsou tlačítka, tabulky, vstupní políčka, rozbalovací seznamy a podobně. Oproti tomu ve skupině panels se nalézají komponenty pro definici layoutu aplikace, tedy rozvržení komponent na stránce.

Widgets:

Ukázka komponent z rodiny widgets
Ukázka komponent z rodiny widgets (plná velikost, cca 110 kB)

Panels:

Ukázka komponent z rodiny panels
Ukázka komponent z rodiny panels (plná velikost, cca 25 kB)

Vývojový shell

Aplikace napsané v Google Web Toolkit mohou běžet ve dvou módech, hosted a web. Ve web módu je aplikace zkompilovaná do JavaScriptu a běží jako jakákoli jiná webová aplikace. V hosted módu se aplikace spouští jako klasická Java aplikace v prostředí speciálně upraveného GWT prohlížeče – je ji tak možno například debugovat v IDE jako jakoukoli jinou Java aplikaci.

Web mód – aplikace je zkompilovaná do JavaScriptu a běží v klasickém prohlížeči.

Web mód - obrázek prohlížeče Firefox
Web mód – obrázek prohlížeče Firefox (plná velikost, cca 40 kB)

Hosted mód – aplikace během vývoje běží převážnou většinu času v hosted módu, kde je ji možno snadno debugovat. Na obrázku níže je vidět GWT prohlížeč speciálně upravený pro interakci s JVM běžícím v debugu. Serverová část aplikace běží na zabudovaném serveru Tomcat.

Hosted mód - obrázek GWT prohlížeče
Hosted mód – obrázek GWT prohlížeče (plná velikost, cca 60 kB)

Debugování aplikace v IDE eclipse
Debugování aplikace v IDE eclipse (plná velikost, cca 70 kB)

Asynchronní implementace vzdáleného volání

Aby aplikace běžící v prohlížeči dokázala komunikovat se serverem, lépe řečeno přímo volat aplikační logiku, je potřeba implementovat nějakou formu vzdáleného volání metod, takzvané Remote Procedure Call (RPC). V prostředí webového prohlížeče to lze udělat posíláním XML přes HTTP, a to nejlépe asynchronní formou (požadavek nevyžaduje znovunačtení okna prohlížeče) pomocí klientského objektu XMLHttpRequest.

Díky RPC se vlastní voláni serverové logiky jeví jako lokální a klientský kód je dokonale odstíněn od HTTP, XML a nutného zla kolem serializací a deserializací posílaných objektů. Následující obrázek ilustruje rozložení vzdáleného volání na klientský kód a serverový kód:

RPC přehled z hlediska serverového a klientského kódu
RPC přehled z hlediska serverového a klientského kódu (plná velikost, cca 15 kB)

Z obrázku se to může zdát složitější, než to ve skutečnosti je. Podívejme se na RPC komunikaci přes jednoduchý „HelloWorld“ příklad.

Za prvé, nadefinujeme rozhraní objektu, který chceme na serveru volat. Řekněme, že bude mít jednu metodu, která bude vracet nějaký text. Jediný rozdíl oproti jakémukoli jinému Java rozhraní je v tom, že naše rozhraní musí být potomkem GWT rozhraní RemoteService.

public interface HelloWorldService extends RemoteService{
  public String sayHello();
}

Za druhé, pro klientský kód aplikace potřebujeme analogické rozhraní převedené do asynchronního módu. Všechny metody původního rozhraní přepíšeme tak, aby byl návratový typ void a každá metoda měla jako poslední argument navíc objekt AsyncCallback.

public interface HelloWorldServiceAsync {
  public void sayHello(AsyncCallback callback);
}

Za třetí, původní rozhraní (synchronní) musíme také naimplementovat. K požadavkům na implementaci musíme přidat to, že objekt musí být potomkem RemoteServiceServlet.

class HelloWorldServiceImpl extends RemoteServiceServlet implements HelloWorldService {
  public String sayHello() {
    return „Hello world!“;
  }
}

Nyní je kód připraven k volání za použití asynchronního volání.

//(1) Vytvoříme si klientskou proxy, která nás odstíní od vzdáleného volání
HelloWorldServiceAsync helloService = (HelloWorldServiceAsync) GWT.create(HelloWorldService.class);
// (2) Nastavíme endpoint, na kterém je vzdálená implementace vystavená
ServiceDefTarget endpoint = (ServiceDefTarget) helloService;
endpoint.setServiceEntryPoint(„/helloService“);
// (3) Vytvoříme callback objekt pro zpracování výsledku volání
AsyncCallback callback = new AsyncCallback() {
  public void onSuccess(Object helloText) {
    Window.alert((String) helloText);
  }
  public void onFailure(Throwable caught) {
    Window.alert(„Ooops something went wrong:“ + caught.getMessage());
  }
};
// (4) Provedeme vlastní volání, vykonávání kódu pokračuje dál.
// Výsledek je delegován na callback objekt (viz 3)
helloService.sayHello(callback);

Pokud mluvíme o RPC musíme nutně zmínit i serializaci a deserializaci Java a JavaScript objektů posílaných mezi klientem a serverem. GWT framework podporuje v základu pouze malou množinu objektů jako java.lang.String a podobně. Pokud chceme posílat mezi klientem a serverem vlastní objekty, musíme dodržet následující pravidla:

  1. Objekt musí implementovat GWT rozhraní IsSerializable. Jedná se o rozhraní typu marker, podobně jako javovské Serializable.
  2. Pokud je argumentem nebo návratovým typem business rozhraní kolekce, musí být typově anotovaná javadoc elementem @gwt.typeArgs v rozhraní, které ji definuje. Například pokud vracíme list řetězců, musíme použít v javadocu metody @gwt.typeArgs <java.lang.String>.
  3. Všechny vnitřní property objektu musí splnit obě předešlé podmínky.

Detailně jsou podmínky pro serializaci popsány v sekci dokumentace Serializable Types.

Jak to celé funguje

Pro běh ve web módu se klientská část aplikace přeloží do JavaScriptu. Pro její zavedení do prohlížeče slouží jakákoli webová stránka s přilinkovaným GWT JavaScriptem a anotací ve formě meta elementu, který označuje zaváděcí modul vaší aplikace.

Ukázka zaváděcí stránky
Ukázka zaváděcí stránky (plná velikost, cca 30 kB)

V této souvislosti stojí určitě za zmínku definice modulu GWT aplikace, představované XML souborem. V tomto souboru s krom jiného definuje zaváděcí třída vaší aplikace a endpointy pro jednotlivé objekty vystavené pro RPC.

GWT modul
GWT modul (plná velikost, cca 20 kB)

Další funkce GWT frameworku

Krom zmíněných stavebních kamenů má GWT framework i další užitečné funkce, které usnadňují tvorbu aplikací.

Management historie
GWT umožňuje řešit velice elegantní cestou problém všech AJAX aplikací. Ten problém se jmenuje „tlačítko zpět“ (back button). Pokud vaše aplikace implementuje Google Web Toolkit rozhraní HistoryListener (obsahuje metodu onHistoryChanged(String historyToken)), je možné na každou změnu stavu reagovat patřičným nastavením aplikace do daného stavu. Přechod ze stavu do stavu je rozlišen pomocí argumentu historyToken.
Internacionalizace
I18N je řešena obdobným způsobem jako v Javě. Základem lokalizace jsou properties soubory, ve kterých jsou přeložené texty, a Java rozhraní, které k nim umožňuje přístup. GWT rozděluje I18N na dva typy, takzvané Constants a Messages. Rozdíl je v tom, že v případě Messages jsou lokalizované texty parametrizovatelné, kdy se část textu uvozená složenými závorkami a číslem nahradí předaným parametrem.
Skládání UI a stylování
Základní komponenty pro tvorbu uživatelského rozhraní lze dále rozšiřovat jejich skládáním do kompaktnějších celků. Například základní komponentu „tabulka“ můžete rozšířit o ovládací prvky pro stránkování. Každá základní komponenta má navíc standardně nadefinovanou třídu (atribut), díky čemuž je stylovatelná pomocí CSS. V rámci API je pak možné každé UI komponentě (i složené) přiřadit libovolnou CSS třídu. Oddělení toho, jak jsou komponenty složené (objektový model), a toho, jak vypadají (CSS), přispívá k větší čistotě kódu.
Command line nástroje
GWT obsahuje nástroje pro rychlé a efektivní používání frameworku. Kromě zmíněného I18N creatoru obsahuje nástroje pro vygenerování kostry aplikace a projektových souborů pro import do IDE Eclipse. Tím se minimalizuje čas nutný na první seznámení s Google Web Toolkit a vývojář si hned může začít zkoušet.
JUnit integrace
Toolkit umí vygenerovat speciální TestCase (základní třída pro testování), pomocí kterého lze psát unit testy na klientskou i serverovou část API aplikace.
JSNI
Pomocí JavaScript Native Interface rozhraní umožňuje Google Web Toolkit v rámci Java kódu napsat JavaScript, který může zpětně volat nějaký Java kód.

Pár slov na závěr

O GWT by se dalo napsat mnohem více, ale rád bych na závěr krátce zmínil některé rysy vývoje, ke kterým použití GWT směřuje:

  • Rapid Application Development na webu díky využití platformy Java a jejích technologií a nástrojů.
  • Odstínění od webu jako takového, model podobný konceptu vývoje desktopové aplikace.
  • Snaha o oddělení vizuálních vlastností komponent od jejich rozložení.
  • All-in-one přístup (vše v jednom).

Výhody GWT

  • opravdu jednoduchý a rychlý vývoj Rich Internet Application
  • GWT je velice dobře dokumentované
  • stále rostoucí komunita uživatelů
  • podpora od Google
  • možnost využití nástrojů platformy Java
  • existence projektů třetích stran – UI knihovny, integrace s JSF

Původní diskuse ke článku

Původní diskuse k tomuto článku naleznete zde.

Žádný příspěvek v diskuzi

Odpovědět