3. Nozioni di base sullo sviluppo web in Java
Discuteremo ora dello sviluppo di applicazioni web dinamiche, ovvero applicazioni in cui le pagine HTML inviate all'utente sono generate da programmi.
3.1. Creazione di un progetto web in Eclipse
Svilupperemo la nostra prima applicazione web utilizzando Eclipse/Tomcat. Seguiremo un processo simile a quello utilizzato per creare un'applicazione web senza Eclipse. Con Eclipse in esecuzione, creiamo un nuovo progetto:

che definiamo come progetto web dinamico:

Nella prima pagina della procedura guidata di creazione, specifichiamo il nome del progetto [1] e la sua posizione [2]:

Nella seconda pagina della procedura guidata, accettiamo i valori predefiniti:

L'ultima pagina della procedura guidata ci chiede di definire il contesto dell'applicazione [3]:

Una volta confermata la procedura guidata cliccando su [Fine], Eclipse si connette al sito [http://java.sun.com] per recuperare alcuni documenti che desidera memorizzare nella cache al fine di evitare traffico di rete superfluo. Viene quindi richiesto un accordo di licenza:

Lo accettiamo. Eclipse crea il progetto web. Per visualizzarlo, utilizza un ambiente, chiamato prospettiva, diverso da quello utilizzato per un progetto Java tradizionale:

La prospettiva associata a un progetto web è la prospettiva J2EE. La accettiamo per vedere... Il risultato è il seguente:

La prospettiva J2EE è in realtà inutilmente complessa per semplici progetti web. In questo caso, la prospettiva Java è sufficiente. Per accedervi, utilizziamo l'opzione [Finestra -> Apri prospettiva -> Java]:

src: conterrà il codice Java per le classi dell'applicazione, nonché i file che devono trovarsi nel classpath dell'applicazione.
build/classes (non mostrata): conterrà i file .class delle classi compilate, oltre a una copia di tutti i file non .java presenti in src. Un'applicazione web utilizza spesso i cosiddetti file "risorsa" che devono trovarsi nel classpath dell'applicazione, ovvero l'insieme di directory che la JVM cerca quando l'applicazione fa riferimento a una classe, sia durante la compilazione che in fase di esecuzione. Eclipse garantisce che la directory build/classes faccia parte del classpath web. I file "risorsa" vengono collocati nella cartella src, sapendo che Eclipse li copierà automaticamente in build/classes.
WebContent: conterrà le risorse dell'applicazione web che non devono necessariamente trovarsi nel classpath dell'applicazione.
WEB-INF/lib: contiene i file .jar richiesti dall'applicazione web.
Esaminiamo il contenuto del file [WEB-INF/web.xml] che configura l'applicazione [person]:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name> personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Abbiamo già incontrato questo tipo di configurazione quando abbiamo studiato la creazione delle pagine di benvenuto nella Sezione 2.3.4. Questo file non fa altro che definire una serie di pagine di benvenuto. Ne manteniamo solo la prima. Il file [web.xml] diventa il seguente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Il contenuto del file XML sopra riportato deve rispettare le regole sintattiche definite nel file specificato dall'attributo [xsi:schemaLocation] del tag di apertura <web-app>. Tale file si trova all'indirizzo [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd]. Si tratta di un file XML a cui è possibile accedere direttamente tramite un browser web. Se il browser è abbastanza recente, sarà in grado di visualizzare un file XML:

Eclipse tenterà di convalidare il documento XML utilizzando il file .xsd specificato nell'attributo [xsi:schemaLocation] del tag di apertura <web-app>. A tal fine, effettuerà una richiesta di rete. Se il tuo computer si trova su una rete privata, devi indicare a Eclipse quale macchina utilizzare per uscire dalla rete privata, ovvero un proxy HTTP. Questa operazione si effettua tramite l'opzione [Finestra -> Preferenze -> Internet]:

Selezionare la casella (1) se ci si trova su una rete privata. In (2), inserire il nome del computer che ospita il proxy HTTP e in (3) la sua porta di ascolto. Infine, in (4), specificare i computer che devono bypassare il proxy, ovvero quelli che si trovano sulla stessa rete privata del computer su cui si sta lavorando.
Ora creeremo il file [index.html] per la pagina iniziale.
3.2. Creazione di una home page
Fai clic con il pulsante destro del mouse sulla cartella [WebContent] e seleziona [Nuovo -> Altro]:

Selezionare il tipo [HTML] e fare clic su [Avanti] ->

In alto, selezionare la cartella principale [WebContent] in (1) o (2), quindi specificare il nome del file da creare in (3). Una volta fatto ciò, passare alla pagina successiva della procedura guidata:

Con (1), possiamo generare un file HTML precompilato con (2). Se deselezioniamo (1), generiamo un file HTML vuoto. Lasciamo (1) selezionato per beneficiare di un modello di codice. Completiamo la procedura guidata cliccando su [Fine]. Viene quindi creato il file [index.html]:

con il seguente contenuto:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
Modifichiamo questo file come segue:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Application personne</title>
</head>
<body>
Application personne active...
<br>
<br>
Vous êtes sur la page d'accueil
</body>
</html>
3.3. Verifica della pagina iniziale
Se non è presente, visualizza la vista [Servers] utilizzando l'opzione [Window -> Show View -> Other -> Servers], quindi fai clic con il tasto destro del mouse sul server Tomcat 5.5:

L'opzione [Aggiungi e rimuovi oggetti] in alto consente di aggiungere o rimuovere applicazioni web dal server Tomcat:

I progetti web riconosciuti da Eclipse sono elencati in (1). È possibile registrarli sul server Tomcat utilizzando (2). Le applicazioni web registrate sul server Tomcat compaiono in (4). È possibile annullarne la registrazione utilizzando (3). Registriamo il progetto [person]:

quindi completare la procedura guidata di registrazione facendo clic su [Fine]. La vista [Server] mostra che il progetto [person] è stato registrato su Tomcat:

Ora avviamo il server Tomcat:
![]() | ![]() |
Avvia il browser web:

quindi inserisci l'URL [http://localhost:8080/personne]. Questo URL è la radice dell'applicazione web. Non viene richiesto alcun documento. In questo caso, viene visualizzata la home page dell'applicazione. Se non esiste, viene segnalato un errore. In questo caso, la home page esiste. Si tratta del file [index.html] che abbiamo creato in precedenza. Il risultato è il seguente:

Corrisponde a quanto previsto. Ora, utilizziamo un browser esterno a Eclipse e richiediamo lo stesso URL:

L'applicazione web [person] è quindi accessibile anche al di fuori di Eclipse.
3.4. Creazione di un modulo HTML
Ora creeremo un documento HTML statico [form.html] nella cartella [person]:

Per crearlo, seguire la procedura descritta nella sezione 3.2, pagina 33. Il suo contenuto sarà il seguente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Retablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Il codice HTML sopra riportato corrisponde al modulo sottostante:

Tipo HTML | nome | Codice HTML | ruolo | |
<input type="text"> | txtName | riga 14 | inserisci nome | |
<input type="text"> | txtEtà | riga 18 | campo età | |
<input type="submit"> | riga 23 | Invia i valori inseriti al server all'URL /person1/main | ||
<input type="reset"> | riga 24 | per riportare la pagina allo stato in cui era stata inizialmente ricevuta dal browser | ||
<input type="button"> | riga 25 | per cancellare il contenuto dei campi di immissione [1] e [2] |
Salviamo il documento nella cartella <person>/WebContent. Avviamo Tomcat se necessario. Utilizzando un browser, accediamo all'URL http://localhost:8080/personne/formulaire.html:

L'architettura client/server di questa applicazione di base è la seguente:

Il server web si trova tra l'utente e l'applicazione web e non è stato raffigurato qui. [formulaire.html] è un documento statico che restituisce lo stesso contenuto per ogni richiesta del client. La programmazione web mira a generare contenuti su misura per la richiesta del client. Questo contenuto viene quindi generato a livello di programmazione. Una soluzione consiste nell'utilizzare una JSP (Java Server Page) al posto del file HTML statico. È proprio questo che esamineremo ora.
3.5. Creazione di una pagina JSP
Letture [rif1]: Capitolo 1, Capitolo 2: 2.2, 2.2.1, 2.2.2, 2.2.3, 2.2.4
La precedente architettura client/server viene trasformata come segue:

Una pagina JSP è un tipo di pagina HTML parametrizzata. Alcuni elementi della pagina ricevono i propri valori solo in fase di esecuzione. Questi valori vengono calcolati dal programma. Abbiamo quindi una pagina dinamica: richieste successive alla pagina possono produrre risposte diverse. In questo contesto, ci riferiamo alla pagina HTML visualizzata dal browser del client come alla risposta. In definitiva, il browser riceve sempre un documento HTML. Questo documento HTML viene generato dal server web a partire dalla pagina JSP, che funge da modello. I suoi elementi dinamici vengono sostituiti dai loro valori effettivi al momento della generazione del documento HTML.
Per creare una pagina JSP, fare clic con il tasto destro del mouse sulla cartella [WebContent] e selezionare l'opzione [Nuovo -> Altro]:

Selezioniamo il tipo [JSP] e facciamo clic su [Avanti] ->

In alto, selezioniamo la cartella principale [WebContent] in (1) o (2), quindi specifichiamo in (3) il nome del file da creare. Una volta fatto ciò, passiamo alla pagina successiva della procedura guidata:

Con (1), possiamo generare un file JSP precompilato con (2). Se deselezioniamo (1), generiamo un file JSP vuoto. Lasciamo (1) selezionato per beneficiare di un modello di codice. Completiamo la procedura guidata cliccando su [Fine]. Viene quindi creato il file [formulaire.jsp]:

con il seguente contenuto:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
La riga 1 indica che abbiamo a che fare con una pagina JSP. Trasformiamo il testo sopra riportato come segue:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// on récupère les paramètres
String nom=request.getParameter("txtNom");
if(nom==null) nom="inconnu";
String age=request.getParameter("txtAge");
if(age==null) age="xxx";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Il documento inizialmente statico è ora diventato dinamico grazie all'introduzione del codice Java. Per questo tipo di documento, procederemo sempre come segue:
- Inseriamo il codice Java all'inizio del documento per recuperare i parametri necessari alla visualizzazione del documento. Questi si trovano spesso nell'oggetto request. Questo oggetto rappresenta la richiesta del client. Potrebbe essere passato attraverso diversi servlet e pagine JSP che potrebbero averlo arricchito. In questo caso, proviene direttamente dal browser.
- Segue il codice HTML. Di solito visualizzerà semplicemente le variabili precedentemente calcolate nel codice Java utilizzando i tag <%= variabile %>. Si noti qui che il segno = si trova proprio accanto al segno %. Questa è una causa comune di errori.
Cosa fa il documento dinamico precedente?
- Righe 6–9: recupera due parametri dalla richiesta, denominati [txtNom] e [txtAge], e assegna i loro valori alle variabili [nom] (riga 6) e [age] (riga 8). Se non trova i parametri, assegna valori predefiniti alle variabili associate.
- Visualizza i valori delle due variabili [name, age] nel seguente codice HTML (righe 25 e 29).
Eseguiamo un test iniziale. Avvia Tomcat se necessario, quindi utilizza un browser per richiedere l'URL http://localhost:8080/personne/formulaire.jsp:

Il documento form.jsp è stato richiamato senza passare alcun parametro. Sono stati quindi visualizzati i valori predefiniti. Ora richiediamo l'URL http://localhost:8080/personne/formulaire.jsp?txtNom=martin&txtAge=14:

Questa volta abbiamo passato i parametri txtNom e txtAge alla pagina form.jsp, come da essa previsto. La pagina li ha quindi visualizzati. Sappiamo che esistono due metodi per passare parametri a una pagina web: GET e POST. In entrambi i casi, i parametri passati vengono memorizzati nell'oggetto request predefinito. In questo caso, sono stati passati utilizzando il metodo GET.
3.6. Creazione di un servlet
Letture [rif1]: Capitolo 1, Capitolo 2: 2.1, 2.1.1, 2.1.2, 2.3.1
Nella versione precedente, la richiesta del client veniva gestita da una pagina JSP. Al primo accesso a questa pagina, il server web — in questo caso, Tomcat — crea una classe Java dalla pagina e la compila. È il risultato di questa compilazione che, in definitiva, elabora la richiesta del client. La classe generata dalla pagina JSP è un servlet poiché implementa l'interfaccia [javax.Servlet]:

La richiesta del client può essere gestita da qualsiasi classe che implementi questa interfaccia. Ora creeremo una classe di questo tipo: ServletFormulaire. La precedente architettura client/server viene trasformata come segue:

Con l'architettura basata su JSP, il documento HTML inviato al client veniva generato dal server web a partire dalla pagina JSP che fungeva da modello. In questo caso, il documento HTML inviato al client sarà interamente generato dal servlet.
3.6.1. Creazione del servlet
In Eclipse, fare clic con il tasto destro sulla cartella [src] e selezionare l'opzione per creare una classe:

quindi definire le caratteristiche della classe da creare:

Nel campo (1) inserire il nome del pacchetto; nel campo (2) inserire il nome della classe da creare. Questa classe deve estendere la classe specificata nel campo (3). Non è necessario digitare manualmente il nome completo della classe. Il pulsante (4) consente di accedere alle classi attualmente presenti nel classpath dell'applicazione web:

In (1), digitare il nome della classe che si sta cercando. In (2), verranno visualizzate le classi nel Classpath i cui nomi contengono la stringa digitata in (1).
Dopo aver confermato la procedura guidata di creazione, il progetto web [person] viene modificato come segue:

La classe [ServletFormulaire] è stata creata con uno scheletro di codice:

La schermata sopra mostra che Eclipse visualizza un [avviso] sulla riga che dichiara la classe. Fare clic sull'icona (lampadina) che indica questo [avviso]:

Dopo aver cliccato su (1), in (2) vengono suggerite delle soluzioni per rimuovere l'[avviso]. Selezionandone una, in (3) appare la modifica al codice che ne deriverà.
Java 1.5 ha introdotto modifiche al linguaggio Java e ciò che era corretto in una versione precedente ora potrebbe generare [avvisi]. Questi non indicano errori che impedirebbero la compilazione della classe. Sono presenti per richiamare l'attenzione dello sviluppatore su aree del codice che potrebbero essere migliorate. L'attuale [avviso] indica che una classe dovrebbe avere un numero di versione. Questo viene utilizzato per la serializzazione/deserializzazione degli oggetti, ovvero quando un oggetto Java .class in memoria deve essere convertito in una sequenza di bit inviati in modo sequenziale in un flusso di scrittura, o il contrario quando un oggetto Java .class in memoria deve essere creato da una sequenza di bit letti in modo sequenziale in un flusso di lettura. Tutto questo è ben lontano dalle nostre attuali preoccupazioni. Chiederemo quindi al compilatore di ignorare questo avviso selezionando l'opzione [Add @SuppressWarnings ...]. Il codice diventa quindi il seguente:

Non ci sono più [avvisi]. La riga aggiunta è chiamata "annotazione", un concetto introdotto in Java 1.5. Completeremo questo codice in seguito.
3.6.2. Classpath di un progetto Eclipse
Il classpath di un'applicazione Java è l'insieme di cartelle e file .jar in cui si effettua la ricerca quando il compilatore la compila o quando la JVM la esegue. Questi due classpath non sono necessariamente identici, poiché alcune classi sono necessarie solo in fase di esecuzione e non durante la compilazione. Sia il compilatore Java che la JVM dispongono di un argomento che consente di specificare il classpath dell'applicazione da compilare o eseguire. In un modo più o meno trasparente per l'utente, Eclipse gestisce la costruzione e il passaggio di questo argomento alla JVM.
Come è possibile determinare gli elementi del classpath di un progetto Eclipse? Utilizzando l'opzione [<progetto> / Build Path / Configure Build Path]:

Viene visualizzata la seguente procedura guidata di configurazione:

La scheda (1) [Libraries] consente di definire l'elenco dei file .jar che fanno parte del classpath dell'applicazione. Questi vengono quindi cercati dalla JVM quando l'applicazione richiede una classe. I pulsanti [2] e [3] consentono di aggiungere archivi al Classpath. Il pulsante [2] permette di selezionare archivi situati nelle cartelle dei progetti gestiti da Eclipse, mentre il pulsante [3] permette di selezionare qualsiasi archivio dal file system del computer.
Sopra compaiono tre librerie:
- [JRE System Library]: la libreria di base per i progetti Java di Eclipse:

- [Runtime Tomcat v5.5]: una libreria fornita dal server Tomcat. Contiene le classi necessarie per lo sviluppo web. Questa libreria è inclusa in qualsiasi progetto web Eclipse che sia stato associato al server Tomcat.

È l'archivio [servlet-api.jar] che contiene la classe [javax.servlet.http.HttpServlet], la classe padre della classe [ServletFormulaire] che stiamo creando. È proprio perché questo archivio si trova nel Classpath dell'applicazione che è stato suggerito come classe padre nella procedura guidata mostrata di seguito.

Se così non fosse stato, non sarebbe apparsa tra i suggerimenti in [2]. Pertanto, se in questa procedura guidata si desidera fare riferimento a una classe padre e questa non viene suggerita, significa che o si è digitato in modo errato il nome della classe, oppure che l’archivio che la contiene non si trova nel classpath dell’applicazione.
- [Librerie app Web] contiene gli archivi situati nella cartella [WEB-INF/lib] del progetto. Qui è vuoto:

Gli archivi nel classpath del progetto Eclipse sono visibili nell'esploratore di progetto. Ad esempio, per il progetto web [person]:

L'esploratore di progetto ci consente di accedere al contenuto di questi archivi:

Come mostrato sopra, possiamo vedere che l'archivio [servlet-api.jar] contiene la classe [javax.servlet.http.HttpServlet].
3.6.3. Configurazione del servlet
Letture [rif1]: Capitolo 2: 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4
Il file [WEB-INF/web.xml] serve a configurare l'applicazione web:

Per il progetto [person], questo file attualmente ha questo aspetto (vedi pagina 32):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Indica solo l'esistenza di un file di benvenuto (riga 8). Lo modifichiamo per dichiarare:
- l'esistenza del servlet [ServletFormulaire]
- gli URL gestiti da questo servlet
- i parametri di inizializzazione del servlet
Il file web.xml della nostra applicazione sarà il seguente:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
I punti principali di questo file di configurazione sono i seguenti:
- Le righe 7–24 riguardano la presenza del servlet [ServletFormulaire]
- Righe 7–20: un servlet è configurato tra i tag <servlet> e </servlet>. Un'applicazione può contenere più servlet e quindi più sezioni di configurazione <servlet>...</servlet>.
- Riga 8: Il tag <servlet-name> assegna un nome al servlet; può essere qualsiasi nome
- Righe 9–11: Il tag <servlet-class> specifica il nome completo della classe del servlet. Tomcat cercherà questa classe nel classpath del progetto web [personne]. La troverà in [build/classes]:
![]()
- Righe 12–15: Il tag <init-param> viene utilizzato per passare i parametri di configurazione al servlet. Questi vengono generalmente letti nel metodo init del servlet perché i suoi parametri di configurazione devono essere noti non appena viene caricato per la prima volta.
- Righe 13–14: il tag <param-name> imposta il nome del parametro e <param-value> ne imposta il valore.
- Le righe 12–15 definiscono un parametro [defaultName, "unknown"], mentre le righe 16–19 definiscono un parametro [defaultAge, "XXX"]
- Righe 21–24: il tag <servlet-mapping> viene utilizzato per associare un servlet (servlet-name) a un modello di URL (url-pattern). In questo caso, il modello è semplice. Specifica che ogni volta che un URL assume la forma /formulaire, deve essere utilizzato il servlet formulairepersonne, ovvero la classe [istia.st.servlets.ServletFormulaire] (righe 8–11). Pertanto, solo un URL è accettato dal servlet [formulairepersonne].
3.6.4. Il codice per il servlet [ServletFormulaire]
Il servlet [ServletFormulaire] avrà il seguente codice:
Basta leggere il servlet per rendersi conto che è molto più complesso della corrispondente pagina JSP. Questa è una regola generale: un servlet non è adatto alla generazione di codice HTML. Le pagine JSP sono progettate proprio per questo scopo. Avremo modo di tornare su questo argomento più avanti. Chiariamo alcuni punti importanti riguardo al servlet sopra riportato:
- Quando un servlet viene chiamato per la prima volta, viene chiamato il suo metodo init (riga 20). Questa è l'unica volta in cui viene chiamato.
- Se il servlet è stato chiamato tramite il metodo HTTP GET, viene chiamato il metodo doGet (riga 32) per elaborare la richiesta del client.
- Se il servlet è stato chiamato tramite il metodo HTTP POST, viene chiamato il metodo doPost (riga 82) per elaborare la richiesta del client.
Il metodo init viene utilizzato in questo caso per recuperare i valori dei parametri di inizializzazione denominati "defaultName" e "defaultAge" dal file [web.xml]. Il metodo init, eseguito al primo caricamento del servlet, è il punto appropriato per recuperare il contenuto del file [web.xml].
- Riga 22: Viene recuperata la configurazione [config] del progetto web. Questo oggetto riflette il contenuto del file [WEB-INF/web.xml] dell'applicazione.
- Riga 23: in questa configurazione, recuperiamo il valore String del parametro denominato "defaultName". Questo parametro conterrà il nome di una persona. Se non esiste, il valore sarà nullo.
- Righe 24–25: Se il parametro denominato "defaultName" non esiste, alla variabile [defaultName] viene assegnato un valore predefinito.
- Righe 26–29: Facciamo lo stesso per il parametro denominato "defaultAge".
Il metodo doPost fa riferimento al metodo doGet. Ciò significa che il client può inviare i propri parametri utilizzando una richiesta POST o una richiesta GET.
Il metodo doGet:
- Riga 32: Il metodo riceve due parametri, `request` e `response`. `request` è un oggetto che rappresenta l'intera richiesta del client. È di tipo `HttpServletRequest`, che è un'interfaccia. `response` è di tipo `HttpServletResponse`, che è anch'essa un'interfaccia. L'oggetto `response` viene utilizzato per inviare una risposta al client.
- request.getParameter("param") viene utilizzato per recuperare il valore del parametro denominato "param" dalla richiesta del client. Alla riga 36, recuperiamo il valore del parametro "txtNom"; alla riga 40, quello del parametro "txtAge". Se questi parametri non sono presenti nella richiesta, il valore del parametro viene impostato su null.
- Righe 37–39: Se il parametro "txtNom" non è presente nella richiesta, alla variabile "nom" viene assegnato il nome predefinito "defaultNom" inizializzato nel metodo init. Lo stesso viene fatto nelle righe 41–43 per l'età.
- Riga 45: response.setContentType(String) viene utilizzato per impostare il valore dell'intestazione HTTP Content-Type. Questa intestazione indica al client la natura del documento che riceverà. Il tipo text/html indica un documento HTML.
- Riga 46: response.getWriter() viene utilizzato per ottenere un flusso di scrittura verso il client
- Righe 47–78: il documento HTML da inviare al client viene scritto nel flusso di scrittura ottenuto alla riga 46.
La compilazione di questo servlet genererà un file .class nella cartella [build/classes] del progetto [person]:

Si invitano i lettori a consultare la documentazione Java sui servlet. A questo scopo è possibile utilizzare Tomcat. Nella home page di Tomcat 5 è presente un link [Documentazione]:

Questo link conduce a una pagina che il lettore è invitato a esplorare. Il link alla documentazione sui servlet è il seguente:

3.6.5. Testare il servlet
Siamo pronti per eseguire un test. Avviare il server Tomcat se necessario.

Quindi, utilizzando un browser, richiedere l'URL [http://localhost:8080/personne/formulaire]. In questo caso, stiamo richiedendo l'URL [/form] dal contesto [/person]. Il file [web.xml] per questo contesto specifica che l'URL [/form] è gestito dal servlet denominato [formperson]. Nello stesso file, è specificato che questo servlet è la classe [istia.st.servlets.ServletFormulaire]. Tomcat affiderà quindi a questa classe l'elaborazione della richiesta del client. Se la classe non era già stata caricata, verrà caricata. Rimarrà quindi in memoria per le richieste future.
Otteniamo il seguente risultato utilizzando il browser integrato in Eclipse:

Otteniamo i valori predefiniti per nome ed età, come specificato nel file [web.xml]. Ora richiediamo l'URL [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30]:

Questa volta, otteniamo i parametri passati nella richiesta. Il lettore è invitato a rivedere il codice del servlet [ServletFormulaire] se non comprende questi due risultati.
3.6.6. Ricaricamento automatico del contesto dell'applicazione web
Avviamo Tomcat:

quindi modifichiamo il codice del servlet come segue:
- La riga 8 è stata modificata
Salviamo la nuova classe. Questo salvataggio attiverà una ricompilazione automatica della classe [ServletFormulaire] da parte di Eclipse, che Tomcat rileverà. Ricaricherà quindi il contesto dell'applicazione web [personne] per riflettere le modifiche. Ciò appare nei log della vista [console]:

Richiediamo l'URL [http://localhost:8080/personne/formulaire] senza riavviare Tomcat:

La modifica è stata applicata con successo.
Ora modifichiamo il file [web.xml] come segue:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
...
<init-param>
<param-name>defaultNom</param-name>
<param-value>INCONNU</param-value>
</init-param>
...
</servlet>
...
</web-app>
- La riga 12 è stata modificata
Ora che abbiamo finito, salviamo il nuovo file [web.xml]. Nella vista [console], nessun log indica che il contesto dell'applicazione è stato ricaricato. Richiediamo l'URL [http://localhost:8080/personne/formulaire] senza riavviare Tomcat:

La modifica non è stata applicata. Riavviamo Tomcat [clic destro sul server -> Riavvia -> Avvia]:

quindi richiediamo nuovamente l'URL [http://localhost:8080/personne/formulaire]:

Questa volta, la modifica apportata in [web.xml] è visibile.
Una modifica a [web.xml] non attiva automaticamente un ricaricamento dell'applicazione che incorpori il nuovo file di configurazione. Per forzare il ricaricamento dell'applicazione web, è possibile riavviare Tomcat come abbiamo fatto, ma si tratta di un processo piuttosto lento. È preferibile utilizzare lo strumento [manager] per l'amministrazione delle applicazioni distribuite in Tomcat. Affinché ciò funzioni, Tomcat deve essere stato configurato all'interno di Eclipse come mostrato nella Sezione 2.5.
Per prima cosa, utilizzando il browser interno di Eclipse, inserisci l'URL [http://localhost:8080] e poi segui il link [Tomcat Manager], come spiegato alla fine della Sezione 2.5:

Apriamo un secondo browser [clic destro sul browser -> Nuovo editor]:
![]() | ![]() |
In questa seconda finestra del browser, inserisci l'URL [http://localhost:8080/formulaire]:

Modifica il file [web.xml] come segue, quindi salvalo:
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>YYY</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
Quindi richiedi nuovamente l'URL [http://localhost:8080/formulaire]. Possiamo vedere che la modifica non è stata applicata. Ora, vai al primo browser e ricarica l'applicazione [person]:

Quindi richiedere nuovamente l'URL [http://localhost:8080/formulaire] utilizzando il secondo browser:

La modifica a [web.xml] è stata applicata. In pratica, è utile avere un browser aperto sull'applicazione [manager] di Tomcat per gestire questo tipo di situazione.
3.7. Interazione tra Servlet e pagine JSP
Letture [rif1]: Capitolo 2: 2.3.7
Torniamo alle due architetture che abbiamo esaminato:

Nessuna di queste due architetture è soddisfacente. Entrambe presentano l'inconveniente di mescolare due tecnologie: la programmazione Java, che gestisce la logica dell'applicazione web, e la codifica HTML, che gestisce la presentazione delle informazioni in un browser.
- La soluzione basata su JSP [1] presenta l'inconveniente di mescolare codice HTML e codice Java all'interno della stessa pagina. Non l'abbiamo notato nell'esempio che abbiamo trattato, che era di base. Ma se [formulaire.jsp] dovesse convalidare i parametri [txtNom, txtAge] nella richiesta del client, saremmo stati costretti a inserire codice Java nella pagina. Questo diventa rapidamente ingestibile.
- La soluzione [2], basata su un servlet, presenta lo stesso problema. Sebbene nella classe sia presente solo codice Java, essa deve generare un documento HTML. Anche in questo caso, a meno che il documento HTML non sia semplice, la sua generazione diventa complicata e quasi impossibile da mantenere.
Eviteremo di mescolare le tecnologie Java e HTML adottando la seguente architettura:

- L'utente invia la propria richiesta al servlet. Il servlet la elabora e costruisce i valori per i parametri dinamici della pagina JSP [form.jsp], che saranno utilizzati per generare la risposta HTML per il client. Questi valori formano quello che è noto come modello di pagina JSP.
- Una volta completato il suo lavoro, il servlet chiederà alla pagina JSP [form.jsp] di generare la risposta HTML per il client. Allo stesso tempo, fornirà alla pagina JSP gli elementi necessari per generare questa risposta, ovvero gli elementi che compongono il modello della pagina.
Esploreremo ora questa nuova architettura.
3.7.1. Il servlet [ServletFormulaire2]
Nell'architettura sopra riportata, il servlet si chiamerà [ServletFormulaire2]. Verrà realizzato nello stesso progetto [personne] di prima, insieme a tutti i futuri servlet:

[ServletFormulaire2] viene creato inizialmente copiando e incollando [ServletFormulaire] all'interno di Eclipse:
- selezionare [ServletFormulaire.java] -> clic destro -> Copia
- Selezionare [istia.st.servlets.personne] -> clic destro -> Incolla -> rinominare in [ServletFormulaire2.java]
Quindi, modifichiamo il codice di [ServletFormulaire2] come segue:
È cambiata solo la parte che genera la risposta HTTP (righe 44–46):
- Riga 46: La pagina JSP `formulaire2.jsp` è responsabile della generazione della risposta. Questa pagina, che non abbiamo ancora trattato, visualizzerà i parametri recuperati dalla richiesta del client: un nome (righe 35–38) e un'età (righe 39–42).
- Questi due valori vengono inseriti negli attributi della richiesta, associati a delle chiavi. Gli attributi della richiesta sono gestiti come un dizionario.
- Riga 44: Il nome viene inserito nella richiesta associato alla chiave "name"
- Riga 45: L'età viene inserita nella richiesta associata alla chiave "age"
- Riga 46: Richiede la visualizzazione della pagina JSP [formulaire2.jsp]. Le viene passato come parametro quanto segue:
- la richiesta del client, che permette alla pagina JSP di accedere ai propri attributi appena inizializzati dal servlet
- la risposta [response], che consentirà alla pagina JSP di generare la risposta HTTP al client
Una volta scritta la classe [ServletFormulaire2], il suo codice compilato appare in [build/classes]:

3.7.2. La pagina JSP [formulaire2.jsp]
La pagina JSP formulaire2.jsp viene creata copiando e incollando la pagina [formulaire.jsp]

e successivamente modificata come segue:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// on récupère les valeurs nécessaire à l'affichage
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire2</title>
</head>
<body>
<center>
<h2>Personne - formulaire2</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Rispetto a [formulaire.jsp] sono cambiate solo le righe 4–8:
- riga 6: recupera il valore dell'attributo denominato "name" nella [richiesta], un attributo creato dal servlet [ServletFormulaire2].
- riga 7: fa lo stesso per l'attributo "age"
3.7.3. Configurazione dell'applicazione
Il file di configurazione [web.xml] viene modificato come segue:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXXX</param-value>
</init-param>
</servlet>
<!-- ServletFormulaire 2-->
<servlet>
<servlet-name>formulairepersonne2</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire2
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<!-- Mapping ServletFormulaire -->
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<!-- Mapping ServletFormulaire 2-->
<servlet-mapping>
<servlet-name>formulairepersonne2</servlet-name>
<url-pattern>/formulaire2</url-pattern>
</servlet-mapping>
<!-- welcome files -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Abbiamo mantenuto il codice esistente e aggiunto:
- Righe 22–36: una sezione <servlet> per definire il nuovo servlet ServletFormulaire2
- Righe 42–46: una sezione <servlet-mapping> per associarlo all'URL /formulaire2
Avviare o riavviare il server Tomcat se necessario. Richiediamo l'URL
http://localhost:8080/personne/formulaire2?txtNom=milou&txtAge=10:

Otteniamo lo stesso risultato di prima, ma la struttura della nostra applicazione è ora più chiara: un servlet che contiene la logica applicativa e delega il compito di inviare la risposta al client a una pagina JSP. D'ora in poi procederemo sempre in questo modo.



