universitÀ degli studi di parma - ce.unipr.it · tesi di laurea di paolo zani. a francesca . i...

80
UNIVERSITÀ DEGLI STUDI DI PARMA FACOLTÀ DI INGEGNERIA CORSO DI LAUREA IN INGEGNERIA INFORMATICA REALIZZAZIONE DI UNO STRUMENTO PER LA GESTIONE DI BASI DI DATI IN APPLICAZIONI WEB Relatore Chiar.mo Prof. Ing. A. POGGI Correlatore Dott. Ing. F. BERGENTI Tesi di Laurea di PAOLO ZANI

Upload: vuxuyen

Post on 15-Feb-2019

227 views

Category:

Documents


0 download

TRANSCRIPT

UNIVERSITÀ DEGLI STUDI DI PARMA FACOLTÀ DI INGEGNERIA

CORSO DI LAUREA IN INGEGNERIA INFORMATICA

REALIZZAZIONE DI UNO STRUMENTO

PER LA GESTIONE DI BASI DI DATI IN

APPLICAZIONI WEB

Relatore

Chiar.mo Prof. Ing. A. POGGI

Correlatore

Dott. Ing. F. BERGENTI

Tesi di Laurea di

PAOLO ZANI

A Francesca

i

Ringraziamenti

Innanzitutto vorrei ringraziare il professor Agostino Poggi per avermi dato

l’opportunità di avvicinarmi al mondo del Java ed in particolare alla

programmazione di applicazioni web; un ringraziamento va anche all’ing.

Federico Bergenti, per la grande disponibilità dimostrata e i tanti consigli che mi

hanno permesso di portare a termine il mio lavoro.

Nulla comunque sarebbe stato possibile senza l’aiuto delle tante persone che in

questi mesi mi sono state vicine; in particolare devo menzionare Francesca

Ambroggi per il tempo, l’attenzione e i mezzi tecnici messi a mia disposizione

durante tutto questo periodo, Paolo Pini per avermi assistito nel duro lavoro di

revisione linguistica, Paolo Baroncini e Dario Lodi Rizzini per l’aiuto che mi

hanno dato nel a venire a capo di problemi di configurazione a prima vista

insolubili, e, naturalmente, Marco e Chiara, che hanno sempre creduto in me,

incoraggiandomi a continuare anche nei momenti di più grossa difficoltà.

ii

Indice

Prefazione…………………………………………………………………vi

1 Strumenti per applicazioni web in Java………………….………………. 1

2 JSTL – JavaServer Pages Standard Tag Library…………………………21

3 Miglioramenti alla gestione dei database via JSTL …………………….. 53

Conclusioni……………………………………………………………… 66

Glossario………………………………………………………………….68

Bibliografia……………………………………………………………….70

iii

Indice delle Figure

1.1 Esecuzione di una pagina JSP……………………………..………………7

1.2 Ciclo di vita di una Servlet generata a partire da una pagina JSP…………8

1.3 Architettura JSP Modello 1………………………………………………..9

1.4 Architettura JSP Modello 2 (MVC)……………………………………...10

1.5 Ambiti di visibilità delle variabili accessibili da una pagina JSP………..13

1.6 Forwarding delle Request………………………………………………..18

1.7 Dinamica del tag include………………………………………………...19

2.1 Schema risorse i18n……………………………………………………...33

iv

Indice delle Tabelle

2.1 EL-based Tag Libraries…………………………………..…………….22

2.2 RT-based Tag Libraries………………………………………………...23

2.3 Tag general-purpose…………………………………………………....27

2.4 Tag condizionali………………………………………………………..28

2.5 Tag iteratori…………………………………………………………….29

2.6 Tag di supporto agli URL……………………………………………...30

2.7 Tag per l’internazionalizzazione (i18n)………………………………..32

2.8 Tag per la formattazione……………………………………………….34

2.9 Tag XML di base………………………………………………………35

2.10 Tag XML per il controllo di flusso…………………………………….36

2.11 Tag XML per la trasformazione………………………………………..37

2.12 Parametri di <sql:query>……………………………………………….43

2.13 Parametri di <sql:update>……………………………………………...45

2.14 Parametri di <sql:transaction>…………………………………………47

2.15 Parametri di <sql:setDataSource>……………………………………...50

2.16 Parametri di <sql:param>……………………………………………....51

2.17 Parametri di <sql:dateParam>………………………………………….52

v

Indice dei Listati

2.1 Utilizzo dell’EL all’interno di un attributo……………………………..24

2.2 Query su un DB e creazione di una tabella contenente il risultato……..39

2.3 Transazione contenente aggiornamenti multipli del contenuto un DB…40

3.1 Esempio delle modifiche apportate a sql.tld……………………………61

3.2 Esempio delle modifiche apportate a sql-rt.tld…………………………62

3.3 Esempio di utilizzo del tag <sql:view>………………………………...63

vi

Prefazione

Negli ultimi anni abbiamo potuto assistere ad una sempre più rapida espansione

delle reti di calcolatori, ed in particolare di Internet: il numero di servizi offerti

dal web è in costante crescita, così come lo è la loro complessità.

In principio, la maggior parte delle operazioni consisteva nello scambio di

posta elettronica (utilizzando protocolli come SMTP e POP3), nel trasferimento di

file (attraverso FTP) o nella presentazione di informazioni attraverso pagine

HTML statiche, che permettevano, comunque, solo interazioni molto limitate. Col

passare del tempo, però, si è iniziata a sentire la necessità di fornire agli utenti la

possibilità di avere accesso a contenuti di tipo più dinamico e personalizzato,

come quelli offerti, ad esempio, da portali o siti di e-commerce.

Per raggiungere questo obiettivo sono state progressivamente sviluppate

diverse tecnologie, come ad esempio CGI e Servlet™, che permettono ad un

server di elaborare le richieste del client e di utilizzare le proprie risorse (dati,

capacità di calcolo ecc…) per fornire una risposta adeguata.

Uno dei problemi che si presentano quando si vuole realizzare servizi di tipo

dinamico è quello di riuscire a separare in modo efficace la fase dell’ elaborazione

dei dati da quella della loro presentazione: la realizzazione un’interfaccia user-

friendly e dall’aspetto gradevole ha assunto oramai una importanza tale da

richiedere, specialmente nel caso di prodotti di tipo commerciale, l’intervento di

personale qualificato, le cui competenze, però, potrebbero esulare da quelle di un

programmatore; allo stesso modo, non è detto che chi scrive le routine che si

preoccupano di elaborare le richieste (ad esempio accedendo ad un DB) abbia le

capacità necessarie a creare un sistema fruibile ed intuitivo anche per un’utenza

non specializzata.

vii

Una tecnologia che consente di realizzare questa separazione in modo

abbastanza semplice ed intuitivo è quella delle JSP™ (JavaServer™ Pages), che

permettono di estendere le possibilità offerte da HTML attraverso l’introduzione

di tutta una serie di nuovi tag che mettono a disposizione del designer di pagine

web gli strumenti necessari a realizzare siti dinamici con un procedimento del

tutto simile a quello utilizzato per la creazione di quelli statici.

I tag JSP hanno l’aspetto di elementi XML, e incapsulano la logica necessaria

alla generazione del contenuto delle pagine; l’elaborazione, inoltre, può essere

svolta da risorse messe a disposizione dal server (come ad esempio dei

JavaBean™), a cui i tag presenti sulla pagina accedono. E’ del tutto evidente che

il processo di realizzazione risulta molto velocizzato, e anche la manutenzione

diventa più semplice.

Un altro vantaggio delle JSP è che il numero di tag disponibile può essere

aumentato a piacere, semplicemente scrivendo delle classi Java™ che ne

implementino il comportamento secondo le specifiche fornite da Sun

Microsystems, Inc. ; in questo modo risulta possibile soddisfare anche le esigenze

di design più particolari o creare strumenti di sviluppo sempre più rapidi e

semplici da usare.

Basandosi su queste specifiche è stata realizzata una libreria di tag (JSTL,

JavaServer Pages Standard Tag Library) che implementa tutta una serie di

funzionalità comunemente richieste durante il processo di sviluppo di un sito web.

Tra le caratteristiche più sfruttate c’è la possibilità di utilizzare dei tag per

accedere a database relazionali, presenti ormai in una grandissima varietà di

situazioni (e.g. transazioni commerciali, gestione di clienti o personale, operazioni

bancarie, controllo magazzini); il sistema impiegato per comunicare coi database

presenta però una caratteristica particolare: i risultati delle query vengono restituiti

all’interno di un oggetto Java.

Questo fatto risulta vantaggioso quando si vogliono compiere ulteriori

elaborazioni sui dati restituiti dal database, ma appesantisce in modo notevole il

codice all’interno della pagina JSP quando quello che si desidera è la semplice

visualizzazione attraverso una tabella: in questo caso, infatti, oltre ai tag necessari

per realizzare la query, ne servono altri per creare un ciclo che scandisca in modo

viii

progressivo i risultati e li mandi in output con la formattazione desiderata; gli

stessi risultati, poi, potrebbero essere in numero tale da rendere molto scomoda la

loro consultazione, se mostrati tutti assieme.

Queste considerazioni hanno portato all’idea di sviluppare un’estensione ai tag

di gestione delle transazioni sql presenti all’interno della JSTL che potesse

permettere di realizzare con una sintassi semplice l’esecuzione di query e la

visualizzazione dei risultati mediante tabelle formattate secondo le necessità del

designer della pagina web.

Attraverso il nuovo tag sarà possibile specificare come parametri le

caratteristiche che la tabella che verrà disegnata dovrà avere (e.g. le dimensioni

del bordo e il foglio di stile da utilizzare per il rendering), e quanti saranno i

risultati visualizzabili al massimo contemporaneamente: i dati risulteranno quindi

divisi in ‘pagine’, attraverso cui si potrà navigare grazie ai bottoni visualizzati al

di sotto di ogni tabella.

Grazie a questo sistema, quindi, non sarà più necessario preoccuparsi di come

realizzare l’output grafico, ma solo di quale aspetto la pagina finale debba avere e

quali siano i dati in essa contenuti.

Strumenti per applicazioni web in Java 1

Capitolo 1

Strumenti per

applicazioni web in Java

Questo capitolo tratta di come sia possibile realizzare applicazioni web

dinamiche utilizzando tecnologie basate sul linguaggio Java.

1.1 Servlet a quando si è cominciato ad utilizzare il Web per fornire servizi, i

provider hanno avvertito la necessità di inserire, nei loro siti, contenuto

dinamico, giacché soltanto in questo modo risulta possibile realizzare

applicazioni di una certa complessità; si possono, infatti, presentare diverse

situazioni in cui una pagina statica non risulta sufficiente:

1. La pagina web è basata su dati inseriti dall’utente – ad esempio, le pagine

dei risultati nei motori di ricerca, o la pagina di conferma delle ordinazioni

in un negozio on- line sono determinate dalle richieste dell’utente;

2. La pagina web è basata su dati che cambiano di frequente – come le

previsioni del tempo o le ultime notizie, per cui si può costruire una pagina

aggiornata in tempo reale ;

D

Strumenti per applicazioni web in Java 2

2

3. La pagina web viene costruita basandosi su DB o altre risorse residenti sul

server – ad esempio, in un sito di e-commerce si potrebbe voler mostrare

le disponibilità e i prezzi dei prodotti presenti in magazzino.

Uno dei primi tentativi in questa direzione sono state le applet, che

utilizzavano la piattaforma client per compiere le elaborazioni richieste; nel

contempo, si è cercato un modo di utilizzare i server stessi per ottenere i risultati

desiderati: sono nati, così, gli script CGI (Common Gateway Interface), che, pur

essendo tuttora largamente utilizzati, hanno un numero considerevole di limiti e

svantaggi. La tecnologia Java Servlet si propone di superare i problemi emersi

finora e di fornire agli utenti, in maniera portabile, contenuti dinamici e

personalizzati.

Le Servlet sono programmi che girano su di un server web, agendo come

strato intermedio tra la request proveniente da un browser o un altro client http e i

database o le applicazioni presenti sul server http. I loro compiti sono:

1. Leggere i dati inviati dall’utente – di solito questi sono inseriti in un form

all’interno di una pagina web, ma potrebbero anche provenire da un’applet

Java o da un qualsiasi altro programma che funga da client HTTP;

2. Controllare ogni altra informazione sulla richiesta che sia stata

eventualmente inserita nella request HTTP – questi dati aggiuntivi possono

comprendere dettagli sulle capacità del browser, cookie, il nome dell’host

su cui è in esecuzione il client e così via;

3. Generare i risultati – questo processo potrebbe richiedere di connettersi ad

un database, eseguire una chiamata RMI o CORBA, eseguire

un’applicazione o generare direttamente una risposta;

4. Inserire i risultati generati all’interno di un documento – nella maggior

parte dei casi questo comporta la creazione di una pagina HTML a partire

dai risultati;

5. Settare i parametri opportuni all’interno della response HTTP – questo

significa indicare al browser il tipo di documento restituito, settare i cookie

o altri parametri e operazioni del genere;

Strumenti per applicazioni web in Java 3

3

6. Inviare il documento al client – il contenuto restituito al client può essere

in forma di testo (HTML), binario (come immagini JPEG) o persino

compresso in qualche formato come gzip.

1.1.1 Confronto tra Servlet e CGI

Le Servlet Java risultano più efficienti, facili da usare, potenti, portabili, sicure

ed economiche che i CGI tradizionali e tecnologie simili.

1. Efficienza

Con i CGI tradizionali viene creato un nuovo processo per ogni request

HTTP ricevuta. Se il programma CGI in sé è relativamente corto il tempo

necessario a farlo partire può diventare maggiore di quello necessario

all’esecuzione. Con le servlet la JVM resta in esecuzione e gestisce ogni

richiesta utilizzando un thread Java, molto meno pesante per il sistema di

un processo. Infine, quando un programma CGI finisce di servire una

richiesta questo termina, rendendo difficile tener traccia delle elaborazioni

svolte, lasciare le connessioni ai database aperte e in generale effettuare

tutte quelle ottimizzazioni che si basano su dati persistenti; le Servlet,

invece, restano in memoria anche dopo aver completato la risposta,

rendendo possibile senza difficoltà lo scambio di dati complessi a piacere

tra una richiesta e l’altra.

2. Facilità d’uso

Le Servlet contengono tutta una serie di infrastrutture che permettono di

analizzare e decodificare i dati contenuti nei form HTML, leggere e settare

header HTTP, manipolare cookie, tener traccia di sessioni e svolgere altri

compiti simili, il tutto in modo automatico.

3. Potenza

Le Servlet offrono diverse caratteristiche che sono difficili o impossibili da

ottenere con i CGI tradizionali: sono, infatti, in grado di comunicare

direttamente col server su cui risiedono (cosa che i CGI sono in grado di

fare soltanto utilizzando API specifiche quando queste siano previste dal

Strumenti per applicazioni web in Java 4

4

server stesso), possono condividere dati (come informazioni sulle

connessioni a database esistenti) e mantenere informazioni da una richiesta

all’altra, semplificando la gestione delle sessioni e permettendo di

mantenere una cache delle elaborazioni svolte.

4. Portabilità

Le Servlet sono scritte in linguaggio Java e seguono una API standard; di

conseguenza, una servlet può, in teoria, girare senza alcuna modifica su un

qualsiasi server che le supporti in modo diretto oppure attraverso dei

plugin. Le Servlet sono diventate parte della J2EE, e quindi il supporto per

questa tecnologia sta diventando sempre più ampio.

5. Sicurezza

Una delle maggiori vulnerabilità dei CGI tradizionali deriva dal fatto che

questi vengono spesso eseguiti all’interno di terminali di sistemi operativi,

obbligando gli sviluppatori a prestare molta attenzione al trattamento di

caratteri particolari, che potrebbero essere interpretati come comandi;

questi programmi, inoltre, sono a volte scritti in linguaggi (come C e C++)

che non eseguono controlli automatici sulle dimensioni di vettori o

stringhe, rendendo possibili attacchi basati su buffer overflow. Le Servlet

non presentano questi problemi, dato che non utilizzano terminali per

eseguire chiamate di sistema e, essendo scritte in Java, si avvantaggiano di

tutti i meccanismi di gestione e protezione della memoria propri di questo

linguaggio di programmazione.

6. Economicità

Sono disponibili diversi server web gratuiti per siti con un carico di lavoro

previsto relativamente basso, e, anche nel caso di prodotti commerciali di

un certo calibro, aggiungere il supporto per l’utilizzo delle Servlet (ove

non sia già previsto) richiede un investimento supplementare minimo.

Strumenti per applicazioni web in Java 5

5

1.2 JavaServer Pages La tecnologia JavaServer Pages permette di creare con facilità contenuti web

che comprendano sia componenti statici che dinamici. Le JSP mettono a

disposizione tutte le potenzialità della tecnologia Java Servlet fornendo nel

contempo un approccio più naturale alla creazione delle parti di contenuto

statiche. Le caratteristiche principali di questa tecnologia sono:

1. un linguaggio per sviluppare pagine JSP, che sono documenti di testo

che descrivono come elaborare una request e costruire una response;

2. un Expression Language per accedere ad oggetti sul lato server;

3. meccanismi per definire estensioni al linguaggio JSP

Una pagina JSP tipicamente risulta composta da componenti HTML/XML

statici, tag JSP e, opzionalmente, parti di codice scritte in Java chiamate

“scriptlet”.

Le specifiche che definiscono JSP ne fanno un’estensione standard costruita

sulla base dell’API prevista per le Servlet, ereditandone tutti i vantaggi. Ci sono

tuttavia delle considerevoli differenze tra queste due tecnologie: a differenza delle

Servlet, le JSP non richiedono grosse capacità di programmazione e si rivolgono

quindi ad un pubblico più vasto, comprendente oltre agli sviluppatori anche i

designer di pagine web, che quindi possono assumere un ruolo di maggiore

importanza nel processo di sviluppo.

Un altro vantaggio delle JSP è la separazione della presentazione dal

contenuto resa ancora più semplice dalla tecnologia, dal momento che questa si

basa su componenti riutilizzabili come i JavaBeans.

1.2.1 Confronto tra JSP e Servlet

Con le Servlet la logica per la generazione del contenuto dinamico è parte della

servlet stessa ed è intimamente legato ai modelli responsabili per la generazione

dell’interfaccia utente, così anche un cambiamento minimo all’interfaccia richiede

tipicamente di ricompilare il codice. Con le JSP invece la logica necessaria a

generare il contenuto dinamico viene tenuta separata dai modelli di presentazione,

Strumenti per applicazioni web in Java 6

6

incapsulandola all’interno di componenti JavaBeans che vengono poi creati e

utilizzati dalla pagina JSP mediante tag speciali e scriptlet. Quando il designer

cambia in qualche modo il modello per la presentazione la pagina viene

ricompilata in modo automatico e ricaricata all’interno del server web dal motore

JSP. Questa tecnologia permette inoltre di trasferire le pagine tra server e

piattaforme diverse senza richiedere modifiche.

Il contenuto dei modelli statici che compongono una pagina JSP possono

essere di qualunque tipo; questo permette di realizzare applicazioni per i più

svariati campi di impiego, da pagine scritte in linguaggi che vanno dall’

HTML/DHTML al WML, fino all’XML impiegato in certe soluzioni

commerciali.

1.2.2 Confronto tra JSP e ASP

ASP™ (Active Server Pages) è una tecnologia concorrente proposta da

Microsoft®; nonostante le caratteristiche offerte da JSP e ASP possano apparire

simili, tra le due esistono notevoli differenze. JSP può girare su tutti i server web

più popolari, come Apache, Netscape ed anche IIS, mentre ASP è legata

all’ultimo (o a prodotti specifici realizzati da terze parti); JSP è indipendente dalla

piattaforma su cui gira, purché questa fornisca una JVM, invece ASP ha bisogno

del supporto di Windows™ e il porting su altri sistemi risulta molto difficoltoso;

JSP utilizza componenti riutilizzabili e multipiattaforma come JavaBeans,

Enterprise JavaBeans e tag library personalizzate, ASP si basa sul modello di

componenti COM tipico di Win32; JSP utilizza per lo scripting Java e JavaScript,

ASP VBScript e JScript; per quanto riguarda la sicurezza, JSP si basa sul modello

Java, mentre il suo concorrente utilizza l’architettura prevista per Windows NT;

per l’accesso ai database il primo utilizza JDBC mentre il secondo ADO (Active

Data Object); JSP infine risulta estensibile mediante l’utilizzo di tag library

personalizzate, ASP no.

1.2.3 Confronto tra JSP e JavaScript

JavaScript, che è completamente distinto dal linguaggio di programmazione

Java, viene di norma utilizzato per generare contenuto HTML direttamente sul

Strumenti per applicazioni web in Java 7

7

client, costruendo parti della pagina mentre il browser la sta caricando. Questa è

una caratteristica utile, ma permette di affrontare unicamente situazioni in cui le

informazioni dinamiche sono basate soltanto sull’ambiente del client. A parte i

cookie, i dati inseriti nella request HTTP non sono disponibili alle routine

JavaScript e, dato che questo linguaggio non prevede strumenti per la

programmazione di rete, il codice presente sul client non può accedere a risorse

presenti sul server come database, cataloghi, listini prezzi e simili. JavaScript può

essere utilizzato anche sul lato server (come per Netscape e IIS).

1.2.4 Architettura JSP

Lo scopo delle JSP è di fornire un metodo dichiarativo e incentrato sulla

presentazione per sviluppare delle servlet. Come è stato già evidenziato le JSP

sono un’estensione basata sull’API Servlet, è quindi naturale che queste due

tecnologie abbiano molto in comune.

Tipicamente le pagine JSP sono soggette ad una fase di traduzione, in seguito

alla quale acquistano la capacità di elaborare le richieste che gli vengono

sottoposte. La compilazione viene effettuata soltanto una volta (a meno che la

Figura 1.1. Esecuzione di una pagina JSP

Strumenti per applicazioni web in Java 8

8

pagina stessa non venga modificata); se la pagina non contiene errori il risultato

sarà una classe Java, che implementa l’interfaccia Servlet, rappresentante la

pagina JSP di partenza.

La fase di traduzione viene di solito portata a termine dal motore JSP stesso la

prima volta che riceve una richiesta indirizzata alla pagina; le specifiche JSP 1.1

prevedono comunque che i file contenenti le classi già compilate possano essere

generati anche in precedenza, in modo da ridurre i tempi morti iniziali.

Il file compilato finale che implementa la pagina JSP estende la classe

HttpJspBase, che a sua volta implementa l’interfaccia Servlet; all’interno di esso è

presente il metodo _jspService(), che è responsabile della formulazione di una

risposta alle richieste inviate dal client. Gli sviluppatori inoltre possono indicare il

comportamento che il sistema dovrà avere nelle fasi di avvio e arresto attraverso i

metodi jspInit() e jspDestroy(), come si può vedere nella figura 1.2.

Una volta che la classe è stata caricata all’interno del contenitore che si

occuperà della sua esecuzione, il metodo _jspService() può elaborare le richieste

Figura 1.2. Ciclo di vita di una Servlet generata a

partire da una pagina JSP

Strumenti per applicazioni web in Java 9

9

del client e costruire le risposte da inviare; di default questo metodo viene

eseguito in un thread separato per ogni richiesta.

Le prime specifiche introdotte per le JSP prevedevano due approcci strutturali

differenti (noti come architetture Modello 1 e Modello 2) per impiegare questa

tecnologia all’interno delle applicazioni web; questi differiscono essenzialmente

per il punto in cui viene eseguita l’elaborazione della request, e forniscono un

utile paradigma per la progettazione.

Come si può vedere nella figura 1.3 nell’architettura Modello 1 la richiesta

proveniente da un browser web viene inviata direttamente alla pagina JSP, che è

quindi incaricata di elaborarla e di fornire la risposta al client; c’è comunque

separazione tra presentazione e contenuto, perché ai dati si accede sempre

attraverso dei JavaBean.

Nonostante questo tipo di architettura sia indicata per piccole applicazioni,

potrebbe rivelarsi inadatta a progetti su larga scala. Un uso indiscriminato di

questa architettura di solito porta ad avere grandi quantità di script o codice Java

Figura 1.3. Architettura JSP Modello 1

Strumenti per applicazioni web in Java 10

10

all’interno delle pagine, specialmente quando è necessario operare una notevole

quantità di elaborazioni sulla richiesta del client. Nonostante questo possa

sembrare un problema di poco conto per chi è abituato a sviluppare codice Java,

può diventare un ostacolo considerevole se le pagine JSP devono essere create o

mantenute da designer (come succede di norma in progetti di un certo rilievo).

Un altro svantaggio di questo approccio nello sviluppo è che ogni singola

pagina JSP deve gestire lo stato corrente dell’applicazione e controllare

autenticazioni e sicurezza.

L’architettura Modello 2, illustrata nella figura 1.4, è una implementazione del

popolare design pattern MVC (Model – View – Controller): qui l’elaborazione è

suddivisa tra componenti di presentazione e di controllo. I primi sono pagine JSP

che generano la risposta HTML/XML che costituirà l’interfaccia utente una volta

che sia stata disegnata dal browser. I restanti componenti (che possono essere

servlet o pagine JSP) invece non si occupano degli aspetti della rappresentazione,

ma piuttosto elaborano tutte le request HTTP: sono quindi loro a decidere quali

Figura 1.4. Architettura JSP Modello 2 (MVC)

Strumenti per applicazioni web in Java 11

11

oggetti o bean creare, e a decidere, in base alle azioni dell’utente, a qua le pagina

JSP indirizzare il risultato.

Il vantaggio di questo tipo di architettura è che non c’è alcuna elaborazione

all’interno dei componenti di presentazione, che hanno semplicemente il compito

di recuperare gli oggetti o i bean creati dai componenti di controllo e di estrarre da

essi il contenuto dinamico per poterlo poi inserire all’interno dei propri modelli

statici; di conseguenza questa netta separazione tra presentazione e contenuto

porta ad una chiara divisione dei ruoli e delle responsabilità dei programmatori da

quelle dei designer all’interno del team di sviluppo. Una ultima caratteristica

positiva di questo tipo di approccio è che essendoci un unico punto di contatto con

l’esterno lo stato, la sicurezza e l’aspetto dell’applicazione risultano più semplici

da gestire.

1.2.5 Elementi di scripting

Gli elementi di scripting JSP permettono di inserire codice Java all’interno

della servlet che verrà generata a partire dalla pagina JSP, e possono assumere tre

forme:

1. espressioni, nella forma <%= espressione %>, che vengono valutate e poi

inserite nell’output;

2. scriptlet, nella forma <% codice %>, che vengono inserite nel metodo

_jspService() della servlet;

3. dichiarazioni, nella forma <%! codice %>, che vengono inserite nel corpo

della classe che costituisce la servlet, al di fuori di qualsiasi metodo già

esistente.

Quando si utilizzano le espressioni JSP il risultato della loro valutazione viene

convertito in una stringa e incluso nella pagina di output. Tipicamente le

espressioni vengono utilizzate per mostrare semplici valori di variabili invocando

il metodo get di un bean, oppure per mostrare lo stato di uno degli oggetti

predefiniti. Le espressioni JSP sono incluse nel tag <%= … %> e non prevedono

l’utilizzo del punto e virgola per terminare le istruzioni.

Strumenti per applicazioni web in Java 12

12

Se diventa necessario svolgere azioni più articolate rispetto al semplice

inserimento del valore di una espressione, le scriptlet JSP permettono di inserire

codice Java arbitrario all’interno della servlet che verrà generata per costruire la

pagina; in generale le scriptlet possono svolgere molti compiti impossibili con il

solo uso di espressioni, come ad esempio settare header e codici di stato

all’interno della response, scrivere nei log del server o aggiornare un database, o

anche eseguire codice che contiene espressioni condizionali o cicli; le variabili

accessibili sono quelle predefinite rese disponibili anche per le espressioni. Si può

inserire qualsiasi frammento di codice Java valido, anche più di una riga alla

volta; una scriptlet è racchiusa nel tag <% … %>.

Le dichiarazioni JSP (inserite nel tag <%! … %>) permettono di definire

variabili visibili all’interno di tutta la pagina per memorizzare informazioni, e

anche di definire metodi che saranno utili al resto del programma; bisogna fare

attenzione perché utilizzando sia le espressioni che le dichiarazioni diventa

semplice inserire una grande quantità di istruzioni Java direttamente all’interno

della pagina JSP, rendendo in seguito la manutenzione molto difficoltosa. Per

questa ragione, e per rendere il codice maggiormente riutilizzabile, è opportuno

inserire la logica responsabile delle elaborazioni principali all’interno di

componenti JavaBean.

1.2.6 Ambiti di visibilità e variabili predefinite

Gli oggetti cui si può accedere all’interno di una pagina JSP possono essere

creati in diversi modi: implicitamente utilizzando le direttive JSP, oppure in modo

esplicito attraverso le azioni o, in rari casi, direttamente con lo scripting. Gli

oggetti istanziati possono essere associati con un attributo che ne definisca

l’ambito di visibilità (scope) , in modo da stabilire quando sia possibile accedervi

e quando invece questi debbano risultare non disponibili. I vari scope possibili

sono illustrati nella figura 1.5.

Strumenti per applicazioni web in Java 13

13

Per semplificare il codice presente all’interno delle pagine JSP sono state

introdotte delle variabili predefinite, a volte chiamate oggetti impliciti:

1. request (scope: request) – questa variabile rappresenta

l’HttpServletRequest associata alla request ricevuta; permette di

accedere ai parametri della request, al suo tipo (GET oppure POST) , e

agli header associati (e.g. i cookie);

2. response (scope: pagina) – questa variabile rappresenta

l’HttpServletResponse associata alla response inviata. Dal momento

che l’output di norma viene inserito in un buffer prima di essere

inviato, risulta possibile inserire header HTTP e codici della response

anche nel mezzo di una pagina JSP (cosa non concessa invece nelle

servlet una volta che sia stato prodotto un qualunque output);

3. out (scope: pagina) – questo è l’oggetto PrintWriter utilizzato per

inviare l’output al client; per rendere utilizzabile l’oggetto response

questa risulta in realtà una versione con buffer di PrintWriter chiamata

Figura 1.5. Ambiti di visibilità delle variabili accessibili da una pagina JSP

Strumenti per applicazioni web in Java 14

14

JspWriter; è possibile stabilire le dimensioni di questo buffer attraverso

l’attributo buffer nella direttiva page;

4. session (scope: sessione) – questa variabile rappresenta l’oggetto

HttpSession associato alla request;

5. application (scope: applicazione) – questa variabile è il ServletContext

ottenuto chiamando getServletConfig().getContext(). Sia le servlet che

le pagine JSP possono inserire dati all’interno dell’oggetto

ServletContext (che infatti prevede i metodi setAttribute() e

getAttribute()) in modo da renderli persistenti e disponibili a tutte le

servlet presenti all’interno del motore Servlet (o dell’applicazione

web);

6. config (scope: pagina) – questa variabile rappresenta l’oggetto

ServletConfig associato alla pagina corrente;

7. pageContext (scope: pagina) – la classe PageContext è stata introdotta

dalle JSP per fornire un punto di accesso unico per molti degli attributi

relativi alla pagina, e un posto in cui inserire i dati condivisi;

8. page (scope: pagina) – sinonimo di this, non è molto utile quando si

programma in Java, è stato inserito per compatibilità con altri linguaggi

di scripting;

9. exception (scope: pagina) – rappresenta l’oggetto Throwable non

gestito che ha portato al caricamento della pagina di errore.

1.2.7 Direttive

Le direttive sono messaggi per il motore JSP: non producono alcun output

visibile, ma forniscono indicazioni su come andrà trattato il resto della pagina;

vengono incluse all’interno del tag <%@ … %>, e possono essere principalmente

di due tipi: page e include (anche se JSP 1.1 prevede anche la direttiva taglib, che

permette di utilizzare librerie di tag personalizzate, come la JSTL).

Tipicamente la direttiva page si trova all’inizio della pagina JSP, e può

comparire anche più di una volta, purché le coppie nome-valore indicate risultino

Strumenti per applicazioni web in Java 15

15

univoche. Gli attributi che possono essere indicati all’interno di questa direttiva

sono: import, contentType, isThreadSafe, session, buffer, autoflush, extends, info,

errorPage, isErrorPage e language.

import=”package.class” o import=”package1.class, … , packageN.class”

questo attributo permette di specificare quali package devono essere importati; è

l’unico che può comparire più di una volta.

contentType=”tipo MIME” o contentType=”tipo MIME; charset=set di

caratteri”

questo attributo specifica il tipo MIME dell’output; il valore di default è

text/html.

isThreadSafe=”true | false”

il valore true indica il normale ciclo di elaborazione della servlet, per cui diverse

request possono essere gestite in modo simultaneo da una stessa istanza della

servlet, con l’assunzione che l’autore si sia preoccupato di sincronizzare l’accesso

alle variabili comuni. Il valore false indica che la servlet deve implementare

SingleThreadModel, in cui le request sono trattate in modo seriale, oppure

elaborate in parallelo da diverse istanze della servlet stessa.

session=”true | false”

il valore true (che è quello di default) indica che la variabile predefinita session (di

tipo HttpSession) deve essere collegata con la sessione corrente, se questa esiste,

altrimenti ne viene creata una. Il valore false indica che non verranno usate

sessioni, e ogni tentativo di accedere alla variabile session causerà un errore al

momento di tradurre la pagina JSP in una servlet.

buffer=”dimensionekb | none”

questo attributo specifica le dimensioni del buffer di output per JspWriter; il

valore di default dipende dal server che si utilizza, con un valore minimo

consentito di 8 Kb.

Strumenti per applicazioni web in Java 16

16

autoflush=”true | false”

il valore di true (default) indica che il buffer verrà svuotato quando è pieno,

mentre se l’attributo è impostato a false viene lanciata un’eccezione quando il

buffer va in overflow (questo valore non è ammesso se si ha buffer=”none”).

extends=”package.class”

indica la superclasse della servlet che verrà generata.

info=”messaggio”

definisce la stringa che si ottiene col metodo getServletInfo().

errorPage=”url”

specifica la pagina JSP che dovrà elaborare ogni oggetto Throwable lanciato ma

non gestito all’interno della pagina corrente.

isErrorPage=”true | false”

indica se la pagina corrente può fungere da gestore per gli errori generati da

un’altra pagina; il valore di default è false.

language=”java”

in futuro servirà per specificare il linguaggio utilizzato; per ora il valore di default,

che è anche l’unico ammesso, è java.

La direttiva include permette di includere un file nel documento JSP nel

momento in cui questo viene tradotto in una servlet (che di solito coincide con la

prima volta in cui si tenta di accedere alla pagina). Questo tipo di comportamento

ha due conseguenze principali: la prima è che, a differenza di quanto avviene con

jsp:include, qui viene inserito il file originale e non l’output prodotto dalla sua

esecuzione permettendo così di inserirvi anche costrutti JSP che interessano la

pagina nel suo complesso; la seconda conseguenza è che se il file incluso viene

modificato, tutte le pagine JSP che lo utilizzano devono essere ricompilate, e ai

server è permesso, ma non imposto, di farlo in modo automatico.

Strumenti per applicazioni web in Java 17

17

1.2.8 Azioni

Le azioni permettono di svolgere compiti sofisticati, come istanziare oggetti e

comunicare con risorse residenti sul server quali possono essere pagine JSP e

servlet senza richiedere alcun tipo di programmazione Java. Anche se gli stessi

risultati possono essere ottenuti con degli scriptlet, l’utilizzo di questi tag migliora

la riutilizzabilità del codice e ne permette una più facile manutenzione.

<jsp:useBean>

Il modello a componenti per la tecnologia JSP è basato sull’architettura

JavaBeans. Questi componenti non sono altro che oggetti Java che seguono un

ben preciso paradigma di progettazione e assegnazione dei nomi: il bean incapsula

i suoi attributi dichiarandoli come privati, e fornisce metodi per accedervi, sia in

lettura che in scrittura.

Il tag <jsp:useBean> cerca di ottenere un riferimento ad una istanza esistente

del bean specificato utilizzando i parametri id e scope forniti, dato che questo

potrebbe essere già stato creato e inserito nella sessione o nell’applicazione da

un’altra servlet o pagina JSP; se il bean cercato non esiste ancora viene creato.

Questo tag prevede anche un body (opzionale), che viene eseguito solo dopo

che il bean è stato creato, utilizzabile per inizializzarne gli attributi.

<jsp:getProperty>

Una volta che il bean è stato dichiarato si può accedere ai suoi attributi; per

accedere in lettura ad valore si utilizza il tag <jsp:getProperty>, specificando il

nome del bean da utilizzare e quello dell’attributo a cui si è interessati. Il valore

ottenuto viene quindi inviato direttamente in output.

Strumenti per applicazioni web in Java 18

18

<jsp:setProperty>

Questo tag permette di assegnare ad un attributo un nuovo valore, specificato con

una delle due sintassi seguenti:

<jsp:setProperty name=”nome del bean” property=”nome dell’attributo”

value=”valore” />

<jsp:setProperty name=”nome del bean” property=”nome dell’attributo”

value=”<% espressione %>” />

Quando il bean viene utilizzato per elaborare i dati inseriti all’interno di un

form è possibile utilizzare un design pattern comune che consiste nel far

corrispondere i nomi degli attributi del bean con quelli dei campi del form; in

questo modo si può indicare al motore JSP, con una sintassi semplificata, di

assegnare tutti i valori provenienti dal form agli attributi appropriati del bean,

come si può vedere nell’esempio seguente:

<jsp:setProperty name=”nome del bean” property=”*” />

Figura 1.6. Forwarding delle Request

Strumenti per applicazioni web in Java 19

19

<jsp:forward>

Utilizzando questa azione è possibile redirigere una qualunque request verso

un’altra pagina JSP, una servlet o anche una pagina HTML statica all’interno del

contesto corrente. Questo tag blocca l’elaborazione della pagina JSP che lo

contiene nel punto stesso dove compare, anche se tutto il codice che lo precede

viene comunque eseguito. La pagina chiamante può passare alla risorsa di

destinazione l’attributo di un bean inserendolo nella request, come si può vedere

nella figura 1.6. È infine possibile inserire dei tag del tipo <jsp:param> per

aggiungere alla request altri valori:

<jsp:forward page=”<%= nome %>” >

<jsp:param name=”nome1” value=”valore1” />

<jsp:param name=”nome2” value=”valore2” />

</jsp:forward>

Figura 1.7. Dinamica del tag include

Strumenti per applicazioni web in Java 20

20

<jsp:include>

Con questa azione si può indirizzare la request a qualunque risorsa, statica o

dinamica, presente nel contesto corrente, aggiungendo anche (se è il caso) gli

attributi di un JavaBean; la risorsa che riceve la request, se è in grado di farlo, la

elabora e il risultato ottenuto viene inserito nella pagina di partenza, come si può

vedere nella figura 1.7.

JSTL – JavaServer Pages Standard Tag Library 21

Capitolo 2

JSTL – JavaServer Pages

Standard Tag Library

Questo capitolo tratta delle caratteristiche e dell’utilizzo dei tag appartenenti alla

libreria JSTL.

2.1 Obiettivi della JSTL o scopo principale della JSTL è rendere più semplice il lavoro di chi

sviluppa pagine web utilizzando le JSP. L’autore è la figura responsabile

del design della parte di presentazione di una web application mediante

l’utilizzo delle JSP, e spesso non è esperto in nessun linguaggio di

programmazione.

Una delle maggiori difficoltà incontrate quindi è la necessità di utilizzare un

linguaggio di scripting (principalmente Java) per manipolare il contenuto

dinamico delle pagine JSP; purtroppo, però, questi linguaggi appaiono spesso

complessi e poco adatti alle esigenze di chi deve impostare l’aspetto grafico di un

sito.

L

JSTL – JavaServer Pages Standard Tag Library 22

22

JSTL viene incontro alle necessità degli autori in diversi modi:

1. Con l’expression language (EL), che permette di mostrare con

semplicità il risultato di espressioni e di settare il valore di variabili in

diversi scope (request, pagina, sessione, applicazione);

2. Con tag operanti come strutture di controllo di flusso (e.g. tag

condizionali, iteratori);

3. Con i tag library validators (TLVs), che consentono di imporre

l’utilizzo di particolari tag library;

4. Fornendo tag che supportano le principali funzionalità richieste durante

lo sviluppo di web applications, come l’accesso a risorse basate su

URL, internazionalizzazione (i18n), accesso a DB relazionali (SQL) e

processing XML.

2.2 Tag library disponibili Una tag library è un’insieme di azioni che incapsulano le funzionalità che

verranno richieste dall’interno di una pagina JSP; JSTL ne include una grande

varietà, e queste possono essere logicamente raggruppate in diverse categorie: la

standard tag library viene così indicata al singolare, pur essendo in realtà

composta da diverse librerie, ognuna dedicata ad implementare un particolare area

funzionale. La suddivisione della JSTL è riassunta nelle tabelle 2.1 e 2.2

Tabella 2.1. EL-based Tag Libraries

Area funzionale URI Prefisso

base http://java.sun.com/jstl/core c

processing XML http://java.sun.com/jstl/xml x

Formattazione compatibile

I18N http://java.sun.com/jstl/fmt fmt

accesso a DB relazionali

(SQL) http://java.sun.com/jstl/sql sql

JSTL – JavaServer Pages Standard Tag Library 23

23

Come si vede dalle tabelle sono presenti due versioni delle librerie: questo

accade perché la JSTL funziona in un contenitore JSP 1.2, e deve quindi risultare

compatibile con lo scripting tipico delle pagine JSP. In questo modo la maggior

parte degli utenti si appoggerà sull’EL, mentre gli autori che preferivano utilizzare

lo scripting basato sui request-time scripting values potranno continuare a lavorare

nella stessa maniera.

2.3 L’Expression Language Uno degli aspetti chiave della JSTL è il suo supporto per un expression

language (EL). L’EL fa leva sul fatto che gli attributi visibili da una pagina JSP

come pure i parametri della request sono il canale privilegiato per trasmettere

informazioni alle pagine stesse, consentendo così di accedere in modo semplice ai

dati generati dalle varie applicazioni e di manipolarli senza dover ricorrere a

scriptlet o request-time expression values.

Nella JSTL l’EL è reso disponibile all’interno degli attributi, e viene invocato

con la sintassi ${espressione}; un attributo può contenere anche più di un’

espressione EL, inframmezzata da testo statico, come nel listato 2.1.

2.3.1 Sintassi

La sintassi dell’EL è abbastanza semplice: alle variabili si accede per nome, e

