6. Applicazione web MVC [personne] – versione 2
Ora proporremo alcune varianti della precedente applicazione [/personne1], che chiameremo [/personne2, /personne3, ...]. Queste varianti non modificano l’architettura iniziale dell’applicazione, che rimane la seguente:

Per queste varianti, le nostre spiegazioni saranno più concise. Presenteremo solo le modifiche apportate rispetto alla versione precedente.
6.1. Introduction
Ci proponiamo ora di aggiungere alla nostra applicazione una gestione delle sessioni. Ricordiamo i seguenti punti:
- il dialogo client-server HTTP è una sequenza di richieste e risposte non collegate tra loro
- la sessione funge da memoria tra le diverse sequenze richiesta-risposta di uno stesso utente. Se ci sono N utenti, ci sono N sessioni.
La seguente sequenza di schermate illustra ciò che ora si desidera ottenere nel funzionamento dell’applicazione:
Scambio n. 1
![]() | ![]() |
La novità riguarda il link di ritorno al modulo che è stato aggiunto nella vista [erreurs].
Scambio n. 2
![]() | ![]() |
Nello scambio n. 1, l'utente ha fornito per la coppia (nome, età) i valori (xx, yy). Se nel corso dello scambio il server è venuto a conoscenza di questi valori, al termine dello scambio li "dimentica". Tuttavia, si può notare che durante lo scambio n. 2 il server è in grado di visualizzare nuovamente tali valori nella propria risposta. È il concetto di sessione che, in questo caso, consentirà al server web di memorizzare i dati nel corso dei successivi scambi client-server. Esistono altre soluzioni possibili per risolvere questo problema.
Durante lo scambio n. 1, il server memorizzerà nella sessione la coppia (nome, età) che il client gli ha inviato, in modo da poterla visualizzare durante lo scambio n. 2.
Ecco un altro esempio di implementazione della sessione tra due scambi:
Scambio n. 1
![]() | ![]() |
La novità riguarda il link di ritorno al modulo che è stato aggiunto nella pagina della risposta.
Scambio n. 2
![]() | ![]() |
6.2. Il progetto Eclipse
Per creare il progetto Eclipse [mvc-personne-02] dell'applicazione web [/personne2], duplicheremo il progetto Eclipse [mvc-personne-01] in modo da recuperare il codice esistente. A tal fine, procediamo come segue:
[clic droit sur projet mvc-personne-01 -> Copy]:

poi [clic droit dans Package Explorer -> Paste]:
![]() | ![]() - indichiamo in [1] il nome del nuovo progetto e in [2] il nome di una cartella esistente ma vuota |
Viene quindi creato il progetto [mvc-personne-02]:

Per il momento è identico al progetto [mvc-personne-01]. Dovremo apportare alcune modifiche manualmente prima di poterlo utilizzare. Passiamo alla vista [Servers] e proviamo ad aggiungere questa nuova applicazione a quelle gestite da Tomcat:
![]() | ![]() |
Si nota che in [1] il nuovo progetto [mvc-personne-02] non viene rilevato da Tomcat. Affinché venga rilevato, è necessario modificare un file di configurazione del progetto [mvc-personne-02]. Utilizziamo l’opzione [File / Open File] per aprire il file [<mvc-personne-02>/.settings/.component]:
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId">
<wb-module deploy-name="mvc-personne-01">
<wb-resource deploy-path="/" source-path="/WebContent"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
<property name="java-output-path" value="/build/classes/"/>
<property name="context-root" value="personne1"/>
</wb-module>
</project-modules>
La riga 3 indica il nome del modulo web da distribuire all’interno di Tomcat. Questo nome, in questo caso, è lo stesso di quello del progetto [mvc-personne-01]. Lo modifichiamo in [mvc-personne-02]:
<wb-module deploy-name="mvc-personne-02">
Inoltre, possiamo cogliere l’occasione per modificare, alla riga 7, il nome del contesto dell’applicazione [mvc-personne-02], che è in conflitto con quello del progetto [mvc-personne-01]:
<property name="context-root" value="personne2"/>
Questa seconda modifica poteva essere effettuata direttamente all’interno di Eclipse. Per contro, non ho trovato il modo di effettuare la prima senza passare dal file di configurazione.
Fatto ciò, salviamo il nuovo file [.content], quindi chiudiamo e riavviamo Eclipse affinché le modifiche vengano applicate.
Una volta riavviato Eclipse, proviamo a eseguire l’operazione che in precedenza non era andata a buon fine:
![]() | ![]() |
Questa volta, il progetto [mvc-personne-02] viene riconosciuto correttamente. Lo aggiungiamo ai progetti configurati per essere eseguiti da Tomcat:

