Da poco mi sono imbattuto, a fini di studio e mera cultura personale, nell'oramai celebre framework Google Web Toolkit (GWT). Questo framework, in sostanza, permette lo sviluppo di applicazioni web AJAX-based in linguaggio Java (seppure con alcune restrizioni, come vedremo), che, in fase di compilazione, viene convertito in Javascript ottimizzato e compatibile con i principali browser. In sostanza, chi è particolarmente abituato a sviluppare il proprio codice in linguaggio Java può sfruttare il proprio know-how per utilizzare GWT, sfruttando allo stesso tempo i vantaggi di Javascript: velocità (il codice prodotto da GWT è altamente ottimizzato e performante) e supporto con tutti i browser, senza doversi "sporcare le mani" nello sviluppo di codice JS (per chi ci è passato, non è il linguaggio di sviluppo più semplice del mondo).
Prima di andare avanti, un utile appunto per gli sviluppatori: diventare operativi su questa tecnologia è veramente semplice. Si può scegliere se utilizzare GWT tramite command-line oppure mediante un plugin per Eclipse : personalmente, ho seguito la seconda modalità, installando ed utilizzando senza problemi il plugin per Eclipse 3.4. Resta inteso che il plugin Eclipse ufficiale di Google non è l'unico: in rete si possono trovare una miriade di tool e plugin per tutti i gusti. Una volta installato il plugin siamo già operativi, possiamo sviluppare applicazioni web, testarle localmente e, se connessi ad Internet, deployarle su Google Apps, uno spazio gratuito a disposizione di ogni utente Google, su cui caricare, testare e condividere le proprie creazioni (tutto questo con semplici click in Eclipse sui pulsanti aggiunti alla toolbar dal plugin).
Dov'eravamo rimasti? Ah ok, abbiamo descritto come avviene lo sviluppo di codice client-side (sviluppo in Java, successivamente tradotto in Javascript). Per invocare codice server-side, GWT offre la funzionalità RPC: in modo simile al tradizionale Java RMI, si crea un'interfaccia che specifica i metodi remoti da invocare. Quando invoco un metodo remoto da browser, GWT RPC serializza gli argomenti, invoca il metodo opportuno sul server, e deserializza il valore di ritorno per il codice client.
I moduli GWT sul nostro web server altro non sono che moduli Javascript e altri file collegati. Per essere eseguiti, devono essere invocati da una pagina web (non necessariamente statica, ma anche crata da una serlet o da una JSP) attraverso il tag <script>: per chi sviluppa applicazioni web, niente di nuovo. Questa pagina web è chiamata host page della nostra appplicazione GWT. In pratica, una tipica applicazione GWT non inlcude alcun contenuto nel body, se non l'invocazione dello script.
<body>
<script language="javascript" src="calendar/calendar.nocache.js"></script>
...
</body>
E' anche possibile permettere al modulo GWT di inserire widget in punti specifici della pagina HTML, usando l'attributo id nei tag HTML per specificare un identificativo che il mio codice GWT code userà per "attaccare" dei widget a quell'elemento HTML.
<td id="slot1"></td>
E nel codice Java:
final Button button = new Button("Click me");
RootPanel.get("slot1").add(button);
La struttura standard di un progetto GWT è la seguente:
- cartella src - sorgente java (sia client che server, preferibilmente in package diversi) e definizioni dei moduli GWT (file XML)
- cartella war - contiene sia risorse statiche, sia output compilato; è l'immagine di deployment della mia applicazione, ed è in formato WAR standard riconosciuto dai web server. Include anche web.xml e i file class/jar necessari al codice server-side.
- cartella test folder - (opzionale) codice di test JUnit
I moduli sono le unità di configurazione GWT, e contengono le informazioni necessarie al modulo, come la entry point class, i moduli da cui eredita, lo stile, ecc... Sono contenuti in file xml della forma <nome_modulo>.gwt.xml. Posso sviluppare la logica applicativa in più moduli, che posso includere (o ereditare) nel mio modulo principale. I moduli che non devono essere invocati direttamente ma che vengono ereditati dal altri moduli non devono definire un entry point. Se invece nella host page invoco N moduli (attraverso il tag script), allora ognuno di essi deve definire un entry point.
Cosa è esattamente un entry point? si tratta di una classe Java (dichiarata nel file XML di definizione del modulo) che deve implementare l'interfaccia EntryPoint, e di conseguenza deve fornire una implementazione del metodo onModuleLoad, invocato per primo quando eseguo l'applicazione. Solitamente in questo metodo vengono creati nuovi componenti grafici, vengono impostati gli handler per gli eventi (a chi ha avuto modo di utliizzare Swing tutto questo suonerà familiare) e viene modificato il DOM del browser in qualche modo.
In GWT troviamo il concetto di hosted mode e di web mode. Mentre sviluppiamo, possiamo eseguire la nostra webapp in hosted mode, ovvero sotto forma di bytecode che gira nella nostra JVM, come una normale applicazione java standalone. Dopo avere cliccato "Run" mediante il pulsante in Eclipse, accediamo alla Hosted Mode console:
Da qui è possibile lanciare lanciare la nostra applicazione nell'Hosted Browser (un browser embedded), oppure avviare la compilazione (mediante il pulsante Compile/Browse) che rende l'applicazione pronta per passare in web mode.
Una volta compilata la nostra applicazione, il codice Java è stato tradotto in codice Javascript: a questo punto siamo pronti per fruire la nostra applicazione sui browser tradizionali e, se lo desideriamo, renderla disponibile per ogni web server, passando quindi in web mode. Prima di passare in web mode, dobbiamo sincerarci che il nostro codice Java non utilizzi classi "proibite", ovvero che non siano traducibili in JavaScript. In hosted mode, GWT usa la JRE Emulation Library per verificare la validità del nostro codice. Per un elenco delle classi utilizzabili si consulti la JRE Emulation Reference.
Tra le molte utili features offerte da GWT, vale la pena nominare la classe Timer, che permette di schedulare l'esecuzione di un metodo (una volta o periodicamente), le classi per effettuare il parsing e manipolare oggetti JSON (il più delle volte un oggetto JSON viene ritornato come risposta ad una HTTP request), le classi per fare parsing e costruire file XML, l'utilizzo di JSNI (JavaScript Native Interface) per integrare GWT con codice JavaScript scritto a mano o con librerie JavaScript di terze parti, o per accedere a funzionalità del browser di basso livello (non coperte da GWT), la possibilità di far comunicare codice Java con codice JavaScript, il deferred binding.
Per il momento è tutto, diciamo che il mio approccio a GWT è ancora "work in progress"...i frutti dei miei esperimenti li trovate qui.
Ciao Matteo,
ReplyDeletebell'articolo... molto chiaro.
In ke parte del mondo ti trovi adesso?
Un abbraccio
Sasà
ciao Sasa', grazie per il commento! Mi trovo in UK adesso...
ReplyDeleteciao, volevo chiederti una cosa riguardo le gwt, magari puoi essermi d'aiuto...io ho realizzato un web project e quando lo testo localmente facendo run funziona tutto (nello specifico vedo che le http post request vengono inviate) , presumo perchè in modalità run eclipse tira su jetty come server locale.
ReplyDeleteQuando carico sul mio server esterno (dove ho il mio sito web) dove c'è Apache con CentOS, i servizi sembrano funzionare, ma le http post request non vengono inviate.
Sapresti per caso darmi una mano?
grazie mille!
Ciao Matteo,
ReplyDeletevolevo chiederti delle informazioni, siccome sono alle prime armi con GWT. Ho letto il tuo articolo e ho provato a sperimentare un pò di cose!!Siccome vorrei creare un progetto esempio un pò più complesso secondo te mi conviene sempre partire dal progetto esempio quello fornito da GWT?? e modificare quello??
Un ultima cosa io ho provato a creare il progetto sia con eclipse e sia con i comandi Dos (webAppCreator) però ho notato che quando lo importo con eclipse non me lo riconosce cm applicazione WEB di Google (infatti non mi fa fare il RAN AS Web Application) ma devo usare Ant per avviare l'esecuzione via Web!!Tu che ne pensi??Forse sbaglio da qualche parte??