nel caso di mappe, liste, array di oggetti e proprietà di JavaBean si può utilizzare

Tabella 2.2. RT-based Tag Libraries

Area funzionale URI Prefisso

base http://java.sun.com/jstl/core_rt c_rt

processing XML http://java.sun.com/jstl/xml_rt x_rt

Formattazione compatibile

I18N http://java.sun.com/jstl/fmt_rt fmt_rt

accesso a DB relazionali (SQL) http://java.sun.com/jstl/sql_rt sql_rt

JSTL – JavaServer Pages Standard Tag Library 24

24

l’operatore generalizzato []. L’operatore “.” può essere impiegato nel caso in cui il

nome della proprietà a cui si vuole accedere segua le convenzioni previste per gli

identificatori java, risultando però così di validità meno generale.

Le variabili possono essere confrontate tra loro (oppure con espressioni di tipo

booleano, stringa, intero o in virgola mobile) utilizzando gli operatori relazionali

Java standard. Si possono impiegare operatori aritmetici per calcolare valori interi

e in virgola mobile, ed è disponibile anche tutta una serie di operatori logici.

L’EL valuta un identificatore ricercando il suo valore come attributo, in

maniera analoga a quanto accade nella funzione

PageContext.findAttribute(String). Ad esempio:

${prodotto}

in questo caso l’EL ricercherà nei vari scope (pagina, request, sessione,

applicazione) un attributo di nome “prodotto” e ne restituirà il valore, oppure null

nel caso che questo non sia presente.

2.3.2 Oggetti impliciti

L’EL oltre agli attributi definiti dall’utente prevede una serie di oggetti

impliciti, a cui si accede in maniera analoga a quanto appena visto, ma che invece

di un valore restituiscono un oggetto Java. Gli oggetti impliciti disponibili sono:

1. pageContext – l’oggetto pageContext

2. pageScope – una Map che contiene gli attributi nello scope pagina e i loro

valori

3. requestScope – una Map che contiene gli attributi nello scope request e i

loro valori

<c:forEach var=”prodotto” items=”${prodotti}”>

<c:out value=”Il prezzo di ${prodotto.nome} è

${prodotto.prezzo}”/>

</c:forEach>

Listato 2.1. Utilizzo dell’EL all’interno di un attributo.

JSTL – JavaServer Pages Standard Tag Library 25

25

4. sessionScope – una Map che contiene gli attributi nello scope sessione e i

loro valori

5. applicationScope – una Map che contiene gli attributi nello scope

applicazione e i loro valori

6. param – una Map che per ogni parametro associa il nome ad un valore in

formato String (ottenuto chiamando la funzione

ServletRequest.getParameter(String name))

7. paramValues – una Map che per ogni parametro associa il nome a tutta la

serie dei suoi valori, contenuti in un array di tipo String (ottenuto

chiamando la funzione ServletRequest.getParameterValues(String name))

8. header – una Map dove i nomi degli header vengono inseriti in un unico

valore String (ottenuto chiamando la funzione

ServletRequest.getHeader(String name))

9. headerValues – una Map dove i nomi degli header vengono associati ad un

array di String in cui sono inseriti tutti i suoi valori (ottenuti chiamando la

funzione ServletRequest.getHeaders(String))

10. cookie – una Map in cui i nomi dei cookie sono inseriti in un unico oggetto

di tipo Cookie. I cookie vengono recuperati secondo la semantica definita

in HttpServletRequest.getCookies(). Se più cookie hanno lo stesso nome

verrà utilizzato quello che compare per primo nell’array di Cookie

restituito dal metodo getCookies(). In ogni caso chi utilizza questo oggetto

implicito deve tener presente che l’ordinamento dei cookie non è al

momento attuale definito all’interno delle specifiche per le Servlet.

11. initParam – una Map che associa i nomi dei parametri di inizializzazione

del contesto ai loro valori in formato String (ottenuti chiamando

ServletContext.getInitParameter(String name))

JSTL – JavaServer Pages Standard Tag Library 26

26

2.4 Core tag library La libreria core fornisce funzionalità di base per la creazione di pagine

dinamiche; i tag che la compongono possono essere divisi in diverse categorie:

1. Tag general-purpose: visualizzano il risultato di espressioni, manipolano

attributi all’interno di uno degli scope dell’applicazione web;

2. Tag condizionali: permettono l’esecuzione condizionale di segmenti di

codice;

3. Tag iteratori: consentono di creare azioni ripetute;

4. Tag di supporto agli URL: forniscono la possibilità di realizzare

redirezioni ed import.

2.4.1 Tag general-purpose

Dal momento che l’expression language non fa ancora parte delle specifiche

JSP si è reso necessario provvedere una funzionalità simile a quella fornita da JSP

(<%=espressione-nel- linguaggio-di-scripting%>) per visualizzare in modo

semplice il valore delle espressioni scritte nell’EL; lo strumento che permette

questo è il tag <c:out>. Come comportamento di default <c:out> converte i

caratteri <, >, ’, ”, & nei loro corrispondenti secondo la codifica HTML (così <

diventa &lt), in modo da evitare problemi di visualizzazione nei browser ed

evitare attacchi basati su scripting; questa convenzione può essere bypassata

settando l’attributo escapeXml a false .

<c:out> prevede anche l’utilizzo di valori di default qualora l’espressione EL

assuma valore null.

Per inserire un attributo all’interno di uno degli scope previsti è stato creato il

tag <c:set>, in cui il valore che verrà assunto dall’attributo stesso può essere

contenuto sia tra i parametri sia nel body del tag, permettendo in questo modo di

permetterne la generazione anche attraverso altre azioni. <c:set> permette inoltre

di impostare il valore di oggetti JavaBean o modificare elementi in un oggetto

java.util.Map.

Il naturale complemento di <c:set> è <c:remove>, che permette di rimuovere

in modo esplicito variabili settate in uno degli scope. Infine <c:catch> integra il

JSTL – JavaServer Pages Standard Tag Library 27

27

meccanismo di gestione degli errori delle pagine JSP, in modo da permettere agli

autori di affrontare in modo semplice le condizioni di errore recuperabili.

2.4.2 Tag condizionali

Molto spesso l’elaborazione che genera l’output di una pagina JSP prevede

che vengano effettuate delle scelte basate sul valore assunto da particolari insiemi

di dati dell’applicazione. Di solito chi programma ricorre a linguaggi di scripting

più o meno complessi per ottenere questo tipo di comportamento dinamico,

mentre questi tag permettono di ottenere il medesimo risultato senza dover

ricorrere a sintassi anche molto diverse dall’HTML.

L’esecuzione condizionata di un segmento di codice di norma può presentarsi

sotto due forme: semplice e mutuamente esclusiva.

Nel primo caso il body contenuto nel tag viene valutato solo se la condizione

dettata da un particolare parametro risulta verificata, mentre nel secondo vengono

dati tutta una serie di possibili azioni da eseguire, ciascuna innescata da un

particolare evento (sempre specificato come parametro all’interno del tag); se

nessuna condizione risulta verificata si passa all’analisi del comportamento di

default, quando questo sia stato definito.

Tabella 2.3. Tag general-purpose

Tag Utilizzo

<c:out> Valuta un’espressione e ne invia il

risultato all’oggetto JspWriter corrente

<c:set>

Assegna il valore ad una variabile in

uno degli scope o ad una proprietà

nell’oggetto desiderato

<c:remove> Rimuove una variabile

<c:catch>

Gestisce gli oggetti di tipo

java.lang.Throwable generati da

qualunque tag annidato

JSTL – JavaServer Pages Standard Tag Library 28

28

2.4.3 Tag iteratori

Come si è visto i tag condizionali semplificano la trattazione di un problema

ricorrente nello sviluppo di applicazioni; un altro tra i costrutti che più di

frequente viene impiegato quando si programma è senz’altro rappresentato dai

cicli. Il gruppo dei tag iteratori consente di scandire una grande varie tà di

collezioni di oggetti, ancora una volta senza richiedere di prestare attenzione a

sintassi complicate o a convertire oggetti di un tipo in un altro per renderli

utilizzabili.

Il tag <c:forEach> ripete il contenuto annidato nel body una volta per ognuno

degli oggetti contenuti nell’insieme indicato come parametro, oppure un numero

fissato di volte; sono inoltre supportati degli indicatori di range per potersi

muovere all’interno di un sottoinsieme di quello indicato in origine. Ad ogni ciclo

il tag esporta l’oggetto corrente all’interno della collezione indicata e uno

contenente informazioni sullo stato dell’iterazione.

Le collection supportate sono tutte quelle definite nella piattaforma J2SE™,

come tutte le implementazioni di java.util.Collection (che include List,

LinkedList, ArrayList, Vector, Stack e Set), e java.util.Map (che include

HashMap, Hashtable, Properties, Provider e Attributes).

Tabella 2.4. Tag condizionali

Tag Utilizzo

<c:if>

Valuta il body solo se l’espressione

specificata attraverso la proprietà test

risulta verificata

<c:choose>

Fornisce il contesto in cui inserire i tag

per effettuare scelte mutuamente

esclusive

<c:otherwise>

Rappresenta l’ultima alternativa

all’interno del contesto generato da

<c:choose>

JSTL – JavaServer Pages Standard Tag Library 29

29

Se l’attributo items è del tipo java.util.Map allora l’oggetto corrente sarà del

tipo java.util.Map.Entry, che ha queste due proprietà:

1. key: la chiave sotto cui l’oggetto è conservato nella Map corrispondente

2. value: il valore che corrisponde a questa chiave

Questo tag supporta anche array di oggetti come pure di tipi primitivi ( che

verranno però convertiti nella classe di oggetti corrispondente (e.g.: int à Integer,

float à Float ); sono utilizzabili anche implementazioni di java.util.Iterator e

java.util.Enumeration, ma bisogna prestare attenzione al fatto che questi oggetti

non possono essere resettati, e bisogna quindi utilizzarli al più all’interno di un

solo tag. Infine è possibile svolgere iterazioni anche su stringhe purché siano nella

forma di elenco separato da virgole.

2.4.4 Tag di supporto agli URL

Nelle specifiche JSP il tag jsp:include permette di includere risorse di tipo sia

statico che dinamico all’interno della pagina, ma presenta dei limiti: i contenuti a

cui si accede devono risiedere nella stessa web application (mentre gli autori

spesso hanno bisogno di importare pagine da un qualsiasi punto di Internet

specificandole per mezzo di un URL assoluto), ed inoltre si rischia di introdurre

dei fenomeni di buffering inutili quando questo tag viene annidato dentro ad altri,

dato che spesso si otterrebbe una elaborazione più efficiente se il tag esterno

potesse accedere direttamente agli oggetti desiderati . I tag introdotti nella JSTL

Tabella 2.5. Tag iteratori

Tag Utilizzo

<c:forEach>

Ripete il contenuto annidato nel body

per ognuno degli oggetti contenuti

nell’insieme indicato, oppure un

numero fissato di volte

<c:forTokens>

Compie un’iterazione su un’insieme di

elementi, separati dai delimitatori

indicati

JSTL – JavaServer Pages Standard Tag Library 30

30

cercano di risolvere questi problemi fornendo un modo semplice e generico per

accedere a risorse basate su URL, il cui contenuto può quindi essere incluso ed

elaborato all’interno della pagina JSP.

L’attributo url permette di specificare l’indirizzo della risorsa da importare, in

una delle seguenti forme:

1. URL assoluto - comincia con l’indicazione del protocollo utilizzato

seguita dal segno :

2. URL relativo con risorsa appartenente al contesto corrente

3. URL relativo con risorsa appartenente ad un contesto diverso

Il comportamento di default dei tag di supporto agli URL contenuti nelle JSTL

non differisce comunque molto da quello di <jsp:include>, dato che anche in

questo caso la risorsa a cui si vuole accedere viene inclusa sa direttamente nella

pagina jsp. Il vantaggio di questa categoria di tag sta invece nella possibilità di

rendere disponibili i contenuti recuperati come oggetti di tipo String (attraverso

l’attributo var) oppure di tipo Reader (attributo varReader) ai tag di elaborazione o

trasformazione; la differenza tra questi due metodi è che mentre il primo effettua

il buffering del contenuto, il secondo consente di accedervi direttamente, anche se

bisogna tenere in considerazione il fatto che il vantaggio in termini di prestazioni

Tabella 2.6. Tag di supporto agli URL

Tag Utilizzo

<c:import> Importa il contenuto di una risorsa

indicata attraverso un URL

<c:url> Costruisce un URL formattandolo

secondo le regole standard

<c:redirect> Invia al client un messaggio HTTP

redirect

<c:param>

Aggiunge parametri per la request ad

un URL; viene annidato in <c:import>,

<c:url> o <c:redirect>

JSTL – JavaServer Pages Standard Tag Library 31

31

dipende dall’implementazione e che l’oggetto restituito è visibile solo agli

elementi annidati nel tag.

In ogni caso quando si utilizzano questi tag bisogna tener presente che se il

server che ospita le pagine JSP è in esecuzione dietro ad un firewall alcune risorse

a cui si vorrebbe accedere attraverso un URL assoluto possono risultare non

disponibili; in questo caso bisogna configurare in maniera opportuna la JVM su

cui gira il server.

2.5 Internationalization tag library Da quando Internet ha cominciato la sua rapidissima crescita, si è reso

necessario adattare il linguaggio e le convenzioni per la formattazione all’interno

delle applicazioni web ai molteplici contesti cui i client che vi accedono possono

appartenere.

Il procedimento con cui si costruisce un’applicazione, strutturandola in modo

da poterla adattare a linguaggi e regioni diversi senza ulteriori modifiche viene

detto internazionalizzazione (in breve i18n). Dopo questa fase l’applicazione può

essere adattata ad un contesto semplicemente aggiungendo elementi locali come

componenti o testi; questo processo prende il nome di localizzazione.

2.5.1 Tag per l’internazionalizzazione (i18n)

Una versione internazionale di un’applicazione viene realizzata basando

l’accesso alle risorse che devono essere localizzate su uno schema che prevede

come elementi chiave i concetti di locale, resource bundle e basename.

Un locale rappresenta una regione specifica (che può essere di diversi tipi,

come ad esempio geografica, culturale o politica), ed è identificato da un codice

linguistico (definito attraverso la normativa ISO-639) e, opzionalmente, da un

codice di paese (normativa ISO-3166).

Un resource bundle contiene l’insieme di oggetti specifici per un determinato

locale; si può accedere ad ogni oggetto presente al suo interno tramite una chiave,

che identifica ciascuno di questi in modo univoco.

JSTL – JavaServer Pages Standard Tag Library 32

32

Se due resource bundle contengono lo stesso insieme di informazioni, riferite

però a due locale diversi, questi condividono lo stesso basename.

Quando il resource bundle per un contesto deve essere determinato, questo

viene recuperato dalle risorse a disposizione dell’applicazione, a seconda del

basename del bundle e del locale preferito.

Il locale può essere impostato sia a livello di applicazione che di browser; nel

primo caso di solito si consente all’utente di scegliere quali impostazioni verranno

applicate, e quindi si settano le variabili all’interno dello scope di conseguenza,

mentre nel secondo è il browser stesso che si preoccupa di fornire all’applicazione

una lista di preferenze ordinata secondo la priorità che queste hanno.

Tabella 2.7. Tag per l’internazionalizzazione (i18n)

Tag Utilizzo

<fmt:setLocale> Salva il locale specificato nella variabile di

configurazione javax.servlet.jsp.jstl.fmt.locale

<fmt:Bundle> Crea un contesto di localizzazione i18n che verrà

usato dal contenuto del suo body

<fmt:setBundle>

Crea un contesto di localizzazione i18n e lo

registra in una variabile all’interno dello scope

oppure in quella di configurazione

javax.servlet.jsp.jstl.fmt.localizationContext

<fmt:message> Ricerca un messaggio localizzato all’interno di un

resource bundle

<fmt:param>

Fornisce un singolo parametro quando ci sia

bisogno di rimpiazzare dei parametri all’interno del

tag <fmt:message> che lo contiene

<fmt:requestEncoding> Setta il tipo di codifica dei caratteri della request

JSTL – JavaServer Pages Standard Tag Library 33

33

Figura 2.1. Schema risorse i18n

Cancella

Acquista

Benvenuto

Registration_it

key

Cancel

Buy

Hello

Registration_en

resource bundle basename locale

2.5.2 Tag per la formattazione

I tag per la formattazione presenti nella JSTL permettono di trasformare

numeri, date, percentuali, prezzi o altri valori in genere secondo le convenzioni

locali o utilizzando regole personalizzate.

Quando si vuole formattare un numero, una percentuale o un prezzo si utilizza

il tag <fmt:formatNumber>, che si preoccupa di applicare al valore fornito le

regole previste dal locale corrente, oppure quelle definite dall’autore, se queste

ultime sono state indicate. Nel caso in cui il numero rappresenti il costo di

qualcosa bisogna tener presente che il tag non effettua la trasformazione secondo i

cambi di valuta vigenti, ma applica soltanto le nuove convenzioni per la

rappresentazione al valore di partenza.

Se risulta necessario localizzare un data o un orario si impiega il tag

<fmt:formatDate>; anche in questo caso è possibile indicare uno stile

personalizzato per la rappresentazione, ed inoltre si può tener conto del fuso orario

del client attraverso il tag <fmt:timeZone> oppure attraverso l’attributo timeZone

all’interno del tag stesso.

JSTL – JavaServer Pages Standard Tag Library 34

34

2.6 XML tag library XML si sta sempre più diffondendo come metodo per rappresentare insiemi di

dati da scambiare, soprattutto in un contesto come Internet, dato che fornisce un

metodo flessibile e standard per trattare valori di qualsiasi forma e tipo; la JSTL

mette per questo a disposizione degli autori di pagine web una serie di strumenti

che permettono di elaborare in maniera semplice i contenuti XML.

Tabella 2.8. Tag per la formattazione

Tag Utilizzo

<fmt:timeZone> Specifica il fuso orario secondo cui il contenuto del

suo body andrà elaborato o formattato

<fmt:setTimeZone>

Setta il fuso orario specificato all’interno di una

variabile in uno degli scope ammessi o in quella

che mantiene la configurazione dei fusi orari

<fmt:formatNumber>

Formatta un valore numerico basandosi sul locale

appropriato o sul formato indicato come numero,

valuta o percentuale

<fmt:parseNumber>

Elabora la stringa che rappresenta il numero, la

valuta o la percentuale dopo che il valore di

partenza è stato formattato secondo le convenzioni

locali o lo stile indicato

<fmt:formatDate> Formatta orari e date basandosi sul locale

appropriato o sul formato indicato

<fmt:parseDate>

Elabora la stringa che rappresenta la data o l’orario

dopo che il valore di partenza è stato formattato

secondo le convenzioni locali o lo stile indicato

JSTL – JavaServer Pages Standard Tag Library 35

35

Uno dei punti fondamentali quando si tratta di manipolare dei contenuti XML

è poter accedere con facilità ai suoi contenuti; su questo argomento esiste una

raccomandazione del W3C sin dal 1999, denominata XPath, che fornisce una

notazione concisa per specificare e selezionare parti di un documento XML; i tag

XML presenti nella JSTL si basano dunque su XPath.

Con XPath viene introdotta una forma di expression language, che espande

quello tipico della JSTL, utilizzata localmente nei tag XML; per permettere ad

entrambi i linguaggi di coesistere sono state stabilite delle regole di integrazione.

Il motore scritto per supportare XPath permette di accedere a tutti gli scope

previsti dalla JSTL, in modo da rendere disponibili i dati dell’applicazione web

anche all’interno di una espressione XPath; è inoltre possibile specificare la fonte

da cui estrarre i dati XML attraverso un oggetto String o Reader generato dal tag

<c:import> a cui venga passato l’URL desiderato.

2.6.1 Tag XML di base

Questo gruppo di tag fornisce una sorta di supporto per l’expression language

quando si utilizza XPath. I tag risultano dunque simili a quelli già visti nella core

tag library, come ad esempio <c:out> e <c:set>, con la differenza che ora ci si

riferisce ad espressioni XPath.

Tabella 2.9. Tag XML di base

Tag Utilizzo

<x:parse> Effettua il parsing di un documento

XML

<x:out>

Valuta un’espressione XPath e ne invia

il risultato all’oggetto JspWriter

corrente

<x:set>

Valuta un’espressione XPath e ne

inserisce il risultato in una variabile

all’interno di uno degli scope ammessi

JSTL – JavaServer Pages Standard Tag Library 36

36

In questa libreria è presente però anche un tag aggiuntivo, <x:parse>, che

elabora un documento XML e ne inserisce il contenuto all’interno di una struttura

che verrà poi passata al motore XPath.

2.6.2 Tag XML per il controllo di flusso

I tag della libreria XML di base consentono di accedere a documenti XML, ma

per poterne analizzare ed elaborare i contenuti bisogna essere in grado di

compiere iterazioni e scelte basate sul valore assunto da espressioni XPath; questo

gruppo di tag rende disponibili gli strumenti necessari a compiere le azioni appena

descritte.

Questa categoria di tag risulta simile a quella presente nella core tag library

(come <c:if>, <c:choose> e <c:forEach>) che consente attraverso l’EL il controllo

del flusso di elaborazione all’interno della pagina JSP, con la differenza che in

questo caso ci si riferisce ad espressioni XPath.

Tabella 2.10. Tag XML per il controllo di flusso

Tag Utilizzo

<x:if>

Valuta l’espressione XPath fornita

dall’attributo select e visualizza il

contenuto del proprio body se questa

assume valore true

<x:choose>

Fornisce il contesto in cui inserire i tag

per generare un’esecuzione di tipo

mutuamente esclusivo

<x:when> Rappresenta un’alternativa all’interno

di un tag <x:choose>

<x:otherwise> Rappresenta il comportamento di

default all’interno di un tag <x:choose>

<x:forEach>

Valuta un’espressione XPath e ripete il

contenuto annidato nel body una volta

per ogni elemento del risultato

JSTL – JavaServer Pages Standard Tag Library 37

37

Il tag <x:if> presenta un parametro chiamato select che specifica il valore di

un’espressione XPath; l’espressione viene valutata e poi convertita in un valore

boolean in modo da consentire al tag di decidere se valutare o meno il suo body.

Il tag <x:choose> permette scegliere quale tra tante opzioni (ognuna racchiusa

in un tag <x:when>) eseguire, eventualmente fornendo un comportamento di

default (col tag <x:otherwise>), quando nessuna delle condizioni precedenti

risultasse verificata.

Il tag <x:forEach>, infine, valuta l’espressione XPath fornita e compie

un’iterazione sul risultato ottenuto.

2.6.3 Tag XML per la trasformazione

In molte applicazioni è comune trasformare i documenti XML applicando dei

fogli di stile XSLT; questi tag permettono di effettuare trasformazioni XSLT

all’interno delle pagine JSP.

In certi casi lo stesso fogli di stile deve essere applicato a più documenti XML;

quando si verifica questa situazione risulta più efficiente elaborare il foglio di stile

una volta all’inizio in modo da creare un oggetto da impiegabile in tutte le

successive trasformazioni.

Tabella 2.11. Tag XML per la trasformazione

Tag Utilizzo

<x:transform>

Applica la trasformazione descritta da

un foglio di stile XSLT ad un

documento XML

<x:param>

Setta i parametri per la trasformazione;

va annidato all’interno di un tag

<x:transform>

JSTL – JavaServer Pages Standard Tag Library 38

38

2.7 SQL tag library Spesso le applicazioni web necessitano di accedere ad un database relazionale

per recuperare i dati necessari alla generazione del contenuto dinamico che verrà

presentato. In generale sarebbe preferibile incapsulare la logica impiegata in

questo tipo di operazioni all’interno di JavaBean, in modo da renderla più

efficiente e semplice da mantenere; possono però presentarsi situazioni in cui è

necessario poter disporre direttamente all’interno della pagina JSP di funzioni in

grado di effettuare manipolazioni su di un database, ad esempio mentre si

realizzano prototipi di un’applicazione, o quando non ci sono tempo o risorse

umane sufficienti ad implementare un sistema di gestione completo.

La JSTL viene incontro a queste necessità mettendo a disposizione degli

sviluppatori la libreria di tag dedicata all’SQL, grazie a cui risulta possibile

eseguire query su di un database, manipolare i risultati che queste producono,

effettuare aggiornamenti ed infine raggruppare un insieme di operazioni in

un’unica transazione.

La prima operazione da compiere quando si intende utilizzare questi tag è

definire la sorgente per i dati a cui si dovrà accedere; per fare ciò si ut ilizza un

oggetto di tipo javax.sql.DataSource, che fornisce una connessione alla sorgente

di dati fisica che rappresenta. Una volta stabilita una Connection verso la

DataSource specificata diventa possibile eseguire al suo interno query SQL e

recuperare i risultati prodotti.

Una sorgente può essere specificata o in modo esplicito attraverso l’attributo

dataSource all’interno dei tag SQL oppure in modo implicito attraverso la

variabile di configurazione javax.servlet.jsp.jstl.sql.dataSource.

Una stringa può indicare una sorgente di dati in due diversi modi:

1. attraverso un percorso JDNI relativo, supponendo che il contenitore

supporti JDNI;

2. indicando i parametri necessari alla classe JDBC DriverManager, che

però pur essendo comoda mentre l’applicazione è allo stato di

prototipo non fornisce tutte quelle funzioni di gestione della

JSTL – JavaServer Pages Standard Tag Library 39

39

connessione che ci si potrebbe aspettare da un oggetto DataSource

progettato correttamente.

Una volta connessi l’operazione più comune che si effettua su di un database è

effettuare una ricerca e mostrarne i risultati, come si può vedere nel listato 2.2.

Quando invece quello che si desidera fare è aggiornare i dati contenuti si può

utilizzare il tag <sql:update>, tenendo conto che è possibile garantire l’integrità

del database nel momento in cui si effettuano diversi aggiornamenti consecutivi

<sql:query var="customers" dataSource="${dataSource}">

SELECT * FROM customers

WHERE country = ’China’

ORDER BY lastname

</sql:query>

<table>

<!-- column headers -->

<tr>

<c:forEach var=”columnName” items=”${result.columnNames}”>

<th>

<c:out value="${columnName}"/>

</th>

</c:forEach>

</tr>

<!-- column data -->

<c:forEach var="row" items="${result.rowsByIndex}">

<tr>

<c:forEach var="column" items="${row}">

<td>

<c:out value="${column}"/>

</td>

</c:forEach>

</tr>

</c:forEach>

</table>

Listato 2.2. Query su un DB e creazione di una tabella contenente il risultato

JSTL – JavaServer Pages Standard Tag Library 40

40

purché questi vengano annidati in un tag <sql:transaction>, come avviene

nell’esempio riportato nel listato 2.3.

Come si può vedere nel listato 2.3 la JSTL supporta l’inserimento di

segnaposto (contrassegnati dal carattere ‘?’) all’interno delle query SQL; questo

tipo di sostituzione viene resa possibile dall’interfaccia SQLExecutionTag, che

viene poi implementata dai tag handler di <sql:query> e <sql:update>. Questa

caratteristica è stata introdotta per permettere a tag personalizzati di recuperare i

parametri da qualsiasi fonte disponibile, elaborarli ed infine sostituirli ai

segnaposto all’interno della query, come potrebbe accadere per una GUI basata su

un’applicazione web. È infine possibile utilizzare i tag di formattazione della

JSTL per trasformare date e numeri in istanze delle classi java.util.Date e

java.lang.Number rispettivamente, prima di passarli all’SQLExecutionTag che li

contiene e che potrà usarli sostituendoli a dei parametri nella query.

<sql:transaction dataSource="${dataSource}">

<sql:update>

UPDATE account

SET Balance = Balance - ?

WHERE accountNo = ?

<sql:param value="${transferAmount}"/>

<sql:param value="${accountFrom}"/>

</sql:update>

<sql:update>

UPDATE account

SET Balance = Balance + ?

WHERE accountNo = ?

<sql:param value="${transferAmount}"/>

<sql:param value="${accountTo}"/>

</sql:update>

</sql:transaction>

Listato 2.3. Transazione contenente aggiornamenti multipli del contenuto un DB

JSTL – JavaServer Pages Standard Tag Library 41

41

Quando i tag <sql:query>, <sql:update> e <sql:transaction> tentano di

accedere ad un database utilizzano l’algoritmo seguente:

- cerca di ottenere il riferimento ad una sorgente di dati come segue:

- se l’attributo dataSource è specificato, usa il suo valore

- altrimenti utilizza (se è diverso da null) il valore di configurazione

associato a javax.servlet.jsp.jstl.sql.dataSource

- se dai passi precedenti si è ottenuto un riferimento valido:

- se questo è un oggetto DataSource, questo sarà la sorge nte di dati

che i tag utilizzeranno per accedere al database

- altrimenti, se è una String:

- assumi che sia un percorso JDNI relativo e recupera la sorgente

di dati dal contesto JDNI del contenitore concatenando il

percorso relativo fornito alla radice definita per la J2EE

(java:comp/env/)

- se il punto precedente non è andato a buon fine assumi che la

stringa specifichi i parametri JDBC secondo la sintassi

url [, [driver][, [user][,password]]]

e in seguito:

- se il driver è specificato, assicurati che sia stato

caricato

- accedi all’URL indicato attraverso la classe

DriverManager, utilizzando una stringa vuota per

user e password se questi non sono stati specificati

- se il punto precedente non è andato a buon fine lancia

un’eccezione

- altrimenti lancia un’eccezione

JSTL – JavaServer Pages Standard Tag Library 42

42

2.7.1 Tag <sql:query>

Questo tag effettua una query sul database indicato, e ammette le sintassi:

1. Senza body

<sql:query sql="sqlQuery"

var="varName" [scope=”{page|request|session|application}”]

[dataSource=”dataSource”]

[maxRows="maxRows"]

[startRow="startRow"]/>

2. Con un body per specificare gli argomenti della query

<sql:query sql="sqlQuery"

var="varName" [scope=”{page|request|session|application}”]

[dataSource=”dataSource”]

[maxRows="maxRows"]

[startRow="startRow"]>

<sql:param> actions

</sql:query>

3. Con un body per specificare la query e degli argomenti opzionali

<sql:query var="varName"

[scope=”{page|request|session|application}”]

[dataSource=”dataSource”]

[maxRows="maxRows"]

[startRow="startRow"]>

query

optional <sql:param> actions

</sql:query>

JSTL – JavaServer Pages Standard Tag Library 43

43

Se dataSource viene specificato il tag non potrà essere annidato all’interno di

<sql:transaction>; maxRows deve essere maggiore o uguale a -1.

Tabella 2.12. Parametri di <sql:query>

Nome Dinamico Tipo Descrizione

sql Vero String Query SQL

dataSource Vero Javax.sql.DataSource

oppure String

Sorgente di dati associata al

database su cui si effettua la

query. Un valore String

rappresenta un percorso

relativo JDNI o i parametri per

la classe DriverManager

maxRows Vero int

Il numero massimo di righe da

includere nel risultato della

query; se non è specificato, o

vale -1, non viene imposto

alcun limite alle dimensioni del

risultato

startRow Vero int

L’oggetto Result ritornato

include le righe a partire

dall’indice specificato. La

prima riga del risultato iniziale

ha indice 0; se non viene

indicato, le righe sono restituita

a partire dalla prima (con

indice 0)

var Falso String

Nome della variabile

contenente il risultato della

query che sarà esportata (di

tipo

javax.servlet.jsp.jstl.sql.Result)

scope Falso String Scope di var

JSTL – JavaServer Pages Standard Tag Library 44

44

Gestione errori:

- se dataSource è null viene lanciata una JspException

- se si verifica un’eccezione durante l’esecuzione di questo tag, questa deve

essere catturata e rilanciata come JspException. Il messaggio della

JspException che viene rilanciata deve contenere il testo della query, e

l’eccezione catturata deve essere indicata come root cause.

Il tag <sql:query> interroga un database e restituisce un unico oggetto

contenente le righe di dati che salva nella variabile identificata dagli attributi var e

scope. Se la query (che può essere specificata attraverso l’attributo sql o nel body)

non produce risultati l’oggetto Result restituito sarà di dimensioni nulle; al suo

interno sono ammessi segnaposto per dei parametri (indicati dal simbolo ‘?’) di

tipo JDBC preparedStatement, i cui valori devono essere forniti da tag annidati

(come <sql:param>). Il tag <sql:query> implementa l’interfaccia

SQLExecutionTag, permettendo così di assegnare i valori ai parametri

eventualmente presenti nella query attraverso dei tag personalizzati.

Il numero massimo di righe restituite dalla query può essere specificato o

attraverso il parametro maxRows di <sql:query> (che ha la precedenza) oppure

attraverso la variabile javax.servlet.jsp.jstl.sql.maxRows; attraverso l’attributo

startRow è invece possibile determinare a partire da quale riga saranno disponibili

i risultati (i.e. se si ha startRow=n i primi n-1 risultati saranno scartati).

Utilizzando in modo congiunto gli attributi startRow e maxRows è possibile

determinare una “finestra” che seleziona un sottoinsieme dei risultati della query,

utile ad esempio per suddividerli in pagine quando questi siano in numero elevato.

Se <sql:query> è annidato in un tag <sql:transaction> questo si preoccupa di

gestire l’accesso al database e di fornire al tag figlio l’oggetto Connection,

altrimenti l’accesso al database è effettuato secondo la procedura descritta in

precedenza : l’oggetto Connection viene ottenuto e poi rilasciato prima che il tag

completi la sua elaborazione.

JSTL – JavaServer Pages Standard Tag Library 45

45

2.7.2 Tag <sql:update>

Questo tag esegue istruzioni SQL del tipo INSERT, UPDATE o DELETE, ed

inoltre permette l’esecuzione di istruzioni, come quelle SQL DDL, che non

restituiscono nulla. Le sintassi ammesse sono:

1. Senza body

<sql:update sql="sqlUpdate"

[dataSource=”dataSource”]

[var="varName"] [scope=”{page|request|session|application}”]/>

2. Con body per specificare gli argomenti

<sql:update sql="sqlUpdate"

[dataSource=”dataSource”]

[var="varName"] [scope=”{page|request|session|application}”]>

Tabella 2.13. Parametri di <sql:update>

Nome Dinamico Tipo Descrizione

sql Vero String Operazione SQL da eseguire

dataSource Vero Javax.sql.DataSource

oppure String

Sorgente di dati associata al

database su cui si effettua la

query. Un valore String

rappresenta un percorso

relativo JDNI o i parametri per

la classe DriverManager

var Falso String

Nome della variabile

contenente il risultato

dell’operazione che verrà

esportata (di tipo

java.lang.Integer)

scope Falso String Scope di var

JSTL – JavaServer Pages Standard Tag Library 46

46

<sql:param> actions

</sql:update>

3. Con body per specificare l’operazione da eseguire e argomenti opzionali

<sql:update [dataSource=”dataSource”]

[var="varName"] [scope=”{page|request|session|application}”]>

update statement

optional <sql:param> actions

</sql:update>

Se scope viene specificato tra i parametri, dovrà esserlo anche var; anche

questo tag, come <sql:query>, non può essere annidato all’interno di

<sql:transaction> se l’attributo dataSource è stato specificato.

Gestione errori:

- se dataSource è null viene lanciata una JspException

- se si verifica un’eccezione durante l’esecuzione di questo tag, questa deve

essere catturata e rilanciata come JspException. Il messaggio della

JspException che viene rilanciata deve contenere il testo della query, e

l’eccezione catturata deve essere indicata come root cause.

L’operazione SQL da eseguire può venire specificata nell’attributo sql o nel

body del tag; al suo interno sono ammessi segnaposto per dei parametri (indicati

dal simbolo ‘?’) di tipo JDBC preparedStatement, i cui valori devono essere

forniti da tag annidati (come <sql:param>). Il tag <sql:update> implementa

l’interfaccia SQLExecutionTag, permettendo così di assegnare i valori ai

parametri eventualmente presenti nell’operazione attraverso dei tag personalizzati.

La connessione al database si ottiene allo stesso modo descritto per il tag

<sql:query>. Il risultato dell’operazione viene salvato nella variabile indicata

dall’attributo var, se questo è stato specificato; questo risultato rappresenta il

numero di righe interessate dall’aggiornamento, e assume valore zero se nessuna

riga è stata modificata, o se è stata compiuta un’azione (come quelle del tipo SQL

DDL) che non restituisce alcun valore.

JSTL – JavaServer Pages Standard Tag Library 47

47

2.7.3 Tag <sql:transaction>

Questo tag fornisce un contesto per eseguire all’interno di un’unica

transazione i tag <sql:query> e <sql:update> annidati. La sintassi è:

<sql:transaction [dataSource=”dataSource”]

[isolation=isolationLevel]>

<sql:query> and <sql:update> statements

</sql:transaction>

L’attributo isolation può assumere i valori “read_committed”,

“read_uncommitted”, “repeatable_read” e “serializable”.

I tag <sql:query> e <sql:update> annidati al suo interno non devono

specificare alcun valore per l’attributo dataSource.

Gestione errori:

- se DataSource è null viene lanciata un’eccezione JspException

Tabella 2.14. Parametri di <sql:transaction>

Nome Dinamico Tipo Descrizione

dataSource Vero Javax.sql.DataSource

Oppure String

Sorgente di dati associata al

database su cui si effettua la

query. Un valore String

rappresenta un percorso

relativo JDNI o i parametri per

la classe DriverManager

isolation Vero String

Livello di isolamento della

transazione. Se non viene

specificato viene usato quello

per cui è tata configurata la

DataSource

JSTL – JavaServer Pages Standard Tag Library 48

48

- ogni eccezione occorsa durante l’esecuzione di questo tag deve essere

catturata e rilanciata una volta che sia stato effettuato il rollback della

transazione

Il tag <sql:transaction> raggruppa i tag <sql:query> e <sql:update> annidati al

suo interno in un’unica transazione, il cui livello di isolamento è definito da

java.sql.Connection; il suo tag handler deve compiere le seguenti operazioni

durante il suo ciclo di vita:

- doStartTag():

- determina il livello di isolamento su cui è impostato il DBMS (usando

il metodo di Connection getTransactionIsolation()).

Se le transazioni non sono supportate (ovvero se il livello di

isolamento è settato a TRANSACTION_NONE) viene lanciata

un’eccezione, che fa fallire la transazione. Per ogni altro valore la

modalità auto-commit viene salvata (in modo da poter essere

ripristinata in seguito) e poi disabilitata chiamando

setAutoCommit(false) su Connection;

- se l’attributo isolation è stato specificato ed è differente da quello

corrente per la connessione questo viene salvato e poi modificato con il

metodo setTransactionIsolation() di Connection.

- doEndTag(): chiama il metodo commit() di Connection.

- doCatch(): chiama il metodo rollback() di Connection.

- doFinally():

- se era stato salvato un livello di isolamento per la transazione lo

ripristina utilizzando il metodo setTransactionIsolation() di

Connection;

- riporta la modalità auto-commit al valore di partenza chiamando il

metodo setAutoCommit() di Connection;

- chiude la connessione.

JSTL – JavaServer Pages Standard Tag Library 49

49

L’oggetto Connection è ottenuto e gestito allo stesso modo descritto per

<sql:query> con la differenza che in questo caso non può essere mai generato da

un tag in cui <sql:transaction> sia inserito. Va notato che le azioni di commit e

rollback sono effettuate chiamando i metodi commit() e rollback() di Connection,

e non con i comandi SQL corrispondenti (e.g. <sql:update sql=”rollback” />).

2.7.4 Tag <sql:setDataSource>

Esporta una sorgente di dati come variabile oppure setta in modo opportuno la

configurazione accessibile tramite javax.servlet.jsp.jstl.sql.dataSource. La sintassi

è:

<sql:setDataSource

{dataSource="dataSource" |

url="jdbcUrl"

[driver="driverClassName"]

[user="userName"]

[password="password"]}

[var="varName"]

[scope=”{page|request|session|application}”]/>

Se dataSource è null viene lanciata una JspException. Quando l’attributo var

viene specificato il tag <sql:setDataSource> esporta la sorgente di dati specificata

(come un oggetto DataSource oppure come String) come variabile in uno degli

scope, altrimenti questa viene inserita all’interno di

javax.servlet.jsp.jstl.sql.dataSource.

La sorgente di dati può essere specificata o attraverso l’attributo dataSource

(come oggetto DataSource, un percorso relativo JDNI o una stringa contenente i

parametri JDBC) oppure assegnando i valori opportuni ai quattro parametri

JDBC, che sono stati previsti per fornire un’alternativa pratica alla stringa di

configurazione JDBC già descritta.

JSTL – JavaServer Pages Standard Tag Library 50

50

Come è già stato sottolineato in precedenza, la classe JDBC DriverManager va

utilizzata per accedere ad un database solo se l’applicazione è ancora allo stato di

prototipo, vista l’assenza di caratteristiche per la gestione della connessione

complete.

Tabella 2.15. Parametri di <sql:setDataSource>

Nome Dinamico Tipo Descrizione

dataSource Vero Javax.sql.DataSource

Oppure String

Sorgente di dati associata al

database su cui si effettua la

query. Un valore String

rappresenta un percorso

relativo JDNI o i parametri per

la classe DriverManager

driver Vero String Parametro JDBC: nome della

classe del driver

url Vero String Parametro JDBC: URL

associato col database

user Vero String

Parametro JDBC: utente a

nome di cui si effettua la

connessione

password Vero String Parametro JDBC: password

dell’utente

var Falso String

Nome della variabile che sarà

esportata contenente la

sorgente dati specificata; può

essere di tipo String o

DataSource

scope Falso String

Se var è specificata contiene lo

scope della variabile esportata,

altrimenti quello settato nella

configurazione

JSTL – JavaServer Pages Standard Tag Library 51

51

2.7.5 Tag <sql:param>

Questo tag setta il valore per i segnaposto inseriti nelle query SQL; va

annidato all’interno di <sql:query> o <sql:update>. Ammette due tipi di sintassi:

1. Il valore viene specificato nell’attributo value

<sql:param value=”value”/>

2. Il valore viene specificato nel body

<sql:param>

parameter value

</sql:param>

Il tag deve essere inserito all’interno del body di un tag il cui handler sia

un’istanza di SQLExecutionTag.

Gestione errori:

- se value assume valore null il parametro assume il valore SQL di NULL

Il tag <sql:param> sostituisce il valore del parametro indicato al segnaposto

presente all’interno della query indicata nel tag che lo contiene; i parametri

vengono sostituiti nell’ordine in cui appaiono.

2.7.6 Tag <sql:dateParam>

Questo tag setta il valore per i segnaposto inseriti nelle query SQL per valori

del tipo java.util.Date; va annidato all’interno di <sql:query> o <sql:update>.

Ammette la sintassi:

<sql:dateParam value=”value” type=”[timestamp|time|date]”/>

Tabella 2.16. Parametri di <sql:param>

Nome Dinamico Tipo Descrizione

value Vero Object Valore del parametro

JSTL – JavaServer Pages Standard Tag Library 52

52

Il tag deve essere inserito all’interno del body di un tag il cui handler sia

un’istanza di SQLExecutionTag.

Gestione errori:

- se value assume valore null il parametro assume il valore SQL di NULL

Questo tag converte l’oggetto java.util.Date fornito in uno tra java.sql.Date,

java.sql.Time o java.sql.Timestamp come indicato dall’attributo type secondo

questi criteri:

- se l’oggetto java.util.Date fornito dall’attributo value è un’istanza di

java.sql.Time, java.sql.Date o java.sql.Timestamp, e l’attributo type

corrisponde al tipo dell’oggetto, allora viene passato così com’è al

database;

- altrimenti, l’oggetto è convertito nel tipo appropriato chiamandone il

costruttore con parametro date.getTime(), dove date è il valore

dell’attributo value.

Il tag <sql:dateParam> sostituisce il valore del parametro indicato al

segnaposto presente all’interno della query indicata nel tag che lo contiene; i

parametri vengono sostituiti nell’ordine in cui appaiono.

Tabella 2.17. Parametri di <sql:dateParam>

Nome Dinamico Tipo Descrizione

value Vero Object Valore del parametro

type Vero String Uno tra “date”, “time” o

“timestamp”

Miglioramenti alla gestione dei database via JSTL 53

Capitolo 3

Miglioramenti alla

gestione dei database via

JSTL

Questo capitolo tratta della realizzazione e dell’utilizzo del tag <sql:view>.

3.1 Contesto di partenza e specifiche che definiscono JSP 1.1 hanno introdotto una utilissima

caratteristica, quella di poter definire dei tag personalizzati. Questa

possibilità consente di gestire elaborazioni anche complesse

incapsulandole all’interno di un tag, consentendo così di soddisfare anche le

esigenze più particolari senza appesantire la sintassi della pagina JSP finale.

Per rendere possibile la gestione di un certo numero di tag è stata anche

prevista la possibilità di raggrupparli in librerie, le cosiddette tag library.

L

Miglioramenti alla gestione dei database via JSTL 54

54

Una delle tag library di maggiore importanza è senz’altro la JSTL, descritta

nel capitolo precedente. Come si è potuto vedere all’interno di questa libreria è

previsto un insieme di tag che consentono di accedere a database relazionali; una

delle operazioni che si esegue più spesso in questo contesto è l’interrogazione del

database e la visualizzazione in forma di tabella del risultato: i tag dedicati

all’SQL della JSTL naturalmente permettono di eseguire delle query, ma la fase di

rappresentazione dei dati ottenuti diventa difficoltosa dal momento che non esiste

alcun tag che produca in maniera automatica un output formattato inseribile

direttamente all’interno del documento finale; vengono invece restituiti oggetti da

cui i risultati vanno estratti e visualizzati.

L’idea che ha portato alla realizzazione di un tag aggiuntivo, da inserire nella

JSTL, è stata quella di mettere a disposizione dei designer uno strumento che

permetta di ottenere in modo automatizzato un output grafico personalizzabile

(tramite fogli di stile) e dotato di funzionalità di navigazione a partire da una

query diretta ad un database.

3.2 Realizzazione di una libreria di tag

personalizzata Per poter produrre ed utilizzare dei tag JSP personalizzati bisogna definire tre

componenti distinti: la classe che definisce il comportamento dei tag (tag handler),

il file che associa i nomi degli elementi XML presenti nella pagina JSP

all’implementazione dei tag (tag library descriptor, abbreviato in TLD) e,

naturalmente, una pagina JSP che faccia uso della libreria appena creata.

3.2.1 Il tag handler

Quando si crea un nuovo tag la prima operazione da compiere è definire la

classe che il sistema dovrà richiamare quando lo incontrerà all’interno di una

pagina JSP; questa classe deve implementare l’interfaccia

Miglioramenti alla gestione dei database via JSTL 55

55

javax.servlet.jsp.tagext.Tag: di solito questo si ottiene estendendo le classi

TagSupport o BodyTagSupport.

3.2.2 Il tag library descriptor

Una volta scritto il tag handler bisogna inserire questa classe nel server e

associarla con un particolare nome di tag espresso secondo la sintassi XML.

Questo compito è assolto dal tag library descriptor, un file scritto in XML che

contiene alcune informazioni fisse, un prefisso arbitrario per la libreria appena

creata, una breve descrizione della libreria stessa ed infine una serie di

informazioni sui tag che questa contiene.

3.2.3 Il file JSP

Una volta create le classi di implementazione e il tag library descriptor si può

scrivere una pagina JSP che utilizzi il nuovo tag. In qualche punto prima

dell’inizio del tag va inserita la direttiva taglib, che ha la forma seguente:

<% taglib uri=” … “ prefix=” … “ %>

dove l’attributo uri (richiesto) deve essere un URL (assoluto o relativo) che punti

al file che funge da tag library descriptor, e l’attributo prefix (obbligatorio

anch’esso) specifica il prefisso da utilizzare davanti a ciascuno dei nomi dei tag

definiti all’interno del tag library descriptor.

3.3 Realizzazione del tag <sql:view> Basandosi sul meccanismo di estensione proprio della tecnologia JSP è stato

possibile realizzare il tag aggiuntivo <sql:view> per la libreria JSTL; in pratica si

è partiti da un’analisi del problema, per poi passare alla definizione degli obiettivi

e alla stesura del codice secondo le fasi appena descritte.

Il nuovo tag doveva presentare le seguenti caratteristiche:

1. consentire l’esecuzione di query SQL specificate sia attraverso i suoi

parametri che mediante il body;

2. fornire un output grafico personalizzabile che rappresentante i risultati

della query;

Miglioramenti alla gestione dei database via JSTL 56

56

3. consentire la suddivisione dei risultati in “pagine” di dimensione fissata

dal designer dell’applicazione web, in modo da rendere semplice la

consultazione anche in presenza di un numero elevato di elementi da

visualizzare;

4. permettere di riordinare i risultati in modo crescente o decrescente

rispetto a una qualsiasi delle colonne presenti;

5. accettare la presenza di più tabelle all’interno della stessa pagina,

mantenendo lo stato e l’aspetto di ciascuna indipendente da tutte le

altre.

Per soddisfare i punti elencati si è deciso di strutturare il tag in modo che una

volta eseguita la query questo disegnasse una tabella formattata basandosi su di un

foglio di stile passato come parametro, contenente i primi n (con n deciso

dall’utilizzatore del tag) risultati e permettendo l’accesso ai restanti, n per volta,

mediante pulsanti di navigazione; sono stati poi previsti dei pulsanti anche in cima

ad ogni colonna per riordinare i risultati. Per mantenere le tabelle eventualmente

presenti in contemporanea sulla stessa pagina indipendenti tra loro a ciascuna

viene assegnato (a cura di chi impiega il tag) un id unico.

Stabilite in questo modo le caratteristiche fondamentali del tag si è potuti

passare alla realizzazione vera e propria.

3.3.1 Il tag handler di <sql:view>

La prima azione compiuta dal nuovo tag deve essere una query SQL diretta ad

un database relazionale, esattamente come avviene in <sql:query>, che è stato

quindi assunto come base naturale da cui partire per fornire tutte le caratteristiche

desiderate.

Il tag <sql:query> restituisce, una volta eseguita l’interrogazione, un oggetto

del tipo Result contenente i dati richiesti; il tag <sql:view> deve quindi generare

un oggetto dello stesso tipo mediante un procedimento analogo, estraendo quindi

in modo ciclico i risultati ed inserendoli all’interno di una tabella HTML (in cui i

tag <table>, <tr>, <th> e <td> riportano tutti come attributo class il nome del

foglio di stile passato al tag), da inviare poi in output mediante una chiamata a

pageContext.getOut.print().

Miglioramenti alla gestione dei database via JSTL 57

57

Come si vede la visualizzazione in sé risulta piuttosto semplice, mentre sono le

funzionalità avanzate di navigazione e consultazione rese disponibili che hanno

richiesto lo sviluppo di un sistema che potesse tener traccia dello stato di ciascuna

tabella presente nella pagina JSP. Il problema è stato risolto inserendo nella

request una coppia nome-valore per ciascuna tabella che contenesse tutte le

informazioni necessarie ad una corretta rappresentazione, e dei bottoni che

modificassero in modo opportuno questi parametri prima di forzare un reload, con

conseguente aggiornamento del contenuto, della pagina stessa.

I parametri della request inseriti hanno tutti questa struttura:

[sqlViewTable{id_tabella}=P{numero_pagina}

--C{nome_colonna_per_l’ordinamento}

--N{numero_colonna_per_l’ordinamento}

--O{tipo_ordinamento}]

Il significato di ciascun parametro è il seguente:

id_tabella: intero che identifica in modo univoco la tabella all’interno della

pagina;

numero_pagina: intero che indica la pagina di risultati da mostrare;

nome_colonna_per_l’ordinamento: stringa che indica il nome della colonna che

verrà utilizzata per ordinare i risultati;

numero_colonna_per_l’ordinamento: intero che indica il numero della colonna

che verrà utilizzata per ordinare i risultati;

tipo_ordinamento: intero che indica se i risultati saranno ordinati in modo

crescente o decrescente.

Esposti i principi di funzionamento dell’handler del tag <sql:view>, si può

passare ad analizzare nel dettaglio le funzioni che lo compongono.

doStartTag()

Miglioramenti alla gestione dei database via JSTL 58

58

La prima azione effettuata all’interno di questo metodo è controllare che il

parametro maxRows (indicante il numero massimo di righe contenenti i risultati

della query che potrà essere restituito) sia valido, o che per lo meno esista un

valore di default all’interno del contesto corrente; se queste condizioni non sono

soddisfatte viene lanciata un’eccezione.

Il passo successivo è cercare di ottenere una connessione al database

specificato, lanciando un’eccezione in caso di fallimento; una volta fatto ciò la

funzione termina ritornando come valore EVAL_BODY_BUFFERED, indicando

quindi al motore JSP di analizzare il contenuto del body del tag.

doEndTag()

Questo metodo per prima cosa recupera i parametri presenti nella request

diretta alla pagina e li analizza, controllando se tra questi qualcuno si riferisce al

tag a cui è collegata la classe; in caso affermativo lo utilizza per configurare in

modo opportuno le variabili interne che definiscono l’output da produrre,

altrimenti assegna a queste dei valori di default. Tutti gli altri parametri, non

indirizzati alla classe, verranno inseriti senza alcuna elaborazione nelle request

eventualmente prodotte da un reload della pagina innescato da uno dei pulsanti di

navigazione generati all’interno della tabella stessa, in modo da evitare ogni

interferenza tra la tabella corrente e gli altri oggetti che potrebbero essere presenti

nella pagina.

Dopo aver inizializzato le variabili necessarie si procede generando la query

che andrà poi inviata al database; questa può essere creata a partire da uno dei

parametri del tag o dal contenuto del body, aggiungendo eventualmente in fondo

la clausola ORDER BY seguita dal nome della colonna secondo cui si vogliono

ordinare i risultati e quindi da DESC se l’ordinamento deve essere decrescente.

Una volta che si è ottenuto l’oggetto Result contenente i dati da visualizzare

bisogna decidere quale sarà la parte che verrà poi inserita nella tabella. Per

conoscere il numero della riga da cui partire ad estrarre i risultati e quello della

riga in cui fermarsi si usano in generale le seguenti formule:

prima_riga = numero_pagina_corrente * numero_righe_per_pagina

Miglioramenti alla gestione dei database via JSTL 59

59

ultima_riga = prima_riga + numero_righe_per_pagina -1

Va comunque tenuto presente che vengono gestiti in modo appropriato anche i

casi particolari in cui le righe da visualizzare vanno calcolate in modo diverso,

come ad esempio quando numero_righe_per_pagina risulta maggiore del numero

di risultati totale disponibile.

A questo punto si è in grado di disegnare la tabella vera e propria, con una

serie di chiamate a pageContext.getOut.print(); i pulsanti che permettono la

navigazione attraverso le pagine in cui sono divisi i risultati e il loro riordino

vengono inseriti all’interno di elementi <form>, al cui interno sono previsti anche

tanti tag del tipo <input>, di tipo “hidden” contenenti i parametri da passare alla

request generata nel momento in cui al form viene dato il comando di inviare il

suo contenuto.

Nel caso in cui l’operazione di disegno della tabella non vada a buon fine

viene sollevata un’eccezione, altrimenti la funzione termina restituendo

EVAL_PAGE, che indica al contenitore JSP di analizzare anche il contenuto del

resto della pagina.

doCatch()

Semplicemente viene catturato un oggetto Throwable e rilanciato in modo che

possa essere gestito in una delle classi di livello superiore.

doFinally()

Prima di terminare l’elaborazione viene chiusa la connessione aperta all’inizio,

a meno che il tag non sia inserito in una transazione, nel qual caso la si lascia in

vita.

Miglioramenti alla gestione dei database via JSTL 60

60

3.3.2 Le classi di supporto alle sintassi EL e RT

La libreria JSTL come visto prevede il supporto all’EL oltre che all’RT; in

entrambi i casi per permettere un corretto funzionamento del tag bisogna creare

due classi che estendano quella, appena descritta, che funge da tag handler.

La classe relativa all’EL prevede una serie di funzioni del tipo setxxx , dove xxx

indica il nome di uno dei parametri presenti all’interno del tag; in ogni funzione si

assegna ad un parametro la stringa passata dal motore JSP come argomento; la

funzione doStartTag() inoltre viene estesa in modo da analizzare tutti i parametri

appena ottenuti e da trasformarne il tipo (tramite una chiamata ad

ExpressionEvaluatorManager.evaluate()) per poi copiarli in quelli previsti dal tag

handler originale.

La classe per l’RT non fa altro che accettare, sempre mediante funzioni del

tipo setxxx i dati forniti dal motore JSP e copiarli all’interno degli attributi

opportuni presenti nella classe base senza però modificarli in alcun modo, a

differenza di quanto avviene nella libreria gemella.

Miglioramenti alla gestione dei database via JSTL 61

61

...

<required>false</required>

<rtexprvalue>false</rtexprvalue>

</attribute>

</tag>

<<ttaagg>>

<<nnaammee>>vviieeww<<//nnaammee>>

<<ttaagg--ccllaassss>>oorrgg..aappaacchhee..ttaagglliibbss..ssttaannddaarrdd..ttaagg..eell..ssqqll..VViieewwTTaagg<<//ttaagg--ccllaassss>>

<<bbooddyy--ccoonntteenntt>>JJSSPP<<//bbooddyy--ccoonntteenntt>>

<<ddeessccrriippttiioonn>>

EExxeeccuutteess tthhee SSQQLL qquueerryy ddeeffiinneedd iinn iittss bbooddyy oorr tthhrroouugghh tthhee

ssqqll aattttrriibbuuttee aanndd pprriinnttss oouutt tthhee rreessuullttiinngg ttaabbllee pprroovviiddiinngg nnaavviiggaattiioonn

ffaacciilliittiieess..

<<//ddeessccrriippttiioonn>>

<<aattttrriibbuuttee>>

<<nnaammee>>vvaarr<<//nnaammee>>

<<rreeqquuiirreedd>>ttrruuee<<//rreeqquuiirreedd>>

<<rrtteexxpprrvvaalluuee>>ffaallssee<<//rrtteexxpprrvvaalluuee>>

<<ttyyppee>>SSttrriinngg<<//ttyyppee>>

<<//aattttrriibbuuttee>>

......

<<aattttrriibbuuttee>>

<<nnaammee>>rroowwssPPeerrPPaaggee<<//nnaammee>>

<<rreeqquuiirreedd>>ffaallssee<<//rreeqquuiirreedd>>

<<rrtteexxpprrvvaalluuee>>ttrruuee<<//rrtteexxpprrvvaalluuee>>

<<ttyyppee>>iinntt<<//ttyyppee>>

<<//aattttrriibbuuttee>>

<<//ttaagg>>

<tag>

<name>update</name>

<tag-class>org.apache.taglibs.standard.tag.el.sql.UpdateTag</tag-class>

...

Listato 3.1. Esempio delle modifiche apportate a sql.tld

3.3.3 Il tag library descriptor di <sql:view>

Anche in questo caso, come per il tag handler, la base da cui si è partiti è stata

quella del tag <sql:query>, o meglio della libreria cui questo appartiene. I file

interessati sono sql.tld e sql-rt.tld, in cui si sono dovute aggiungere delle sezioni

che descrivessero il tag appena aggiunto, i parametri da questo accettati e le classi

preposte alla sua gestione, come si può vedere nei listati 3.1 e 3.2.

Miglioramenti alla gestione dei database via JSTL 62

62

...

<required>false</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>

<<ttaagg>>

<<nnaammee>>vviieeww<<//nnaammee>>

<<ttaagg--ccllaassss>>oorrgg..aappaacchhee..ttaagglliibbss..ssttaannddaarrdd..ttaagg..rrtt..ssqqll..VViieewwTTaagg<<//ttaagg--ccllaassss>>

<<bbooddyy--ccoonntteenntt>>JJSSPP<<//bbooddyy--ccoonntteenntt>>

<<ddeessccrriippttiioonn>>

EExxeeccuutteess tthhee SSQQLL qquueerryy ddeeffiinneedd iinn iittss bbooddyy oorr tthhrroouugghh tthhee

ssqqll aattttrriibbuuttee aanndd pprriinnttss oouutt tthhee rreessuullttiinngg ttaabbllee pprroovviiddiinngg nnaavviiggaattiioonn

ffaacciilliittiieess..

<<//ddeessccrriippttiioonn>>

<<aattttrriibbuuttee>>

<<nnaammee>>vvaarr<<//nnaammee>>

<<rreeqquuiirreedd>>ttrruuee<<//rreeqquuiirreedd>>

<<rrtteexxpprrvvaalluuee>>ffaallssee<<//rrtteexxpprrvvaalluuee>>

<<ttyyppee>>SSttrriinngg<<//ttyyppee>>

<<//aattttrriibbuuttee>>

......

<<aattttrriibbuuttee>>

<<nnaammee>>rroowwssPPeerrPPaaggee<<//nnaammee>>

<<rreeqquuiirreedd>>ffaallssee<<//rreeqquuiirreedd>>

<<rrtteexxpprrvvaalluuee>>ttrruuee<<//rrtteexxpprrvvaalluuee>>

<<ttyyppee>>iinntt<<//ttyyppee>>

<<//aattttrriibbuuttee>>

<<//ttaagg>>

<tag>

<name>update</name>

<tag-class>org.apache.taglibs.standard.tag.rt.sql.UpdateTag</tag-class>

...

Listato 3.2. Esempio delle modifiche apportate a sql-rt.tld

3.3.4 La pagina JSP di prova

Per poter utilizzare il tag <sql:view> si deve procedere come per qualsiasi

altro tag presente nella JSTL: all’inizio della pagina va dichiarata l’intenzione di

impiegare la libreria tramite la direttiva taglib:

<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>

Miglioramenti alla gestione dei database via JSTL 63

63

<<%%@@ ttaagglliibb pprreeffiixx==""ssqqll"" uurrii==""hhttttpp::////jjaavvaa..ssuunn..ccoomm//jjssttll//ssqqll"" %%>>

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

<html>

<head>

<title>sql:view tag</title>

...

<sql:setDataSource

var="example"

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/javatest"

user="javauser"

password="javadude"/>

...

<sql:transaction dataSource="${example}">

<sql:update var="newTable">

create table mytable(

nameid int primary key,

name varchar(80),

rating int)

</sql:update>

...

<sql:update var="updateCount">

INSERT INTO mytable VALUES (1,'Foo',8)

</sql:update>

...

<<ssqqll::vviieeww vvaarr==""rreessuulltt"" bboorrddeerr==""11"" ccssssCCllaassss==""ttaabbeellllaa11"" ttaabblleeIIDD==""1133"" rroowwssPPeerrPPaaggee==""22"">>

SSEELLEECCTT ** FFRROOMM mmyyttaabbllee

<<//ssqqll::vviieeww>>

</sql:transaction>

Listato 3.3. Esempio di utilizzo del tag <sql:view>

bisogna poi indicare a quale database ci si dovrà connettere col tag

<sql:setDataSource>, eventualmente modificare una tabella tramite i tag

<sql:transaction> e <sql:update> ed infine eseguire su di essa una query col tag

<sql:view>, come è mostrato nel listato 3.3.

Miglioramenti alla gestione dei database via JSTL 64

64

3.4 I componenti di <sql:view> Il tag descritto in queste pagine è stato creato in modo da poter essere integrato

all’interno della libreria JSTL, i cui file risulterebbero così in parte modificati; in

particolare, risulterebbero aggiornati (com’è ovvio) sia il codice sorgente che la

versione compilata.

3.4.1 Modifiche al codice sorgente della JSTL

File aggiunti:

org.apache.taglibs.standard.tag.common.sql.ViewTagSupport.java

File contenente le routine principali che implementano il funzionamento del tag

<sql:view>, descritto nel paragrafo 3.3.1.

org.apache.taglibs.standard.tag.el.sql.ViewTag.java

File contenente la logica necessaria per fornire il supporto all’EL, descritto nel

paragrafo 3.3.2.

org.apache.taglibs.standard.tag.rt.sql.ViewTag.java

File contenente la logica necessaria per fornire il supporto all’RT, descritto nel

paragrafo 3.3.2.

Miglioramenti alla gestione dei database via JSTL 65

65

File modificati:

sql.tld

File contenente i descrittori per i tag di tipo sql con supporto all’EL presenti nella

JSTL, esteso secondo quanto specificato nel paragrafo 3.3.3

sql-rt.tld

File contenente i descrittori per i tag di tipo sql con supporto all’RT presenti nella

JSTL, esteso secondo quanto specificato nel paragrafo 3.3.3

3.4.2 Modifiche ai file binari della JSTL

Una volta compilata la JSTL produce una serie di archivi jar da installare nel

server. Di questi risulta modificato soltanto standard.jar, a cui vengono aggiunte le

classi:

org/apache/taglibs/standard/tag/common/sql/ViewTagSupport.class

org/apache/taglibs/standard/tag/el/sql/ViewTag.class

org/apache/taglibs/standard/tag/ rt/sql/ViewTag.class

e in cui vengono modificati i file:

META-INF/sql.tld

META-INF/sql-rt.tld

Conclusioni 66

Conclusioni

La grande importanza che al giorno d’oggi rivestono i servizi basati sul web ha

portato a notevoli investimenti economici in questo campo, e alla richiesta di

figure professionali specializzate che siano in grado di seguire con competenza le

varie fasi che portano alla realizzazione di un prodotto competitivo.

Questa filosofia di produzione porta a strutturare le applicazioni in strati

indipendenti tra loro, e ad utilizzare tecnologie che rendano questo processo il più

diretto possibile.

Come si è potuto vedere JavaServer Pages, in particolare quando viene

impiegata assieme alla JSTL, risulta molto indicata quando si vogliono separare le

fasi di presentazione e di elaborazione in una applicazione web; questa sua

caratteristica la rende adatta sia alla realizzazione di progetti complessi sia

all’impiego nel caso di prototipi. In questo ultimo campo diventa importante poter

disporre di elementi che producano output anche abbastanza elaborati senza che

sia necessario ricorrere a linguaggi e costrutti sintattici che, pur permettendo una

notevole potenza e flessibilità, richiedono conoscenze e tempo per essere

impiegati in modo proficuo, risorse, queste, che, per la stessa natura

dell’applicazione che si sta realizzando, spesso non sono disponibili.

Il tag <sql:view>, sviluppato come estensione per la sezione dedicata all’SQL

della libreria JSTL, fornisce un utile supporto quando si tratta di gestire l’accesso

al contenuto di un database, dato che crea in modo automatico all’interno della

pagina web in cui viene inserito una tabella che, oltre a formattare i dati recuperati

dal database secondo quanto previsto dal designer, fornisce anche la possibilità di

navigare al loro interno e di riordinarli, il tutto con una sintassi di tipo XML.

Conclusioni 67

67

Il risultato è quindi la possibilità di creare semplici applicazioni web in grado

di dialogare con basi di dati, richiedendo all’autore soltanto la conoscenza

dell’HTML e una certa dimestichezza con la tecnologia JSP, abilità, queste, molto

spesso possedute da grafici e designer, dai quali, dunque, non dovrà più essere

preteso anche di padroneggiare linguaggi di programmazione come il Java per

poter esprimere al meglio la propria creatività.

Glossario 68

Glossario

ADO, ActiveX ® Data Objects , tecnologia che permette ad un client di gestire ed

accedere ai dati contenuti in un server di database.

API, Application Programming Interface, set di comandi che un’applicazione

utilizza per richiedere e portare a termine servizi di livello più basso.

ASP, Active Server Pages, ambiente software che permette di creare pagine

dinamiche, sviluppato inizialmente per IIS combinando HTML, script

(Jscript o VBScript) e controlli ActiveX.

CGI, Common Gateway Interface, meccanismo che permette ad un server web di

eseguire un programma o uno script sul server e di inviare l’output ad un

browser.

HTML, Hypertext Markup Language, sistema per formattare un documento in

modo da renderlo pubblicabile sul World Wide Web.

HTTP, Hypertext Transfer Protocol, protocollo Internet usato da server e client

per scambiare informazioni.

J2EE, Java 2 Enterprise Edition, ambiente di sviluppo creato da Sun

indipendente dalla piattaforma e basato su Java; permette la realizzazione

di applicazioni basate sul web.

JavaBeans , componenti riutilizzabili per comporre applicazioni Java, applet e

servlet; possono venire riuniti in librerie.

JDBC, Java Data Base Connectivity, protocollo emesso da Sun per la

connessione di applicazioni applet e servlet a database esterni; consente

l’esecuzione di interrogazioni SQL, anche attraverso connessioni ODBC.

JSP, JavaServer Pages, tecnologia nata per estendere le possibilità offerte dalle

Servlet Java, produce pagine HTML dal contenuto dinamico.

Glossario 69

69

JSTL, JavaServer Pages Standard Tag Library, insieme di tag che estendono le

possibilità offerte dalle JSP, fornendo ai creatori di applicazioni web uno

strumento intuitivo per sviluppare pagine dinamiche.

JVM, Java Virtual Machine, Software che interpreta i programmi Java compilati

facendoli funzionare sulla piattaforma per cui è stata sviluppata.

MIME, Multimedia Internet Mail Extension, standard che permette di pubblicare

ed utilizzare dati binari all’interno del World Wide Web.

Servlet, programma Java eseguito su di un server web attraverso una JVM,

risultando quindi indipendente sia dalla piattaforma hardware/software che

dal protocollo utilizzato; non necessita di interfaccia grafica, permette di

sostituire gli script CGI.

SQL, Structured Query Language, linguaggio per la creazione di query e la

programmazione di database.

URL, Uniform Resource Locator, stringa che identifica il percorso e il protocollo

da utilizzare per accedere ad un documento su Internet o all’interno di una

intranet.

XML, eXtensible Markup Language, sottoinsieme dell’ SGML (Standard

Generalized Markup Language) che permette di trasferire informazioni

all’interno del World Wide Web in modo flessibile ed indipendente dal

contenuto.

Bibliografia 70

70

Bibliografia

Bruce Eckel, Thinking in Java (2nd edition), Prentice Hall PTR, 2000.

Jason Hunter, Java Servlet programming (2nd Edition), O’Reilly & Associates,

2001.

D. K. Fields, M. A. Kolb, S. Bayern, Web Developement with JavaServer Pages,

Manning Publications Company, 2001.

Shawn Bayern, JSTL in Action, Manning Publications Company, 2002.

Marty Hall, Core Servlets and JavaServer Pages, Prentice Hall PTR, 2000.

David M. Geary, Core JSTL: Mastering the JSP Standard Tag Library, Prentice

Hall PTR, 2002.

S. White, M. Fisher, R. Cattel, G. Hamilton, M. Hapner, JDBC™ API Tutorial

and Reference: Universal Data Access for the Java™ 2 Platform (2nd

Edition), Addison-Wesley Pub Co, 1999.