6.3. Configurazione dell’applicazione web [personne2]
Il file web.xml dell’applicazione /personne2 è 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>mvc-personne-02</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
<init-param>
<param-name>urlReponse</param-name>
<param-value>
/WEB-INF/vues/reponse.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlErreurs</param-name>
<param-value>
/WEB-INF/vues/erreurs.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlFormulaire</param-name>
<param-value>
/WEB-INF/vues/formulaire.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlControleur</param-name>
<param-value>
main
</param-value>
</init-param>
<init-param>
<param-name>lienRetourFormulaire</param-name>
<param-value>
Retour au formulaire
</param-value>
</init-param>
</servlet>
<!-- Mappatura ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<!-- file di benvenuto -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Questo file è identico a quello della versione precedente, tranne per il fatto che dichiara due nuovi parametri di inizializzazione:
- riga 6: il nome visualizzato dell’applicazione web è cambiato in [mvc-personne-02]
- righe 31-36: definiscono il parametro di configurazione denominato [urlControleur], che corrisponde all’URL [main] che rimanda al servlet [ServletPersonne]
- righe 37-42: definiscono un parametro di configurazione denominato [lienRetourFormulaire], che corrisponde al testo del link di ritorno al modulo dalle pagine JSP, [erreurs.jsp] e [reponse.jsp].
La pagina iniziale [index.jsp] cambia:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
response.sendRedirect("/personne2/main");
%>
- riga 5: la pagina [index.jsp] reindirizza il client all'URL del controller [ServletPersonne] dell'applicazione [/personne2].
6.4. Il codice delle viste
6.4.1. La vista [formulaire]
Questa vista è identica a quella della versione precedente:

Viene generata dalla pagina JSP [formulaire.jsp] seguente:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// si recuperano i dati del modello
String nom=(String)session.getAttribute("nom");
String age=(String)session.getAttribute("age");
String urlAction=(String)request.getAttribute("urlAction");
%>
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="<%=urlAction%>" 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>
<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>
<input type="hidden" name="action" value="validationFormulaire">
</form>
</center>
</body>
</html>
Novità:
- riga 19, il modulo presenta ora un attributo [action] il cui valore è l'URL a cui il browser dovrà inviare i valori del modulo quando l'utente cliccherà sul pulsante [Envoyer] di tipo submit. La variabile [urlAction] avrà il valore action="main". La vista [formulaire] viene visualizzata dopo le seguenti azioni dell’utente:
- richiesta iniziale: GET /persona2/main
- clic sul link [Retour au formulaire]: GET /persona2/main?action=retourFormulaire
Poiché l'attributo [action] non specifica un URL assoluto (che inizia con /) ma un URL relativo (che non inizia con /), il browser utilizzerà la prima parte dell'URL della pagina attualmente visualizzata [/personne2] e vi aggiungerà l'URL relativo. L’URL di POST sarà quindi [/personne2/main], ovvero quello del controller. Questa richiesta POST sarà accompagnata dai parametri [txtNom, txtAge, action] delle righe 23, 27 e 38.
- riga 8: si recupera il valore dell’elemento [urlAction] del modello. Viene cercato negli attributi della richiesta corrente. Verrà utilizzato alla riga 19.
- righe 6-7: si recuperano i valori degli elementi [nom, age] del modello. Vengono ricercati negli attributi della sessione e non più in quelli della richiesta come nella versione precedente. Ciò per soddisfare le esigenze della richiesta [GET /personne2/main?action=retourFormulaire] relativa al collegamento delle viste [réponse] e [erreurs]. Prima di visualizzare queste due viste, il controller inserisce nella sessione i dati inseriti nel modulo, il che gli consente di recuperarli quando l’utente utilizza il collegamento [Retour au formulaire] delle viste [réponse] e [erreurs].
6.4.2. La vista [reponse]
Questa vista visualizza i valori inseriti nel modulo quando questi sono validi:
![]() | ![]() |
Rispetto alla versione precedente, la novità è rappresentata dal link [Retour au formulaire]. La vista è generata dalla pagina JSP [reponse.jsp] seguente:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// si recuperano i dati del modello
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Personne - réponse</h2>
<hr>
<table>
<tr>
<td>Nom</td>
<td><%= nom %>
</tr>
<tr>
<td>Age</td>
<td><%= age %>
</tr>
</table>
<br>
<a href="?action=retourFormulaire"><%= lienRetourFormulaire %></a>
</body>
</html>
- riga 31: il link di ritorno al modulo. Questo link ha due componenti:
- la destinazione [href="?action=retourFormulaire"]. La vista [réponse] viene visualizzata dopo la vista POST del modulo [formulaire.jsp] all'URL [/personne2/main]. È quindi quest’ultimo URL che viene visualizzato nel browser quando viene visualizzata la vista [réponse]. Cliccando sul link [Retour au formulaire], il browser effettuerà una richiesta GET all’URL specificato dall’attributo [href] del link, in questo caso "?action=retourFormulaire". In assenza di un URL in [href], il browser utilizzerà quello della vista attualmente visualizzata, c.a.d. [/personne2/main]. In definitiva, cliccando sul link [Retour au formulaire] il browser effettuerà una richiesta GET all'URL [/personne2/main?action=retourFormulaire], c.a.d, l'URL del controller dell'applicazione, accompagnato dal parametro [action] per indicargli cosa deve fare.
- il testo del link. Questo farà parte del modello trasmesso alla pagina dal controller e recuperato alla riga 10.
6.4.3. La vista [erreurs]
Questa vista segnala gli errori di inserimento nel modulo:
![]() | ![]() |
Rispetto alla versione precedente, la novità è rappresentata dal link [Retour au formulaire]. La vista è generata dalla pagina JSP [erreurs.jsp] seguente:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
<%
// si recuperano i dati del modello
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<%
for(int i=0;i<erreurs.size();i++){
out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
}//per
%>
</ul>
<br>
<a href="?action=retourFormulaire"><%= lienRetourFormulaire %></a>
</body>
</html>
- riga 26: il link di ritorno al modulo. Questo link è identico a quello della vista [réponse]. Si invita il lettore a rileggere, se necessario, le spiegazioni fornite per questa vista.
6.5. Test delle viste
Per eseguire i test delle viste precedenti, duplichiamo le relative pagine JSP nella cartella /WebContent/JSP del progetto Eclipse:

Quindi, nella cartella JSP, le pagine vengono modificate come segue:
[formulaire.jsp]:
...
<%
// -- test: si crea il modello della pagina
session.setAttribute("nom","tintin");
session.setAttribute("age","30");
request.setAttribute("urlAction","main");
%>
<%
// si recuperano i dati dal modello
String nom=(String)session.getAttribute("nom");
String age=(String)session.getAttribute("age");
String urlAction=(String)request.getAttribute("urlAction");
%>
Le righe 4-5 sono state aggiunte per creare il modello necessario alla pagina delle righe 11-13.
[reponse.jsp]:
<%
// -- test: si crea il modello della pagina
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// si recuperano i dati dal modello
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
Le righe 4-6 sono state aggiunte per creare il modello necessario alla pagina delle righe 11-13.
[erreurs.jsp]:
<%
// -- test: si crea il modello della pagina
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// si recuperano i dati dal modello
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
Le righe 4-8 sono state aggiunte per creare il modello richiesto dalla pagina alle righe 13-14.
Avviamo Tomcat, se non è già stato fatto, quindi richiediamo i seguenti URL:
![]() | ![]() |
![]() |
Otteniamo effettivamente le visualizzazioni previste.
6.6. Il controller [ServletPersonne]
Il controller [ServletPersonne] dell'applicazione web [/personne2] gestirà le seguenti azioni:
n. | richiesta | origine | elaborazione |
1 | [GET /personne2/main] | URL digitato dall'utente | - inviare la vista [formulaire] vuota |
2 | [POST /personne2/main] con parametri [txtNom, txtAge, azione] inviati | clic sul pulsante [Envoyer] nella vista [formulaire] | - verificare i valori dei parametri [txtNom, txtAge] - se non sono corretti, inviare la vista [erreurs(erreurs)] - se sono corretti, inviare la vista [reponse(nom,age)] |
3 | [GET /persona2/main? action=ritornoModulo] | clic sul link [Torna al modulo] delle viste risposta] e [erreurs]. | - inviare la vista [formulaire] precompilata con gli ultimi valori inseriti |
Abbiamo quindi una nuova azione da gestire: [GET /personne2/main?action=retourFormulaire].
6.6.1. Struttura del controller
Lo scheletro del controller [ServletPersonne] è quasi identico a quello della versione precedente:
Le novità:
- riga 4: l’uso di una sessione richiede l’importazione del pacchetto [HttpSession]
- righe 28-30: il nuovo metodo [doRetourFormulaire] gestisce la nuova azione: [GET /personne2/main?action=retourFormulaire].
6.6.2. Inizializzazione del controller [init]
Il metodo [init] è identico a quello della versione precedente. Verifica la presenza nel file [web.xml] degli elementi dichiarati nella tabella [paramètres]:
- riga 5: sono stati aggiunti i parametri [urlControleur] (URL del controller) e [lienRetourFormulaire] (testo del link delle viste [réponse] e [erreurs]).
6.6.3. Il metodo [doGet]
Il metodo [doGet] deve gestire l'azione [GET /personne2/main?action=retourFormulaire] che prima non esisteva:
- righe 6-14: si verifica che l'elenco degli errori di inizializzazione sia vuoto. In caso contrario, viene visualizzata la vista [erreurs(erreursInitialisation)] che segnalerà l'errore o gli errori.
Per comprendere questo codice, è necessario ricordare il modello della vista [erreurs]:
<%
// si recuperano i dati dal modello
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
La vista [erreurs] si aspetta un elemento chiave "errori" nella richiesta. Il controller crea questo elemento alla riga 8. Si aspetta inoltre un elemento chiave "lienRetourFormulaire". Il controller crea questo elemento alla riga 9. In questo caso il testo del link sarà vuoto. Non ci sarà quindi alcun link nella vista [erreurs] inviata. Infatti, se si sono verificati errori durante l’inizializzazione dell’applicazione, questa deve essere riconfigurata. Non è necessario proporre all’utente di proseguire l’applicazione tramite un link.
- righe 34-37: elaborazione della nuova azione [GET /personne2/main?action=retourFormulaire]
6.6.4. Il metodo [doInit]
Questo metodo elabora la richiesta n. 1 [GET /personne2/main]. Per questa richiesta, deve inviare la vista [formulaire(nom,age)] vuota. Il suo codice è il seguente:
- riga 4: la sessione corrente viene recuperata se esiste, altrimenti viene creata (parametro true di getSession).
- righe 9-10: viene visualizzata la vista [formulaire]. Ricordiamo il modello previsto da questa vista:
<%
// si recuperano i dati dal modello
String nom=(String)session.getAttribute("nom");
String age=(String)session.getAttribute("age");
String urlAction=(String)request.getAttribute("urlAction");
%>
- righe 6-7: gli elementi [nom,age] del modello della vista [formulaire] vengono inizializzati con stringhe vuote e inseriti nella sessione, poiché è lì che la vista li attende.
- riga 8: l’elemento [urlAction] del modello viene inizializzato con il valore del parametro [urlControleur] del file [web.xml] e inserito nella query.
6.6.5. Il metodo [doValidationFormulaire]
Questo metodo elabora la richiesta n. 2 [POST /personne2/main] in cui i parametri inviati sono [action, txtNom, txtAge]. Il suo codice è il seguente:
- righe 5-6: si recuperano dalla richiesta del cliente i valori dei parametri "txtNom" e "txtAge".
- righe 8-10: si memorizzano questi valori nella sessione per poterli recuperare quando l’utente cliccherà sul link [Retour au formulaire] delle viste [réponse] e [erreurs].
- righe 12-19: viene verificata la validità dei valori dei due parametri
- righe 21-28: se uno dei parametri è errato, viene visualizzata la vista [erreurs(erreurs,lienRetourFormulaire)]. Ricordiamo il modello di questa vista:
<%
// si recuperano i dati dal modello
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
- righe 30-34: se entrambi i parametri "txtNom" e "txtAge" recuperati hanno valori validi, viene visualizzata la vista [reponse(nom,age,lienRetourFormulaire)]. È necessario ricordare il modello della vista [reponse]:
<%
// si recuperano i dati dal modello
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
6.6.6. Il metodo [doRetourFormulaire]
Questo metodo elabora la richiesta n. 3 [GET /personne2/main?action=retourFormulaire]. Il suo codice è il seguente:
Al termine di questo metodo, deve essere visualizzata la vista [formulaire] precompilata con gli ultimi dati inseriti dall’utente. Ricordiamo il modello della vista [formulaire]:
<%
// si recuperano i dati dal modello
String nom=(String)session.getAttribute("nom");
String age=(String)session.getAttribute("age");
String urlAction=(String)request.getAttribute("urlAction");
%>
Il metodo [doRetourFormulaire] deve quindi ricostruire il modello precedente.
- riga 4: si recupera la sessione in cui il controller ha memorizzato i valori (nome, età) inseriti.
- riga 7: si recupera il nome dalla sessione
- righe 8-9: se non è presente, lo si inserisce con un valore vuoto. Questo caso non dovrebbe verificarsi nel normale funzionamento dell’applicazione, poiché l’azione [retourFormulaire] ha sempre luogo dopo l’azione [validationFormulaire], ovvero dopo l’inserimento in sessione dei dati inseriti. Tuttavia, una sessione può scadere poiché ha una durata limitata, spesso di alcune decine di minuti. In questo caso, la riga 4 ha ricreato una nuova sessione in cui non sarà presente il nome. Si inserisce quindi un nome vuoto nella nuova sessione.
- righe 11-13: si procede allo stesso modo per l’età
- se si ignora il problema della sessione scaduta, allora le righe 3-13 sono superflue. Gli elementi [nom,age] del modello sono già presenti nella sessione. Non è quindi necessario reinserirli.
- riga 15: si imposta il valore dell’elemento [urlAction] del modello
6.7. Tests
Avviare o riavviare Tomcat. Richiedere l’URL [http://localhost:8080/personne2], quindi riprendere i test illustrati nell’esempio al paragrafo 6.1.
















