Escolar Documentos
Profissional Documentos
Cultura Documentos
it EDITORIALE
JAVA Journal
BIMESTRALE - ANNO 1 - N.3
DIRETTORE RESPONSABILE
Ajax: ritorno
MARIALETIZIA MARI
(MMARI@INFOMEDIA.IT)
DIRETTORE ESECUTIVO
MICHELE SCABARRÀ
al passato
(MICHELE.SCIABARRA@JAVAJOURNAL.IT)
EDITORIAL BOARD
Tempi complicati per noi programmatori Java, almeno per chi ha voglia di indiriz-
UGO LANDINI, STEFANO SANNA, zare la propria carriera in una direzione ben precisa. Fino a poco tempo fa non c’era
F A B I O S T A R O , TO N Y M O B I L Y dubbio che programmare in Java spesso significava programmare per il Web.
Oggi le cose si sono fatte meno certe: da un lato assistiamo allo sviluppo della piatta-
REDAZIONE forma Micro Edition, dall’altra all’attecchire di Java come piattaforma di sviluppo a
MIRELLA DI GIROLAMO tutto tondo, quindi perfettamente accettabile anche per applicazioni Desktop (cosa
fino a quale anno fa una via di mezzo tra follia ed eresia).
COLLABORATORI Allora, cosa siamo diventati? In un certo senso, lo sviluppo di Java è omogeneo con
MATTEO BACCAN lo sviluppo del Web. Java è prima di tutto e soprattutto, un linguaggio multipiat-
ANDREA COLLEONI taforma. Il terreno fertile per la prima ondata è stato quello della programmazione
JACOPO GIUDICI Web, con la sua moltitudine di server di tipo diverso.
UGO LANDINI Ma il Web è cresciuto, è diventato pervasivo, onnipresente, omnicomprensivo. Via
FE D E R I C O PA P A R O N I http ci passa di tutto, che siano file, email o transazioni di qualunque tipo. E quindi
STEFANO SANNA le applicazioni che in qualche modo hanno a che fare con il Web si sono moltiplicate.
ROBERTO SIDOTI Per esempio le applicazioni mobili, per chi lavora nell’ambiente Micro Edition, sono
FA B I O S T A R O in realtà nella maggior parte dei casi client di applicazioni Web, o browser specia-
D O M E N I C O VE N T U R A lizzati di servizio Web. Lo stesso si può dire di molte applicazioni Desktop scritte in
LUIGI ZANDERIGHI Java, che si collegano in qualche modo, soprattutto usando i Web Service, a qualche
sito web per scambiare informazioni. Sono quindi dei cosiddetti “rich-client”.
I rich-client in realtà sono la ri-edizione del vecchio modello client-server di molti
anni fa, con gli elementi innovativi del supporto multipiattaforma e dell’essere di-
stribuiti su rete geografica anziché locale. Ma il problema è che i rich-client sono
delle applicazioni Desktop che vanno installate. E non sempre conviene. Aumenta i
costi di manutenzione, e non di poco.
GRUPPO EDITORIALE INFOMEDIA SRL Il web si è dimostrato da molto tempo migliore, con le sue pagine HTML che in
V I A V A L D E R A P. 1 1 6 pratica sono pezzi di una applicazione che non richiedono di essere installate, ma
5 6 0 3 8 PO N S A C C O ( P I ) I T A L I A vengono caricate on-demand.
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2 A voler proprio fare analogie, le applicazioni Web sono la riedizione dei vecchi ter-
E-MAIL INFO@INFOMEDIA.IT minali a carattere, in cui comandava il server e il terminale non faceva altro che
S I T O W E B W W W. I N F O M E D I A . I T “obbedire” visualizzando le informazioni. Una comodità preziosa che si è persa con
l’avvento delle GUI. Naturalmente la relativa staticità del modello Web, che prose-
gue inesorabilmente, pagina dopo pagina, ha sempre sofferto della scarsa interatti-
DIREZIONE vità rispetto alle applicazioni GUI.
N A T A L E FI N O (NFINO@INFOMEDIA.IT) A chiudere il cerchio sembra averci pensato la riscoperta del JavaScript potenziato
con la necessità di non dover ricaricare le pagine, e arricchito di un formato dati, che
CONTATTI in teoria sarebbe l’XML (e che in pratica è più spesso il JSON).
Ma l’acronimo AJAX è orami rimasto incollato nelle nostre menti per descrivere la
TE C H N I C A L B O O K tecnica di Asincronous Javascript And XML. L’idea è semplice, l’implementazione è
(BOOK@INFOMEDIA.IT) complessa. Questa tecnica è in pratica il ritorno alle origini. Quasi subito nell’html
è stato aggiunto il javascript, dotato poi della capacità di cambiare la pagina senza
MARKETING & ADVERTISING ricaricarla (il vecchio DHTML). Ma tra Java applet prima, Flash dopo, e nel mezzo
SEGRETERIA: 0587736460 tanta confusione, ci si era dimenticati del fatto che tutto questo si poteva fare sem-
MARKETING@INFOMEDIA.IT plicemente in JavaScript. Ci ha pensato Google a ricordarcelo, con il suo approccio
AMMINISTRAZIONE a riconsiderare in maniera nuova quello che già c’è. E Google Maps e Gmail ci
(AMMINISTRAZIONE@INFOMEDIA.IT) hanno mostrato che si possono realizzare applicazioni quasi desktop usando solo il
JavaScript.
SEGRETERIA La quantità di librerie che sono venute fuori in pochi anni è sconvolgente. Anche se
(INFO@INFOMEDIA.IT) ancora non è chiaro chi o cosa prevarrà o diventerà pervasivo. Il nostro speciale cerca
comunque di indagare su questi aspetti e si occupa in dettaglio degli strumenti ad
GRAFICA oggi più importanti per trattare questa tecnica.
STEFANO BELLANI Concludo con due comunicazioni di servizio. La prima è l’entrata di Fabio Staro
(GRAFICA@GRUPPOINFOMEDIA.IT) nell’editorial board, con la sua nuova rubrica Orizzonti Enterprise. E la seconda è la
decisione di offrire il Video Corso Java a tutti gli abbonati a JavaJournal, senza più
limitazioni di data di abbonamento. Basta abbonarvi e richiederlo, e vi sarà dato
UFFICIO ABBONAMENTI l’accesso.
TE L 0 5 8 7 7 3 6 4 6 0 F A X 0 5 8 7 7 3 2 2 3 2
ABBONAMENTI@INFOMEDIA.IT
W W W. I N F O M E D I A . I T
Michele Sciabarrà
JAVA E TUTTI I MARCHI DERIVATI Direttore Esecutivo
SONO MARCHI O MARCHI REGISTRATI Java Journal
DI SUN MICROSYSTEMS, INC. NEGLI
U S A E I N A L T R I PA E S I . I L G R U P P O
EDITORIALE INFOMEDIA È INDIPEN-
Speciale AJAX
AJAX e Java:un’accoppiata vincente
di Luigi Zanderighi 8
AJAX facile con prototype.js
di Domenico Ventura 14
Google Web Toolkit
di Jacopo Giudic 20
Educational
Introduzione agli EJB 3.0 - Prima parte
di Fabio Staro 31
Tutto Java in un Hello World
di Federico Paparoni 40
Focus
Introduzione a Struts
di Andrea Colleoni 47
Programmazione AOP con AspectJ
di Matteo Baccan 54
Rubriche
Orizzonti Enterprise
Tutto ciò che è tendenza nel mondo JEE
di Fabio Staro 28
Idiomatica
Tutto ciò che è tendenza nel mondo JEE
di Ugo Landini 61
Una guida pratica pensata per gli Il libro, ricco di illustrazioni a co-
sviluppatori Java. lori e di esempi, offre linee guida
Il libro mira a rendere le applica- spiegate nel dettaglio per 9 comuni
zioni web in Java più responsive e tecniche di prototipazione.
O’Reilly dinamiche; include strategie per Morgan Kaufmann I template e le risorse citate nel
228 pp - 32,00 Euro integrare Ajax in applicazioni JSP e 624 pp - 57,40 Euro testo sono disponibili sul Web per
ISBN 9780596101879 JSF e per usare Ajax con Struts. ISBN 9780120885688 il riutilizzo.
Potraiacquistare
Potrai
Potrai acquistarei ilibri
acquistare i libri
libriqui
quiriportati
qui riportati
riportati
Una guida completa per migliorare conuno
con
con uno SCONTOECCEZIONALE
unoSCONTO
SCONTO ECCEZIONALE
ECCEZIONALE
le prestazioni del sistema operativo
e per la manutenzione del computer del
del 10%anche
10%
del10% anchesese
anche seacquisti
acquistisolo
acquisti soloun
solo unlibro
un libro
libro
O’ Reilly
942 pp - 47,20 Euro indipendentemente dalla versione OPPURE
OPPURE
OPPURE
di Windows Vista posseduta.
ISBN 9780596528003
del 20%
20%sese
del20%
del acquisti33
seacquisti
acquisti 3libri
libri
libri
JAVA JOURNAL
CP 167 3
speciale AJAX JAVA Journal
AJAX e Java:
un’accoppiata
vincente
Capire come funziona AJAX non è un optional
JavaScript
D
Il primo passo per capire AJAX è studiarne le tecno-
opo mesi di scetticismo e perplessità logie abilitanti, ossia le tecnologie che messe insieme
su AJAX, avete finalmente deciso di rendono possibile sviluppare con la tecnica AJAX.
fare il grande passo e introdurre que- Partiamo con dal ruolo di Javascript lato client. Già
sta tecnologia all’interno di un nuovo alla fine degli anni ’90 si faceva uso di DHTML, ma
progetto. Senza preoccuparvi di come l’uso di Javascript non ha mai trovato ampio con-
funziona il meccanismo sottostante senso per mancanza di standard. Negli ultimi tempi
avete scaricato uno script che fa al caso vostro. Ma il divario tra le API e le funzionalità offerte dai vari
ora sudate freddo. Le cose non funzionano. Lo script browser si è notevolmente ridotta e ora si può conta-
che avete scaricato per qualche motivo si è rotto e re su un insieme molto esteso di funzioni sovrappo-
non sapete dove mettere le mani. Prima era sempli- nibili. Questa sovrapposizione non è ancora completa
ce, ora con AJAX in mezzo non si capisce dove può e tutti gli script devono tenerne conto.
essere il problema. Capite che è giunto il momento La grossa differenza, che ha sempre contraddistinto
di fare ciò che avete evitato fino ad ora: capire come MS Internet Explorer dagli altri browser, è il modo
funziona AJAX. con cui si recupera il riferimento di un elemento a cui
è stato assegnato un id all’interno del codice HTML,
AJAX, a differenza delle altre tecnologie con cui ossia:
siamo abituati a trattare, non gode di specifiche
tecniche: in effetti AJAX non è né un linguaggio né document.getElementById(id)
un framework, ma definisce una tecnica di sviluppo
costituita da un insieme di tecnologie. oppure
AJAX significa letteralmente Asynchronous Java-
script and XML, e nasce dall’unione di HTML, Java- document.all[id]
script, dell’oggetto XMLHttpRequest (XHR) e di una
o più tecnologie lato server. Per mascherare questa diversità, di solito si fa uso
Un grosso limite dell’HTML è sempre stato la man- di uno script “wrapper” che contempla ambedue le
canza di comunicazione tra client e server. Microsoft precedenti notazioni.
per prima ha aggirato questo problema già nei brow- Il frammento che segue è un esempio di codice Java-
ser IE4, con il controllo ActiveX Microsoft.XMLHTTP. script in grado di recuperare gli elementi indipenden-
Nell’Aprile 2006 il consorzio W3 ha rilasciato le temente dal browser:
specifiche per l’oggetto XHR che definisce le API che
forniscono le funzionalità di trasferimento dati tra // Funzione per recuperare un elemento dall’id
client e server, aprendo così ufficialmente le porte
alla interoperabilità tra client e server. function getElement(id) {
var element;
XMLHttpRequest
interface XMLHttpRequest {
attribute EventListener onreadystatechange;
readonly attribute unsigned short readyState;
void open(in DOMString method, in DOMString url);
void open(in DOMString method, in DOMString url, in boolean async);
void open(in DOMString method, in DOMString url, in boolean async, in DOMString user);
void open(in DOMString method, in DOMString url, in boolean async, in DOMString user,
in DOMString password);
void setRequestHeader(in DOMString header, in DOMString value);
void send();
void send(in DOMString data);
void send(in Document data);
void abort();
DOMString getAllResponseHeaders();
DOMString getResponseHeader(in DOMString header);
readonly attribute DOMString responseText;
readonly attribute Document responseXML;
readonly attribute unsigned short status;
readonly attribute DOMString statusText;
};
}
function getXMLHttpRequest() {
Strumenti e framework
GWT
Nell’esempio che abbiamo visto poc’anzi, abbiamo scritto
sia il codice client sia il codice server, partendo da zero. Il primo framework che vediamo è il Google Web Toolkit.
Per farlo abbiamo dovuto sfoggiare le nostre competenze Utilizzando GWT ci occuperemmo solo di scrivere il con-
nei linguaggi HTML, Javascript e Java. L’esempio era però trollo lato server. Ogni elemento “attivabile” con AJAX
molto semplice: non ci siamo preoccupati di aggiungere dispone di una classe, che possiamo estendere per fornire
quei controlli che sarebbero indispensabili in un ambiente le funzionalità client dinamiche. Ad esempio disponiamo
if (request.getParameter(“value”)==null || request.getParameter(“value”).equals(“”)) {
text=”Valorizzare il campo”;
color=”grey”;
} else if (request.getParameter(“value”).length()==5) {
text=”La lunghezza della stringa è corretta”;
color=”green”;
} else {
text=”La lunghezza (“+request.getParameter(“value”).length()+
“) della stringa non è corretta”;
color=”red”;
}
}
out.print(“<message><color>”+color+”</color><text>”+text+”</text></message>”);
out.close();
dell’oggetto Button() con tutti i metodi definiti in DHTML le chiamate AJAX. In genere con JSF accade che, come per
come ad esempio onclick(). i componente swing, chi sviluppa utilizza ciò che trova già
Tra le caratteristiche interessanti di GWT troviamo un pronto, eventualmente con qualche estensione. Solo in
wizard da riga di comando che genera lo scheletro di una casi eccezionali ci si cimenta nella sviluppo di componenti
prima applicazione e i file di progetto per Eclipse. Altra ca- completamente nuovi con tutte le problematiche annesse.
ratteristica importante è la possibilità di eseguire il codice JSF è quindi un ottimo candidato per applicazioni che fan-
in “hosted mode”, ossia senza l’intervento di un browser no uso di AJAX; ma l’uso di JSF non è indice dell’utilizzo
esterno, ma utilizzando un browser speciale che viene for- di AJAX. Occorre trovare i componenti giusti per disporre
nito insieme con il framework. di controlli avanzati AJAX.
Riporto un blocco di codice tratto dal sito del webtoolkit Alcuni esempi di componenti JSF/AJAX si possono trovare
per mostrare la semplicità del codice: nella sandbox di myfaces. Tra le cose interessanti troviamo
dropdown che si popolano sulla base di valori di altri ele-
public class Hello implements EntryPoint { menti di un form, suggerimenti dinamici in fase di digita-
public void onModuleLoad() { zione e verifica della validità dei valori su onblur.
Button b = new Button(“Click me”, new ClickListener() {
public void onClick(Widget sender) {
Window.alert(“Hello, AJAX”);
}
});
RootPanel.get().add(b);
}
}
Al campo di input
JSF
viene assegnato un
JSF (Jave Server Faces) basa la propria architettura sul-
l’uso di componenti. Ogni componente esegue il rendering id per consentirne
di bean specifici (chiamati backing-bean). A ogni compo-
nente possono essere assegnati degli actionListener su
eventi che si verificano sul client su cui viene renderizzato
l’identificazione
il bean. L’approccio è molto simile a quello adottato dalle
interfacce swing per la gestione degli eventi.
Questo tipo di architettura si è mostrata terreno molto
fertile per lo sviluppo di funzionalità AJAX.
In JSF poter disporre di funzionalità AJAX significa avere
dei componenti che per costruzione sono in grado eseguire
ECHO2 Conclusioni
È probabilmente quanto di più completo si possa tro- Sviluppare con la tecnica AJAX consente di realizzare vere
vare oggigiorno in Java su AJAX. ECHO2 è un web e proprie applicazioni client. Il browser non mostra più
framework che dispone di una libreria molto completa semplici pagine ma potenzialmente una singola pagina
di componenti per realizzare applicazioni con frontend che continua ad aggiornarsi dinamicamente in funzione
molto ricchi e complessi. ECHO2 dispone anche di un delle interazioni con l’utente. Per capire a fondo le poten-
ambiente di sviluppo visuale avanzato, in grado di zialità basta vedere Gmail di Google, con il suo sistema di
aiutare notevolmente in fase di sviluppo. Le librerie di chat o il nuovo frontend per la posta di Yahoo!.
ECHO2 sono disponibili con licenze lgpl o mpl, mentre AJAX comporta una serie di conseguenze, che impongono
l’ambiente di sviluppo è proprietario. Per utilizzare un attento studio prima di essere utilizzato indistintamente.
ECHO2 non è indispensabile utilizzare l’ambiente vi- Le prime considerazioni sono sull’accessibilità. Una applica-
suale anche se si perdono molti dei benefici della piat- zione AJAX sarà difficilmente accessibile da altri sistemi, in
taforma, come i wizard e i suggerimenti. particolare dai motori di indicizzazione. Siti per i quali è fon-
Gli esempi presenti sul sito del produttore (http: damentale l’indicizzazione o per i quali è previsto l’accesso
//demo.nextapp.com) descrivono le potenzialità del fra- da altre piattaforme non dovrebbero fare uso di Javascript
mework meglio di qualunque descrizione testuale. e quindi di AJAX. Un’altra considerazione è sulla sicurezza:
esporre servizi web è come mostrare il fianco al nemico. Oc-
corre utilizzare tutti gli accorgimenti per evitare che altri ne
Firebug abusino (ad esempio con un blocco su referrer) e per i dati
sensibili occorre sempre proteggere l’accesso e fornire i dati
Uno dei problemi di chi sviluppa con AJAX è monitorare solo in HTTPS. Sono accorgimenti comuni ma spesso trascu-
il dialogo client/server per individuare facilmente dove rati, per la percezione errata che nessuno conosce il servizio
possono annidarsi eventuali problemi. L’ultimo stru- e quindi nessuno lo chiamerà direttamente.
mento che consiglio è Firebug. Si tratta di un plugin
per Firefox in grado di intercettare, tra le altre cose, Note Biografiche
l’uso del oggetto XHR, mostrando sia la chiamata che Luigi Zanderighi è Ingegnere del software ed è esperto nella pro-
la risposta. gettazione di architetture distribuite e di software Java.
Titoli preferenziali:
Passione per il mondo Internet, le nuove tecnologie, l’integrazione tra sistemi, lo studio e la realizzazione di community dedicate al
mondo consumer dell’entertainment (web e mobile).
Completano il profilo autonomia e spirito d’iniziativa, orientamento ai risultati e motivazione ad inserirsi in un contesto giovane e
molto dinamico.
L
A questo punto la nostra pagina è pronta per utilizza-
a maggior parte dei framework e delle re in pieno tutte le potenzialità di Prototype!
librerie opensource che si trovano in
rete hanno l’ambizione di semplificare la
vita al programmatore. Prototype è fra le
poche che raggiunge pienamente questo
scopo. Nata con l’obiettivo di rendere la
programmazione Javascript meno confusionaria, più
strutturata, in poche parole più divertente, Prototype
è nota per essere la libreria Javascript distribuita e
usata in Ruby on Rails per gestire le chiamate AJAX
Prototype è fra le poche
lato client. Ciò nonostante Prototype può tranquilla-
mente essere usata in qualunque progetto web.
librerie che realmente
Tra i numerosi punti di forza di Prototype, e sono tan-
ti, non può però essere annoverata la documentazio- semplificano il compito
ne, che (almeno sino al lancio del nuovo sito, a fine
febbraio) è sempre stata carente, se non completa- del programmatore
mente mancante, costringendo quasi sempre il pro-
grammatore ad andare per tentativi o a leggere diret-
tamente il sorgente all’interno della libreria. Questo
articolo fornisce una panoramica su Prototype, sulle
funzionalità e sugli oggetti base, in particolare quelli
legati al supporto per AJAX, alla gestione dei form e
del DOM.
Tutti quei $ $ $ qua e là
Per iniziare Una delle prime cose che saltano agli occhi esami-
nando del codice che utilizza Prototype (o analiz-
L’ultima versione di Prototype, che attualmente è zando direttamente il sorgente di Prototype) sono
la 1.5.0, può essere scaricata dal sito ufficiale http: le tante chiamate $(...), $F(...), $$(...), che danno
//www.prototypejs.org/. La libreria si compone di un un po’ l’impressione di un listato Perl. In realtà que-
solo file, prototype.js appunto, che deve essere inclu- ste sono funzioni di utilità generale, tra quelle che
so all’interno delle pagine web con il tag <script>: maggiormente adempiono al dovere di semplificarci
la vita, evitandoci di scrivere del codice ripetitivo. Ve-
<script type=”text/javascript” diamone alcune nel dettaglio.
<input type=”text” id=”nome” /> Sin qui abbiamo visto una serie di funzioni
di uso generico, sicuramente molto utili
<input type=”button” value=”mostra” onclick=”mostraNome()” />
e ben fatte, ma uno degli scopi principali
per utilizzare Prototype è poter avere delle
LISTATO 1 Esempio di utilizzo della funzione $F( ) funzionalità AJAX! Vediamo allora come
utilizzare la libreria al meglio per creare
funzione sia la stringa con l’ID dell’elemento, sia l’ele- delle pagine AJAX.
mento stesso. Nel proseguo della funzione si utilizza poi Per centralizzare tutte le funzionalità AJAX, Prototype crea
l’elemento esteso da Prototype con le sue funzionalità e rende pubblico un oggetto denominato, appunto, Ajax:
aggiuntive. questo si fa carico di gestire dietro le quinte tutte le dif-
ferenze di implementazione e di utilizzo sui vari browser
dell’oggetto XMLHttpRequest, assicurando così la fruibili-
tà delle nostre applicazioni con qualunque browser.
La Funzione $F( ) Nella pratica, per la realizzazione di funzionalità AJAX,
bisogna utilizzare delle sottoclassi dell’oggetto Ajax. Vedia-
Anche la funzione $F( ) è una scorciatoia molto comoda: per- mole in dettaglio.
mette di ottenere il valore di un qualsiasi elemento di input,
passando come parametro il suo ID. Il Listato 1 riporta un
esempio che mostra un alert con il valore inserito nel campo Ajax.Request
nome quando si effettua un click sul pulsante mostra.
Il modo più semplice e immediato di creare una chiamata
AJAX è istanziare un oggetto Ajax.Request. Ad esempio:
new Ajax.Request
Document.getElementByClassName()
(“/unaURL”, { method:”get” });
Questa funzione consente di ottenere un array di tutti gli
elementi della pagina che hanno la classe CSS passata Il primo parametro del costruttore indica a quale URL
come parametro. Si può anche passare un riferimento ad indirizzare la richiesta. Il secondo parametro è un ogget-
un elemento della pagina come parametro opzionale: in to Javascript, creato in questo caso secondo la notazione
questo caso la ricerca avviene solo sui figli di tale elemen- JSON, che indica le opzioni da utilizzare per la richiesta
to. AJAX: nell’esempio indica che la richiesta HTTP deve es-
Ad esempio, se vogliamo ottenere la lista di tutti gli ele- sere fatta in GET.
menti di classe test, scriveremo: Questo secondo parametro merita qualche spiegazione in
document.getElementByClassName(“test”);
// Tutti i form della pagina:
Un altro esempio; per ottenere la lista di tutti gli elementi $$(“form”);
di classe test contenuti all’interno di un elemento (un div,
un form) di ID “login”, scriveremo: // Tutti i link della pagina
// con attributo href=”#” (wow!)
document.getElementByClassName(“test”, $(“login”)); $$(“A[href=’#’]”);
new Ajax.Request
più: è comune a tutte le classi dell’oggetto AJAX e consente
(
di specificare le opzioni da usare in una singola richiesta
AJAX. La Tabella 1 elenca le opzioni di più comune utiliz- “/trovaUtente.do”,
zo: tutte hanno un default, di modo che possiamo specifi- {
care solo quelle che realmente si intende modificare. method:”get”,
L’esempio appena mostrato non serve realmente a molto: parameters: “userId=888”,
dopo aver invocato la URL “/unaURL” non specifica cosa onSuccess: function(resp)
fare della risposta che si ottiene. Poiché le richieste AJAX {
sono per definizione asincrone, la gestione dell’output alert(“Salve utente “ +resp.responseText);
(così come delle condizioni di errore) deve essere compiu- },
ta tramite delle callback. Anche le callback da usare vanno onFailure: function
definite nel parametro che indica le opzioni. {
Il Listato 3 mostra un altro esempio di utilizzo di
alert(“C’è stato” + “un errore...”);
Ajax.Request, completo di callback per la gestione dell’er-
}
rore e della risposta AJAX. In questo secondo esempio ven-
}
gono definite due callback: una da chiamare nel caso che
la richiesta Ajax sia andata a buon fine e una da chiamare );
in caso di errore. Nella prima callback, il parametro resp che
viene passato è l’oggetto XMLHttpRequest originario, di LISTATO 3 Esempio di una chiamata AJAX completa di
cui si possono usare le proprietà responseText o responseXML. callback
La Tabella 2 riporta l’elenco delle callback più comuni.
Callback Descrizione
onComplete Chiamata alla fine del ciclo di vita di una richiesta AJAX.
Element.update(“unDiv”, nuovoHtml);
Creare delle pagine L’altro modalità per utilizzare le estensioni del DOM di
Prototype consiste nell’utilizzare direttamente gli oggetti
estesi, ovviamente tramite la funzione $( ):
AJAX cross-broweser in
$(“unDiv”).update(nuovoHtml);
Google Web
Toolkit
Creare un progetto AJAX partendo da zero comporta una ottima conoscenza di javascript ol-
tre che di XML, HTML, CSS e delle compatibilità dei vari browser. Tuttavia, il progetto GWT
(Google Web Toolkit) permette agli sviluppatori Java di creare siti in AJAX senza dover scrive-
re neanche una linea di codice javascript.
I
L’installazione dei GWT e la creazione del pri-
l Google Web Toolkit [1] è un framework svi- mo progetto
luppato dal Google Team che permette di com-
pilare del codice Java trasformandolo in pagine
che utilizzino la tecnologia AJAX. I Google Web Toolkit (da ora GWT) sono delle libre-
Con la nascita dell’acronimo AJAX, le grandi rie Java con a corredo una serie di programmi che
compagnie di software hanno realizzato meto- permettono la creazione rapida di classi Java trasfor-
di più o meno efficaci per semplificare il lavoro degli mabili tramite compilazione in pagine HTML-AJAX.
sviluppatori creando dei framework per la creazione I progetti creati con i GWT sono pronti per essere
di pagine contenenti la nuova tecnologia a partire dai modificati, compilati o valutati tramite strumenti
linguaggi di programmazione proprietari. Microsoft tipici della programmazione Java, quali, ad esempio,
ha sviluppato Atlas per ASP.NET [2], Yahoo ha reso Eclipse, Ant e JUnit. Il nucleo dei GWT è composto da
disponibile le User Interface Library [3] e anche la una serie di librerie Java e quindi indipendenti dalla
comunità Open Source si è prodigata nella creazione piattaforma; tuttavia, alcuni programmi contenuti
di svariati progetti, tra i quali il più famoso è proba- nel pacchetto sono dei file di script dipendenti dal
bilmente Sarissa [4]. sistema operativo. Proprio per questo, i GWT posso-
L’approccio di Google è, tuttavia, originale e permette no essere scaricati in due versioni: per Windows e
ai puristi Java di creare degli interi siti AJAX inte- per Linux/MacOS. Dopo aver scaricato il file adatto
grandoli con le tecnologie che già utilizzano quali, ad al vostro sistema operativo e averlo decompresso,
esempio, Servlet, JSP e EJB, senza dover necessaria- l’installazione è terminata. L’unico ulteriore passo,
mente conoscere javascript. non necessario ma consigliato, è l’inserimento nel
PATH della cartella creata dalla decompressione del
file, contenente i vari script per creare o modificare
progetti e classi GWT.
All’interno della cartella decompressa contenente i
L’approccio di GWT, esistono due file di script: projectCreator e ap-
plicationCreator: file .cmd sotto Windows e .sh sotto
Google è originale e Linux/MacOS. Per creare un nuovo progetto, creiamo
una cartella chiamata JavaJournal che conterrà il pro-
permette di creare siti getto e quindi navighiamo fino a quella cartella con
AJAX senza conoscere la shell dei comandi. Da qui, lanciamo il comando:
package it.jj.client;
import com.google.gwt.core.client.*;
import com.google.gwt.user.client.ui.*;
public class Reviews implements EntryPoint {
private VerticalPanel treeRev = new VerticalPanel();
private DockPanel page = new DockPanel();
public void onModuleLoad() {
addTree();
treeRev.setWidth(“100%”);
page.add(treeRev, DockPanel.WEST);
RootPanel.get().add(page);
}
public void addTree() {
Tree tree = new Tree();
TreeItem root1 = new TreeItem(imageItemHTML(“riviste_jj.jpg”, “#1”));
tree.addItem(root1);
root1.addItem(nuovoArticolo(“Java Server Faces”, “Michele Sciabarrà”,
“michele.sciabarra@javajournal.it”));
root1.addItem(nuovoArticolo(“Le novità di JSF 1.2”, “Andrea Nasato”,
“andrea.nasato@javajournal.it”));
root1.addItem(nuovoArticolo(“Java Card”, “Matteo Campanella”,
“matteo.campanella@javajournal.it”));
root1.setState(true);
TreeItem root2 = new TreeItem(imageItemHTML(“riviste_jj.jpg”, “#2”));
tree.addItem(root2);
root2.addItem(nuovoArticolo(“J2ME Best Practice”, “Andrea Nasato”,
“andrea.nasato@javajournal.it”));
root2.addItem(nuovoArticolo(“Apache Ant”, “Michele Ferretti”,
“michele.ferretti@javajournal.it”));
root2.setState(true);
treeRev.add(tree);
}
/*
* Le variabili recuperate dal metodo vengono definite static perchè dovranno
* essere utilizzate all’interno dell’istanza di ClickListener
*/
private HTML nuovoArticolo(final String nomeArticolo, final String autore, final String mail) {
/*
* Inserisco nell’html, come href un riferimento a javascript senza nome del metodo
* da eseguire: sarà poi il metodo addClickListener a inserire il giusto codice
*/
final HTML link = new HTML(“<a href=’javascript:;’>” + nomeArticolo + “</a>”);
link.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
MyPopupPanel popup = new MyPopupPanel(nomeArticolo, autore, mail);
int left = link.getAbsoluteLeft() + 32;
int top = link.getAbsoluteTop() + 8;
popup.setPopupPosition(left, top);
popup.show();
}
});
return link;
}
private static class MyPopupPanel extends PopupPanel {
public MyPopupPanel(String nomeArticolo, String autore, String mail) {
/*
* L’utilizzo del costruttore PopupPanel(true) permette di settare la variabile
* auto-hide a true, nascondendo il pannello popup al primo click esterno allo stesso
*/
super(true);
HTML html = new HTML(“<a href=\”#\”>” + nomeArticolo + “</a>” +
“<br /><img src=\”inbox.gif\” /> “ +
“<a href=\”mailto:” + mail + “\”>” + autore + “</a>”, true);
setWidget(html);
setStyleName(“myPopup”);
}
}
private String imageItemHTML(String imageUrl, String title) {
return “<span><img style=’margin-right:4px’ src=’” + imageUrl.toLowerCase()
+ “’>” + title + “</span>”;
}
}
seguenti classi CSS: base, abbiamo deciso di non inserire uno scheletro nel corpo
della pagina HTML ma di eseguire solamente il codice conte-
.gwt-MenuBar {} nuto nel modulo javascript gwt.js con il seguente comando:
.gwt-MenuBar .gwt-MenuItem {}
.gwt-MenuBar .gwt-MenuItem-selected {} <script language=”javascript” src=”gwt.js”></script>
setStyleName(“myPopup”);
I progetti creati con i
per legare la classe dei vari popup, MyPopupPanel, della GWT sono pronti per
quale discuteremo più avanti, allo stile definito nel codice
HTML: .myPopup. In questa classe CSS viene inoltre defini-
to uno stile che necessita di una immagine per poter creare
Eclipse, Ant e JUnit
lo sfondo del popup:
background-image: url(gray_gradient.gif);
page.add(treeRev, DockPanel.WEST);
RootPanel.get().add(page);
utilizzato Swing e il BoxLayout, basti sapere che il comando o Jsp utilizzando le RPC (Remote Procedure Calls) con parti-
page.add(treeRev, DockPanel.WEST); aggiunge a page il colari classi GWT.
pannello treeRev posizionandolo ad Ovest, cioè attaccato I GWT, come visto, permettono la creazione di pagine AJAX
al bordo sinistro del contenitore. senza dover conoscere javascript e le sue implicazioni ma
Il metodo onModuleLoad() esegue anche il comando ad- solamente inserendo particolari classi nel codice Java e,
dTree() che crea un menu ad albero utilizzando la classe soprattutto, utilizzando metodi simili a quelli che vengono
Tree. I comandi utilizzati per creare l’albero sono tre: utilizzati con altri strumenti.
Seguendo la politica di Google del “no-evil”, come riporta-
1. il comando Tree tree = new Tree(); che istanzia l’albe- to sul sito, i GWT vengono rilasciati sotto licenza Apache 2.0
ro. Open Source License permettendo la navigazione del codice
2. il comando TreeItem <variabile> = new TreeItem(); più complesso e, come auspicabile, un veloce migliora-
che crea un nodo dell’albero contenente del codice mento delle funzionalità più interessanti. In particolare,
HTML. il Google Team vuole rendere stabili, entro il 2008, i mec-
3. il comando <variabile>.addItem(<nodo>); che lega canismi di RPC che permettono la comunicazione client-
un nodo all’albero o al ramo superiore. server. Questo processo potrebbe fornire agli sviluppatori
la possibilità di creare con pochi comandi dei web-service
Quindi, con il comando setState(true); determino che utilizzando solo codice Java e client personalizzati e visua-
il nodo dell’albero sia espanso, mentre con il comando lizzabili tramite browser.
treeRev.add(tree); inserisco l’albero nel pannello treeRev, Il progetto è solo agli inizi ma, visto che Google è l’azienda
facendolo quindi visualizzare sul lato sinistro della pagi- capofila, ci si può aspettare un salto in avanti da un mo-
na. mento all’altro, cosa auspicabile sia per il programmatore
I nodi dell’albero devono essere scritti in HTML e, per esperto che per il neofita che non deve così imparare altri
inserire i vari nodi, l’applicazione utilizza due metodi linguaggi oltre a Java.
appositi per la creazione delle stringhe formattate: imageI-
temHTML() e nuovoArticolo(). Il primo di questi due metodi
crea un area di tipo <span> contenente un immagine e
un testo; il secondo crea il codice HTML della finestra Po-
pup. La finestra verrà visualizzata istanziando un pannello
particolare di tipo MyPopupPanel che, a sua volta, estende
la classe PopupPanel. La classe MyPopupPanel contiene un
oggetto di tipo HTML, ossia una Label contenente codice
HTML con i riferimenti all’articolo e all’autore, passati al I GWT vengono
metodo tramite il suo costruttore. L’oggetto HTML così
creato viene settato come widget principale della classe rilasciati sotto licenza
MyPopupPanel, diventando il corpo dell’oggetto.
Il metodo nuovoArticolo() crea quindi un altro oggetto di
tipo HTML, collegandoci un istanza della classe clickLi- Apache 2.0 Open
stener, esattamente come in precedenza veniva fatto per
il pulsante nell’applicazione di base. Il metodo onClick() Source License
istanzia una variabile di tipo MyPopupPanel e ne definisce
la posizione. Il pannello di popup viene quindi mostrato
tramite l’esecuzione del metodo show() della variabile
creata.
Conclusioni
Riferimenti
Dopo aver completato la scrittura del modulo, la compila-
zione avviene utilizzando ant oppure lanciando il comando 1 http://code.google.com/webtoolkit/
Reviews-compile.cmd. Al termine della compilazione, trove- 2 http://ajax.asp.net/
remo una cartella www con all’interno una serie di file. 3 http://developer.yahoo.com/yui
Questi file sono il risultato della compilazione del modulo 4 http://sarissa.sourceforge.net/
e della sua trasformazione in AJAX, suddivisi per browser.
Al caricamento della pagina AJAX, una serie di comandi
Note Biografiche
javascript valuteranno quale browser tenti di accedere al
codice e caricheranno al giusta versione dei moduli GWT. Jacopo Giudici si occupa di applicazioni per il Web, di RFID e di
domotica su piattaforme J2ME, J2EE e .NET. Progetta e tiene
Inoltre, la compilazione crea una cartella chiamata tomcat corsi di formazione aziendali sulla sicurezza delle reti informa-
che conterrà, al momento, una serie di file di configura- tiche e sulla programmazione Java per ambienti distribuiti.Ha
zione del server Apache Tomcat. Questa cartella serve a lavorato per Microsoft, BottegaVerde, CONAD, Confartigiana-
to e ha pubblicato una collana di 6 libri con DeAgostini Scuola
configurare Tomcat per applicazioni GWT più complesse sui Sistemi Elettronici-Informatici per il triennio degli istituti
che necessitino di comunicazione con oggetti quali Servlet tecnici superiori.
FIGURA 1 Pila dei protocolli dei web service (adattata da: http://it.wikipedia.org/wiki/Web_service)
dei componenti web service. Ma quale rapporto intercorre ha notevolmente migliorato il supporto per i web service
tra SOA e i web service? I web service sono una specifica e al contempo lo ha semplificato attraverso l’uso delle
tecnologica attraverso la quale pubblicare e invocare sul web annotazioni (cfr: JSR 181, Web Services Metadata for the Java
dei servizi; SOA è un paradigma architetturale (architectural Platform). In particolare esporre un EJB di tipo stateless
pattern) per il software design. In sintesi i web service sono una come web service è estremamente semplice. Attraverso
implementazione, la principale, è vero, ma non l’unica (se si l’annotazione
pensa per esempio al mondo CORBA), del paradigma SOA. La
Figura 1 mappa i ruoli di una architettura SOA sui protocolli javax.jws.WebMethod
di rete utilizzati per definire, localizzare ed invocare i servizi
web. Con riferimento alla figura, possiamo definire i tre pro- è possibile identificare i metodi che saranno esposti come ope-
tocolli di riferimento: razioni del web service mentre attraverso l’annotazione
Introduzione agli
EJB 3.0
Prima Parte
Con la nuova specifica 3.0 la SUN ha eseguito una reingegnerizzazione della tecnologia EJB ar-
ricchendo l’API di nuove caratteristiche e semplificando, in modo radicale, lo sviluppo dei bean
enterprise.
FIGURA 1 una applicazione client invoca un bean enterprise X che esegue varie operazioni
radicale reingegnerizzazione della tecnologia arricchendo conoscenza di base della specifica 2.x e delle problematiche
notevolmente l’API ma soprattutto semplificando note- inerenti alla tecnologia EJB in generale. L’esempio riporta-
volemte lo sviluppo dei componenti. A testimonianza di to è stato verificato con l’application server JBoss versione
ciò riportiamo quanto segue, direttamente dal documento 5.0 [6] e con il database MySQL versione 5.0.27 [7].
della specifica:
package it.articolo.ejb;
import it.articolo.ejb.interceptors.LogInterceptor;
import it.articolo.ejb.interceptors.PerformanceInterceptor;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
import javax.sql.DataSource;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagementType;
import javax.ejb.TransactionAttributeType;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
@Stateless (name=”Biblioteca”)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class GestoreBibliotecaBean implements GestoreBiblioteca {
private static Log oLogger = LogFactory.getLog(GestoreBibliotecaBean.class);
@Resource (name=”jdbc/exampleDatasource”)
DataSource theDatasource = null;
@Interceptors({PerformanceInterceptor.class, LogInterceptor.class})
public List<Libro> getLibri(String nomeAutore)
{
oLogger.info(“Invocato metodo EJB (CON INJECTION)”);
List<Libro> oListaLibri = new DAOGestoreBiblioteca().getLibri(nomeAutore,
theDatasource);
return oListaLibri;
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void assegna(Persona persona, Libro libro) throws LibroNonDisponibile {
assegnaLibro(persona, libro);
boolean result = diminuisciNumeroCopie(libro);
if (!result)
throw new LibroNonDisponibile(“Il libro: “+libro.getTitolo()
+” non è disponibile per il prestito”);
}
private boolean diminuisciNumeroCopie(Libro libro) throws LibroNonDisponibile {
boolean operationResult = new DAOGestoreBiblioteca().diminuisciNumeroCopie(libro,
theDatasource);
return operationResult;
}
private void assegnaLibro(Persona persona, Libro libro) {
new DAOGestoreBiblioteca().assegnaLibro(persona, libro, theDatasource);
}
}
public class GestoreBibliotecaBean implements e che non hanno un legame diretto con un container o con
GestoreBiblioteca un application server. Con gli EJB 3.0 non sono più obbli-
{ gatori i file XML di configurazione, i talvolta complessi e
… sicuramente prolissi deployment descriptor, essendo possibile
} definire tutte le caratteristiche di un EJB attraverso le an-
notazioni. La Tabella 2 riporta alcune differenze e sempli-
Le poche righe di codice sopra riportate sono di fatto il no- ficazioni che si hanno per gli EJB di tipo session passando
stro EJB 3.0 di nome Biblioteca e mostrano un carattere di- dalla versione 2.x alla versione 3.x.
stintivo ed innovativo degli EJB 3.0 rispetto alle precedenti
versioni 2.x e 1.x: gli EJB 3.0 sono POJO, acronimo di Plain Il carattere remoto o locale di un EJB si definisce attraver-
Old Java Object, ossia semplici classi Java che non devono so le due annotazioni
implementare interfacce particolari e/o metodi di callback
…
@TransactionManagement(TransactionManagementType.CONTAINER)
public class GestoreBibliotecaBean implements GestoreBiblioteca
{
…
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void assegna(Persona persona, Libro libro) throws LibroNonDisponibile {
assegnaLibro(persona, libro);
boolean result = diminuisciNumeroCopie(libro);
if (!result)
throw new LibroNonDisponibile(“Il libro: “+libro.getTitolo()
+” non è disponibile per il prestito”);
}
private boolean diminuisciNumeroCopie(Libro libro) throws LibroNonDisponibile {
boolean operationResult =
new DAOGestoreBiblioteca().diminuisciNumeroCopie(libro, theDatasource);
return operationResult;
}
private void assegnaLibro(Persona persona, Libro libro) {
new DAOGestoreBiblioteca().assegnaLibro(persona, libro, theDatasource);
}
…
}
lativo al deployment descriptor, il file ejb-jar.xml, mentre il come le operazioni di lookup sono di fatto eliminate nella
secondo alla classe del bean). nuova specifica EJB 3.0:
… …
<resource-ref> public class GestoreBibliotecaBean implements
<description></description> GestoreBiblioteca
<res-ref-name>jdbc/exampleDatasource </res-ref-name> {
<res-type>javax.sql.DataSource</res-type> @Resource (name=”jdbc/exampleDatasource”)
<res-auth>Container</res-auth> DataSource theDatasource = null;
<res-sharing-scope>Shareable</res-sharing-scope> }
</resource-ref> …
…
Attraverso l’annotazione @javax.annotation.Resource è va-
… lorizzato da parte del container l’oggetto theDatasource di
// Codice per ottenere il contesto JNDI tipo javax.sql.DataSource prima che sia invocato un qualsiasi
Context initCtx = new InitialContext(); metodo di business dell’EJB da parte di un client.
// Operazione di lookup In modo analogo, attraverso l’annotazione @javax.ejb.EJB
javax.sql.DataSource ds = (javax.sql.DataSource) è possibile referenziare un secondo componente EJB. Di
initCtx.lookup(“java:comp/env/jdbc/exampleDatasource”); seguito un esempio di codice:
…
…
In generale i passi necessari per eseguire le operazioni di public class GestoreBibliotecaBean implements
lookup sull’albero JNDI per una risorsa esterna sono ripeti- GestoreBiblioteca
tivi e soprattutto sono dettati dal contesto tecnologico e {
non dalla logica di business. Inoltre, la dipendenza di un @EJB SecondEJB secondEJB;
componente EJB dall’API JNDI rende complesso il test …
unitario del componente al di fuori di un container EJB. }
Il problema è che nelle righe di codice sopra riportate la …
classe del bean enterprise ha un legame diretto con la tec-
nica attraverso la quale si recupera un riferimento ad una La sintassi equivale ad eseguire una operazione di lookup
risorsa esterna (nell’esempio un datasource, ma di fatto può dell’EJB individuato dalla reference java:comp/env/ejb/
anche essere una queue o un topic JMS, un altro EJB, ecc.). secondEJB. Per apprezzare la semplificazione introdotta
La dependency injection rovescia tale paradigma essendo il riportiamo di seguito il codice presente in un EJB 2.x per
container EJB a passare alla classe del bean enterprise una risolvere la medesima reference al secondo EJB:
reference alla risorsa esterna. Detto in altri termini, il con-
tainer EJB inietta nel bean enterprise una reference per la …
risorsa esterna prima che sia eseguito un qualsiasi metodo Context ctx = new InitialContext();
di business del bean. Lo stralcio di codice che segue mostra SecondEJBHome secondEJBHome = (SecondEJBHome)javax.rmi.Porta
bleRemoteObject.narrow(
ctx.lookup(“java:comp/env/ejb/secondEJB”), La specifica EJB 3.0 definisce due annotazioni per la ge-
SecondEJBHome.class); stione delle transazioni:
SecondEJB secondEJB = secondEJBHome.create();
… • @TransactionManagement
• @TransactionAttribute
package it.articolo.client;
...
public class Client {
}
bute sono definiti nella enumerazione TransactionAttribu- }
teType, sempre presente nel package javax.ejb, e sono: …
Tutto Java in un
Hello World
In questo articolo vediamo come sia possibile scrivere un Hello World senza fermarci al semplice
System.out.println(). Vedremo infatti collegate diverse tecnologie Java, che si legano una con l’altra
per veicolare un messaggio di prova.
Q
mentazione dell’oggetto RMI provvede quindi ad
uante volte avete incominciato a studia- inviare ad una coda JMS (Java Message Service)
re un linguaggio di programmazione? La il messaggio testuale. In questo caso utilizzeremo
cosa più bella in questi momenti è quan- una coda JMS messa a disposizione dall’application
do ancora non sapete niente di quello che server BEA WebLogic. Dall’altro capo della coda ab-
vi trovate davanti, non avete capito bene come è or- biamo in listening un oggetto che provvede, appena
ganizzato, vi affannate per cercare di capire se c’è un arriva un messaggio, ad inserirlo tramite JDBC (Java
IDE grafico che può aiutarvi e passate un bel po’ di Database Connectivity) nel nostro database. Infine
tempo su Google per cercare qualche articolo che vi abbiamo un’applicazione classica desktop che richie-
possa illuminare. Nonostante ciò, quando si inizia a de di continuo una pagina JSP (Java Server Pages),
studiare un nuovo linguaggio, il classico HelloWorld, la quale utilizzando JSTL (JavaServer Pages Standard
un semplice programma che scrive semplicemente a Tag Library) provvederà a restituirci il messaggio ap-
schermo una stringa di testo, è la cosa che viene fatta pena questo sarà disponibile nel nostro database.
abbastanza semplicemente e vi invoglia a continua- Insomma un bel giro di classi, metodi e tecnologie.
re, anche perché pensate “Ora voglio proprio vedere Incominciamo ora a vedere la prima applicazione da
come fare….”. Purtroppo dedicandoci ad un linguag- realizzare, ovvero quella JavaME.
gio in particolare, in questo caso Java, non possiamo
provare spesso questa emozione. Oggi in questo arti-
colo proveremo a scrivere un HelloWorld che attra-
versi tutto Java (o comunque una buona parte), per
vedere come tutte le tecnologie Java possono essere
legate insieme.
Un’applicazione
Architettura dell’applicazione
JavaME che si collega
L’architettura della nostra applicazione è abbastanza
ingarbugliata e quindi richiede un attimo di attenzio- ad una Servlet
ne per essere capita. Diciamo che tutto ciò viene fatto
per legare diverse tecnologie Java insieme e quindi
bisogna capire bene dove ciascuna componente entra
in gioco. Nella Figura 1 viene riportato un diagram-
ma della nostra applicazione che ci permette di avere
un’idea chiara di quello che succede. Come punto di
partenza abbiamo un’applicazione JavaME che si JavaME
collega ad una Servlet. L’applicazione invierà tramite
una classica connessione HTTP il messaggio. Succes- L’applicazione che in questo caso dobbiamo realiz-
sivamente la Servlet invierà questo messaggio ad un zare è abbastanza semplice. Dovremo creare un’in-
oggetto RMI (Remote Method Invocation), che viene terfaccia che permette di avviare la richiesta HTTP,
utilizzando un Form classico, come viene riportato qui di vedere l’emulatore JavaME che mostra la MIDlet dopo
seguito l’esecuzione.
…
d = Display.getDisplay(this);
Servlet
form=new Form(“Java Hello World”);
form.append(“To launch the Java Hello World, press La Servlet ha due fasi distinte che devono essere analizza-
Start command”); te nella nostra applicazione: l’avvio e l’elaborazione della
start=new Command(“Start”,Command.OK, 1); richiesta. Durante l’avvio dobbiamo utilizzare il metodo
exit=new Command(“Exit”,Command.EXIT, 2); init() della Servlet per inizializzare tutte le risorse di cui
form.addCommand(start); avremo bisogno per il corretto funzionamento della no-
form.addCommand(exit); stra applicazione. Qui di seguito viene riportato il metodo
form.setCommandListener(this); init(), che viene richiamato nel momento in cui l’applica-
d.setCurrent(form); zione server viene installata/avviata.
…
public void init() throws ServletException {
In questo modo abbiamo presentato all’utente un’in- try {
terfaccia con due comandi disponibili: Start e Exit. Per System.out.println(“Start servlet”);
intercettare i comandi che abbiamo inserito nell’inter- Registry registry = LocateRegistry.createRegist
faccia dobbiamo implementare l’interfaccia Comman- ry(1199);
dListener, ovvero è necessario implementare il metodo HelloRMIImpl helloRMIImpl = new HelloRMIImpl();
commandAction() dove faremo partire la vera e propria registry.bind(“HelloRMI”, helloRMIImpl);
connessione verso il server HTTP. Nel Listato 1 è ripor- System.out.println(“Registrato oggetto RMI”);
tata la classe che permette di inviare la richiesta HTTP,
ed è implementata estendendo la classe Thread, per evi- jmsReceiver=new HelloJMSReceiver();
tare il deadlock della nostra applicazione. Come potete System.out.println(“Avviato JMS receiver”);
vedere, viene effettuata una chiamata HTTP utilizzando }
HttpConnection, un’interfaccia standard disponibile sulla catch(Exception e) {
piattaforma JavaME. La URL che viene richiamata è System.out.println(“init: “+e.toString());
quella della Servlet che dobbiamo implementare, alla }
quale viene passato un parametro che specifica il mes- }
saggio che vogliamo inviare. Alla fine dell’esecuzione di
questo Thread, viene restituito all’interfaccia grafica il Prima di tutto viene creato un registro RMI, nel quale
messaggio di risposta della Servlet. In Figura 2 potete viene inserito un oggetto RMI che in seguito andremo ad
Inserire un messaggio
in una coda JMS
che un client remoto può sapere di un oggetto RMI. Per JMS. Questa classe implementa l’interfaccia javax.jms.M
utilizzare un oggetto RMI, come abbiamo fatto qui, dob- essageListener e nel costruttore si collega alla coda JMS
biamo caricarlo dal registro RMI e poi richiamare i suoi che già abbiamo visto. In questo caso, però, la coda viene
metodi. È necessario che il client conosca l’interfaccia di utilizzata soltanto per ricevere i nuovi messaggi che ven-
questo oggetto, per poter invocare i metodi che esso offre. gono inseriti, quindi il nostro oggetto si comporterà come
Nel Listato 2 si può invece osservare l’implementazione consumatore, rispetto all’oggetto HelloRMIImpl che è il
dell’interfaccia HelloRMI. In questo caso, nel metodo sen- produttore. Come abbiamo visto precedentemente, que-
dHello(), si può vedere come abbiamo realizzato l’ulteriore sto oggetto viene istanziato nel metodo init() della Ser-
salto per il nostro messaggio. Per fare ciò ci siamo connessi vlet, quindi da quel momento in poi è in listening sulla
ad una coda JMS messa a disposizione dall’Application coda it.javajournal.queue. Quando viene inserito l’oggetto
Server BEA WebLogic 8.1 e abbiamo inserito il nostro mes- TextMessage nella coda, viene richiamato il metodo onMes-
saggio. In questo esempio è stata utilizzata una Queue, e sage(), che provvede ad inserire il nostro messaggio all’in-
grazie al ConnectionFactory standard di BEA abbiamo inseri- terno di un database utilizzando JDBC. In questo caso
to un TextMessage creato con il messaggio che viene passato viene utilizzato il DataSource /weblogic/jdbc/jts/HelloDS che
come parametro al metodo sendHello(). Nella Figura 3 si è stato precedentemente configurato nel nostro Applica-
osserva la configurazione della coda JMS sulla console di tion Server. Un DataSource non è altro che un’interfaccia
amministrazione di BEA. definita nelle API JDBC che permette di ottenere una
connessione verso un database. La comodità di richia-
mare un DataSource definito esternamente è relativa
JMS agli aspetti di configurazione. Praticamente, se dobbiamo
utilizzare un database diverso, un utente diverso, o un
Siamo arrivati quindi all’implementazione del listener driver JDBC diverso, non dovremo effettuare questi cam-
JMS. Anche in questo caso, come nella Servlet, dobbiamo biamenti nel codice ma direttamente nel pannello di am-
distinguere due diversi momenti, quello dell’inizializza- ministrazione del nostro Application Server. In Figura 4
zione e quello del metodo onMessage(), che viene richia- potete vedere la configurazione che viene utilizzata per il
mato ogni volta che è presente un messaggio nella coda. DataSource che abbiamo utilizzato. Qui di seguito viene
Nel Listato 3 è riportata l’implementazione della classe riportato il semplice script SQL che abbiamo utilizzato
HelloJMSReceiver, che si occupa appunto di gestire la coda per creare la tabella sul database.
CREATE TABLE HELLO_MESSAGE (MESSAGGIO VARCHAR2(765)); due diverse tecnologie Java, JSP e JSTL. Praticamente,
COMMIT; all’interno di una pagina JSP avremo modo di recupe-
rare le informazioni sul database grazie alle tag library
standard. Qui di seguito potete vedere il codice che rea-
lizza la funzione richiesta:
Esporre un oggetto
<%@ taglib uri=”http://java.sun.com/jstl/core” prefix=”c” %>
<sql:setDataSource
RMI, disponibile per var=”ds”
driver=”oracle.jdbc.driver.OracleDriver”
client remoti url=”jdbc:oracle:thin:@127.0.0.1:1521:HELLOWORLD”
user=”system”
password=”system”
/>
A questo punto il messaggio, che è partito dal nostro <c:forEach var=”row” items=”${messaggi.rows}”>
cellulare, è finito dentro il database. Ora dobbiamo <c:out value=”${row.messaggio}” />
occuparci di realizzare una pagina che verrà chiama- </c:forEach>
ta di continuo da un classico programma JavaSE, per
fornire il messaggio che è stato inserito nella tabella In questa pagina JSP vengono utilizzate due diverse tag li-
HELLO_MESSAGE del database. Per fare ciò utilizzeremo brary, quella relativa al database (sql) e quella base (core).
Programma Desktop
Introduzione a
Struts
Struts è un framework completo e diffuso e offre le basi per sviluppare in modo organico le
applicazioni web
http://localhost/struts-examples/welcome.do.
<servlet-name>action</servlet-name>
// logon.jsp
<url-pattern>*.do</url-pattern>
</servlet-mapping>
...
…
...
Questo frammento di codice consente di regi-
strare l’uso della Tag library struts-logic all’inter-
LISTATO 1 La JSP per la Logincon struts no della pagina JSP e quindi di utilizzare il tag
redirect di tale libreria per eseguire un’azione di
redirect. In particolare il browser viene rediretto
Dando un’occhiata più da vicino, cerchiamo di capire come verso una Action di nome Welcome, che è definita nel file
funziona e quale plus dà Struts a questa applicazione. In di configurazione di Struts.
primo luogo osserviamo il descrittore WEB-INF/web.xml: Nella sezione action-mappings del file WEB-INF/struts-
config.xml, viene definita tra le altre l’azione Welcome:
// web.xml
… // struts-config.xml
<servlet> …
<servlet-name>action</servlet-name> <action path=”/Welcome”
<servlet-class> type=”org.apache.struts.webapp.example.Wel
org.apache.struts.action.ActionServlet comeAction”>
</servlet-class> <forward name=”failure” path=”/Error.jsp” />
<init-param> <forward name=”success” path=”/welcome.jsp” />
<param-name>config</param-name> </action>
<param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-config- // LogonAction.java
registration.xml
</param-value> ...
</init-param>
<load-on-startup>1</load-on-startup> public ActionForward execute(...) throws Exception {
</servlet> ...
… String username = (String) PropertyUtils.getSimplePropert
y(form,
Nella sezione relativa alla definizione dei USERNAME);
servlet, viene definito il controller del nostro String password = (String) PropertyUtils.getSimplePropert
framework MVC: l’ActionServlet. L’Action- y(form,
Servlet viene caricato all’avvio e gli vengono PASSWORD);
passati come parametri due file di configu- ...
razione scritti in XML che il servlet caricherà return (mapping.getInputForward());
all’avvio dell’applicazione e di cui vedremo tra ...
poco il contenuto. return (findSuccess(mapping));
Per essere invocato dal servlet container,
l’ActionServlet, deve essere associato ad un }
pattern URL:
...
// web.xml
…
<servlet-mapping>
LISTATO 2 La Action (java) per la Login con struts
ActionForm
form,
HttpServletRequest
request,
HttpServletResponse
response)
throws
Exception {
...
if
(messages.size()>0) {
...
return
findFailure(mapping);
}
return
findSuccess(mapping);
}
FIGURA 3 editiamo una azione }
…
…
Nel codice, a seconda del successo o meno di alcune
Questo frammento della configurazione, noto come istruzioni che non è nostro scopo approfondire, possiamo
ActionMapping, fa sì che quando viene richiesta l’URL decidere di “uscire con successo” o “uscire con insuccesso”
/Welcome.do (è case sensitive, quindi con la
W maiuscola), venga creato un oggetto di // La classe TextBean è molto semplice:
classe WelcomeAction, che è istanziato dal fra- // ha una proprietà di nome text di tipo String
mework, ma è definito dal programmatore. // accessibile sia in lettura che in scrittura.
Il frammento contiene anche la definizione
di due forward di nome failure e success. A TextBean.java
questi sono associate due pagine JSP, rispet- public class TextBean {
tivamente /Error.jsp e /welcome.jsp. Vediamo private String text;
cosa significano queste impostazioni e come public String getText() {
funziona un’azione Struts.
return this.text;
Aprendo il file WEB-INF/src/org/apache/struts/ }
webapp/example/WelcomeAction.java, a cui si ri- public void setText(String text) {
ferisce l’action mapping visto sopra, notiamo
che l’azione estende una classe fornita nel- this.text = text;
l’esempio: BaseAction che a sua volta estende }
la classe del framework Action introducendo }
rispetto a quest’ultima solo alcuni semplici
metodi di utilità.
Una volta individuata la classe corrispondente // TextManager ha solo un metodo
all’azione, il framework la istanzia e ne invoca // che altera il contenuto della
il metodo execute() al quale vengono passati // proprietà text del bean TextBean
tutti gli oggetti per operare con il contesto
web e due oggetti Struts: l’ActionMapping TextManager.java
che rappresenta il contenuto del file di con- public class TextManager {
figurazione e l’ActionForm. Il metodo quindi
termina restituendo al framework che l’ha public TextManager() {
invocato, un oggetto di tipo ActionForward. }
<action path=”/Logon”
LISTATO 4 la form che visualizza il bean
forward=”/logon.jsp”/>
La pagina /logon.jsp, contiene un form costruito con i tag La classe LogonAction conterrà il codice per eseguire l’au-
della libreria HTML di Struts (Listato 1). tenticazione utilizzando username e password forniti dal
form (Listato 2).
Anche nel file di configurazione di Struts esiste una rap-
presentazione di questo form; si trova nella sezione form- Vale anche la pena di osservare che il metodo execute() è
beans: in grado di ritornare alla pagina di logon in caso di errori,
con il metodo mapping.getInputForward() che restitui-
// struts-config.xml sce il forward definito nell’attributo input dell’action-
… mapping.
<form-bean name=”LogonForm”
type=”org.apache.struts.validator.DynaValidatorForm”>
<form-property name=”username”
Uno sguardo alla “blank application”
type=”java.lang.String”/>
<form-property name=”password” La “blank-application” è contenuta nell’archivio struts-
type=”java.lang.String”/> blank.war e contiene lo “scheletro” di un’applicazione web
</form-bean> che funziona con il controller Struts. Ha un web.xml che
… carica l’ActionServlet con la configurazione definita nel file
struts-config.xml, che inizialmente contiene alcuni esempi
Il contenuto del form può essere quindi gestito dal ben commentati.
framework (in questo caso viene addirittura valicato Per iniziare a costruire applicazione web con Struts la
automaticamente dal framework attraverso l’uso del Dy- blank-application fornisce quindi una buona base di par-
naValidatorForm) e rappresentato al suo interno come tenza.
un JavaBean. L’azione /SubmitLogon a cui il form invia le Per interagire con il file di configurazione di Struts, può
informazioni è così definita: essere comodo inizialmente utilizzare uno strumento
di supporto grafico che aiuti a ricordare la struttu-
// struts-config.xml ra del file e il suo utilizzo. Un buono strumento in tal
… senso è la Struts console reperibile all’indirizzo http:
<action path=”/SubmitLogon” //www.jamesholmes.com/struts/console/ di cui in questo
type=”org.apache.struts.webapp.example.Lo esempio è stata usata la versione 4.8.
gonAction” Per iniziare con una nuova applicazione, quindi
name=”LogonForm” estrarremo il file struts-blank.war in qualche directory
scope=”request” nella quale verranno costruiti tutti i percorsi e i file di
input=”logon”> default, quindi usando la console struts e un kit di svi-
... luppo per Java procederemo con lo sviluppo di azioni
</action> e pagine JSP.
…
// SubmitAction.java
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
ActionForward retValue;
TextBean tb = new TextBean();
TextManager tm = new TextManager();
tb.setText((String) PropertyUtils.getSimpleProperty(form, “textproperty”));
tm.modifica(tb);
request.setAttribute(“risultato”, tb);
return mapping.findForward(“success”); }
}
FIGURA 4
// Success.jsp
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8”>
<title>JSP Page</title>
</head>
<body>
Il testo contenuto nel JavaBean processato è <bean:write name=”risultato” property=”text” />
</body>
</html>
• Infine aggiungiamo la pagina success.jsp che deve pre- Struts in effetti è un framework completo e diffuso e offre
sentare all’utente il risultato del processo avvenuto nel anche basi per sviluppare organicamente altre parti delle ap-
backend (Listato 6). plicazioni web, come il supporto all’internazionalizzazione,
alla validazione che in quest’articolo abbiamo solo sfiorato.
Per installare ed eseguire l’esempio è necessario compilare L’avvento di altri validi framework di successo ed il tentativo di
il progetto e copiare tutti i file dell’applicazione web conte- standardizzare lo sviluppo di applicazioni MVC condizionano
nuti nella cartella c:\esempi\struts nel servlet container. lo sviluppo di Struts ed in effetti la divisione tra l’Action Fra-
Una volta copiati i file necessari navighiamo all’URL http: mework e Shale è conseguenza di questo fatto.
//localhost/struts-blank/text.jsp. A questo punto, basterà
Note Biografiche
inserire del testo nella casella di testo, inviare il form … e
avremo ottenuto il risultato atteso. Andrea Colleoni si occupa professionalmente di sviluppo di sof-
tware dal 1996 e di Java dal 2000. Attualmente svolge l’attività
di consulente attraverso la sua società, coordinando gruppi di
lavoro su progetti software di dimensioni medie o grandi in am-
bito finanziario/bancario e industriale prevalentemente con tec-
Conclusioni nologie legate a J2EE, ma anche con Microsoft.NET. Si occupa
anche di formazione; insegna Informatica alla Facoltà di Eco-
Nell’esempio abbiamo toccato i punti essenziali dell’Action nomia dell’Università di Bergamo e in altri corsi più specifici
Framework che di fatto è l’elemento architetturale che con- organizzati da vari enti di formazione. Vive a Seriate in provin-
cia di Bergamo con mia moglie Elena e la sua piccolina, Greta,
sente di scrivere applicazioni web secondo il paradigma MVC. arrivata cinque mesi fa.
Programmazione
AOP con AspectJ
Dopo anni di programmazione strutturata, si è passati ad anni di programmazione ad oggetti.
Ora si inizia a parlare di POP (Post Object Programming), e delle tecnologie correlate. AOP (Aspect
Oriented Programming), è appunto una di queste tecnologie. Vediamo di cosa si tratta, con esempi
pratici e l’utilizzo di un compilatore gratuito come AspectJ.
Perché AOP
P
Lo scopo di AOP è quello di isolare un’esigenza oriz-
zontale, racchiuderla all’interno di una regola (as-
rogettare una libreria di funzioni o un pect), ed applicarla solamente nei punti in cui serve,
framework di classi, è sicuramente senza impattare minimamente la classe che ne trarrà
un’operazione lunga e laboriosa. vantaggio.
Occorre capire i problemi che si avran- Questo vuol dire che, le persone che sviluppano una
no, il modo col quale astrarli e genera- classe e quelle che la arricchiscono con un aspect,
lizzarli, ma soprattutto prevedere, nel possono tranquillamente far parte di due team di svi-
modo più completo possibile, le nuove esigenze che luppo diversi, dato che lavorano su due set di classi
si potrebbero avere, per evitare di trovarsi, durante lo differenti, che si fondono per creare un unico byteco-
sviluppo, in problemi architetturali. de, che sarà quello che andrà ad essere utilizzato in
Esistono però delle esigenze orizzontali ad un fra- fase di runtime.
mework, che dovrebbero far parte di tutte le classi, Sorgenti diversi, impatti minimi al cambio delle
ma, per evitare di sporcare tutto il codice, si tende a funzionalità delle classi, possibilità di aggiungere
non integrarle, ad integrarle parzialmente, o a dele- comportamenti senza modificare il framework che
garle al programma chiamante. deve essere arricchito, queste sono le caratteristiche
Esempi classici di queste esigenze sono la gestione principali di AOP.
degli errori, il debug degli oggetti, il controllo formale
dei parametri e così via.
Cosa vuol dire affrontare in modo generalizzato que- AspectJ
ste problematiche?
Sicuramente significa creare dei sorgenti ridondanti, Lo strumento di cui parleremo in questo articolo è
copiare dei frammenti di codice da un metodo all’al- AspectJ, un compilatore gratuito, che si appoggia a
tro, astrarre esigenze in interfacce ed obbligare le javac e permette di integrare, all’interno delle proprie
classi ad implementarle. Fino ad arrivare agli assurdi classi, degli aspect.
delle dipendenze circolari, schemi dai quali diventa Questo compilatore è facilmente scaricabile da: http:
complicato uscire. //www.eclipse.org/aspectj/, e si installa con la clas-
Quando poi l’esigenza orizzontale muta, ne risente sica invocazione da riga comando: java -jar aspectj-
l’intero framework, creando delle destabilizzazioni 1.5.0.jar.
nel codice: se il tutto non è stato progettato più che Una volta installato, viene creata una cartella su
bene, ci si può trovare di fronte alla riscrittura di disco, generalmente c:\aspectj1.5\, che conterrà sia il
varie classi, che non dipendono direttamente dalla compilatore che le librerie per poterlo utilizzare.
modifica della funzionalità orizzontale, ma semplice- Il passo successivo sarà quello di mettere in path la
mente sono impattate in quanto utilizzatrici dirette directory c:\aspectj1.5\bin e in classpath il jar di As-
della funzionalità ormai obsoleta. pectJ: c:\aspectj1.5\lib\aspectjrt.jar.
Call / Execution
void around()
This/Target
: primo_metodo() {
proceed(); aspect Logging {
} pointcut primo_metodo()
} : execution( * *.go() )
&& this(Demo2);
void around():
primo_metodo() {
proceed();
Set/Get
}
Così come possiamo controllare l’accesso ad un metodo, è
possibile controllare l’accesso ad una variabile d’istanza, pointcut primo_metodo2()
sia in lettura che in scrittura. Per fare questo è possibile : execution( * *.go() )
utilizzare un pointcut dove indicare quale variabile, di quale && target(Demo);
classe, andare a controllare. Per quanto riguarda l’advice, void around():
rimane tutto invariato, come nel caso del metodo: primo_metodo2() {
proceed();
}
}
Set/Get
aspect Logging {
pointcut primo_metodo()
: set( String Demo.cVal );
pointcut primo_metodo2()
Questa modalità
: get( String Demo.cVal );
void around()
: primo_metodo() {
}
proceed(); permette di aggiungere
String around()
: primo_metodo2() {
del codice, ad
String c;
c = proceed();
applicazioni già scritte,
return c;
} senza bisogno di
}
modificarle
This/Target
proceed();
System.out.println(“Dopo”); di questo tipo di programmazione, ma solo i concetti
} base, che permettono di capire come iniziare a pro-
} grammare. Come si può notare, il concetto base di
AOP è molto semplice. Servono poche righe di codice
per arricchire in modo concreto, molte classi di nuove
Advice funzionalità.
Piuttosto, il problema di AOP è la sua giovane età. Il
Ora che abbiamo ben compreso come creare dei poin- supporto per questo tipo di programmazione non è an-
tcut, vediamo quali tipo di esecuzione è possibile far cora molto diffuso, anche se inizia a essere presente in
fare ad un advice. alcuni ambienti di sviluppo.
Oltre ad around, osservato negli esempi precedenti, è Inoltre, pensare in AOP, richiede un ulteriore passo in
possibile anche indicare before se vogliamo eseguire del avanti, rispetto alla programmazione Object Oriented,
codice prima del pointcut, o after, se lo vogliamo esegui- passo di cui non si sente ancora l’esigenza diffusa.
re dopo. Come tutte le cose, il tempo ci potrà dare ragione o
Da notare che un advice è di per se molto simile ad un potrà cancellare completamente questo approccio post-
metodo, in quanto, come un metodo: object oriented.
• Non ha un nome
• Non può essere chiamato direttamente, è il sistema Un aspect è una regola
che lo esegue
• Ha accesso ad alcune variabili valorizzate all’interno che indica il punto dove
di this che possono servire a prendere informazioni
sui join point catturati: thisJoinPoint deve essere eseguito
Altro aspetto interessante degli advice è quello di poter
essere eseguiti dopo il ritorno di un valore da un meto-
del codice
do, oppure nel momento di un’eccezione nel codice.
Advice su eccezione
aspect Logging {
after() throwing: call(* *.*()) {
System.out.println(“ERRORE”);
}
}
Note Biografiche
Matteo Baccan è uno specialista di progettazione e svilup-
po C++, JAVA e AOP. È ideatore del portale JobCrawler.it e
Conclusioni speaker in importanti eventi Java (Javaday, JIP Day). Attual-
mente si occupa di analisi presso un importante operatore di
Questo articolo è un’introduzione alla programmazio- telefonia mobile. Può essere contattato tramite il suo sito http:
//www.baccan.it.
ne AOP. Non sono stati toccati i concetti più complessi
5. Se non ci sono validi motivi per non farlo, • Andare a cercare i falsi oggetti nel vostro codi-
spostare il comportamento dalle classi Handler/ ce
Manager alla classe di dominio • Andare a cercare i falsi oggetti in un software
open source a piacere
• Elencare i casi in un oggetto anemico è giustifi-
cato dal contesto
Conclusioni: