10. Applicazione web MVC [personne] – versione 5
10.1. Introduction
In questa versione apportiamo due modifiche:
La prima riguarda il modo in cui il client indica al server l’azione che desidera eseguire. Finora questa veniva specificata tramite un parametro denominato [action] nella richiesta del client GET o POST. In questo caso, l’azione sarà specificata dall’ultimo elemento dell’URL richiesto dal client, come mostra la seguente sequenza:

In [1], l’URL a cui è stato inviato il modulo è [/personne5/do/validationFormulaire]. È l’ultimo elemento [validationFormulaire] dell’URL che ha permesso al controller di riconoscere l’azione da eseguire. In [2], l'azione POST, generata dal link [Retour au formulaire], è stata eseguita all'URL [/personne5/do/retourFormulaire]. Anche in questo caso, l’ultimo elemento [retourFormulaire] dell’URL indica al controller l’azione da eseguire.
Introduciamo questa modifica perché è il metodo utilizzato dai framework di sviluppo web più diffusi, come Struts o Spring MVC.
Tutti gli URL dell'applicazione avranno il formato [/personne5/do/action]. Il file [web.xml] dell'applicazione [/personne5] indicherà che quest'ultima accetta URL del formato [/do/*]:
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
Il controller recupererà il nome dell'azione da eseguire nel modo seguente:
Il metodo [getPathInfo] dell’oggetto [request] restituisce l’ultimo elemento dell’URL della richiesta.
La seconda modifica riguarda il modo in cui vengono memorizzati i dati inseriti dall'utente tra due cicli di richiesta/risposta. Al momento, queste informazioni vengono memorizzate in una sessione. Questo metodo può presentare degli svantaggi se ci sono molti utenti e molti dati da memorizzare per ciascuno di essi. Infatti, ogni utente ha la propria sessione personale. Inoltre, la sessione rimane attiva per un certo tempo dopo che l’utente si è disconnesso, a meno che non sia stata prevista un’opzione di disconnessione. Pertanto, 1000 sessioni da 1000 byte occuperanno 1 MB di memoria. Si tratta comunque di un requisito moderato e sono poche le applicazioni che hanno 1000 sessioni attive contemporaneamente.
Tuttavia, esistono alternative alla sessione, meno onerose in termini di memoria, ed è bene conoscerle. In questo caso utilizzeremo il metodo dei cookie. Illustriamolo con un esempio.
Fase 1: l’utente invia un modulo:
![]() |
Questo ciclo richiesta/risposta dà luogo ai seguenti scambi HTTP tra il client e il server:
[1] : [demande du client]
Si tratta di un classico POST. Non c'è nulla di particolare da segnalare qui, se non che, sebbene non si intenda utilizzare una sessione, il server web ne crea comunque una. Lo si nota dal token di sessione che il browser rinvia al server alla riga 11 e che aveva ricevuto in precedenza dal server.
[2]: [réponse du serveur]
Si nota che alle righe 3 e 4 sono state inviate al browser client le intestazioni HTTP e [Set-Cookie], una per il nome (riga 3) e una per l’età (riga 4). I valori di questi cookie corrispondono a quelli inviati alla riga 14 dei cookie POST e [1] sopra riportati.
Fase 2: Ritorno al modulo

Questo ciclo richiesta/risposta dà luogo ai seguenti scambi HTTP tra il client e il server:
[1]: [demande du client]
Qui assistiamo al POST generato dal clic sul link [Retour au formulaire]. Alla riga 11, vediamo che il browser rinvia al server i cookie che ha ricevuto ([nom, age, JSESSIONID]) tramite l’intestazione HTTP [Cookie]. Questo è il principio di funzionamento dei cookie: il client rinvia al server i cookie che quest’ultimo gli ha inviato. In questo esempio, il controller riceverà i valori [pauline, 18] che dovrà inserire nei campi [txtNom, txtAge] della vista [formulaire] visualizzata in [2].
[2] : [réponse du serveur]
Non c'è nulla di particolare da segnalare, se non il fatto che in questa risposta il server non ha inviato alcun cookie. Ciò non impedirà al browser di rinviare, nel prossimo scambio, tutti i cookie ricevuti dal server, anche se ciò non serve a nulla. Si riduce quindi la pressione sulla memoria disponibile del server a costo di un aumento del flusso di caratteri negli scambi client/server.
10.2. Il progetto Eclipse
Per creare il progetto Eclipse [mvc-personne-05] dell’applicazione web [/personne5], si duplicherà il progetto [mvc-personne-04] seguendo la procedura descritta al paragrafo 6.2.
![]() | ![]() |
10.3. Configurazione dell'applicazione web [personne5]
Il file web.xml dell’applicazione /personne5 è 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-05</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
...
</servlet>
<!-- Mappatura ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</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 che per alcuni dettagli:
- riga 6: il nome visualizzato dell’applicazione web è cambiato in [mvc-personne-05]
- riga 18: gli URL gestiti dall’applicazione hanno il formato [/do/*]. In precedenza, veniva gestito solo l’URL [/main]. Ora, il numero di URL corrisponde a quello delle azioni da elaborare.
La pagina iniziale [index.jsp] cambia:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<c:redirect url="/do/formulaire"/>
- riga 5: la pagina [index.jsp] reindirizza il client all'URL [/personne5/do/formulaire], il che equivale a richiedere al controller di eseguire l'azione [formulaire].
10.4. Il codice delle viste
Le viste [formulaire, réponse, erreurs] subiscono poche modifiche. L'unica modifica deriva dal fatto che l'azione da eseguire non è più specificata come in precedenza, quando era definita in un campo nascosto denominato [action] dei moduli inviati via POST. Ora è definita nell’URL di destinazione dei moduli inviati, c.a.d, nell’attributo [action] del tag <form>:
[formulaire.jsp]:
...
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
...
</script>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" action="validationFormulaire" method="post">
...
</form>
</center>
</body>
</html>
- riga [13]: il parametro [action] del modulo ricompare dopo essere scomparso per un certo periodo nelle versioni precedenti. Per comprendere il valore di questo attributo in questo contesto, occorre ricordare che tutti gli URL elaborati dall’applicazione hanno la forma [/do/action]. Riga [13]: l’attributo [action] ha come valore un URL relativo (che non inizia con /). Pertanto, il browser lo completerà con l’URL della pagina attualmente visualizzata, quindi necessariamente un URL della forma [/do/action]. L’ultimo elemento verrà sostituito dall’URL relativo dell’attributo [action] del tag <form> per ottenere l’URL [/do/validationFormulaire] come destinazione di POST.
- Il campo nascosto [action] è scomparso
[réponse.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- riga [7]: la destinazione di POST sarà [/do/retourFormulaire]
- il campo nascosto [action] è scomparso nel modulo delle righe 7-8.
[erreurs.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- riga [6]: la destinazione di POST sarà [/do/retourFormulaire]
- il campo nascosto [action] è scomparso nel modulo alle righe 6-7.
Si invita il lettore a testare queste nuove viste seguendo il principio illustrato nelle versioni precedenti.
10.5. Il controller [ServletPersonne]
Il controller [ServletPersonne] dell’applicazione web [/personne5] gestirà le seguenti azioni:
n. | richiesta | origine | elaborazione |
1 | [GET /personne5/do/formulaire] | URL digitato dall'utente | - inviare la vista [formulaire] vuota |
2 | [POST /persona5/do/validationFormulaire] con i parametri [txtNom, txtAge] pubblicati | cliccando 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 | [POST /persona5/do/retourFormulaire] senza parametri inviati | clic sul link [Torna al modulo] delle visualizzazioni [réponse] e [erreurs]. | - inviare la vista [formulaire] precompilata con gli ultimi valori inseriti |
Lo scheletro del controller [ServletPersonne] è identico a quello della versione precedente. Esaminiamo le modifiche apportate ai metodi [doValidationFormulaire, doRetourFormulaire, doGet], poiché i metodi [init, doInit, doPost] non subiscono variazioni.
10.5.1. Il metodo [doGet]
Il metodo [doGet] non recupera l’azione da eseguire allo stesso modo delle versioni precedenti:
- riga 12: si recupera l'azione da eseguire. Essa ha la forma [/action].
- righe 18-22: elaborazione dell’azione [/formulaire] richiesta da una richiesta GET
- righe 23-27: elaborazione dell'azione [/validationFormulaire] richiesta da una richiesta POST
- righe 28-32: elaborazione dell'azione [/retourFormulaire] richiesta da una richiesta POST
10.5.2. Il metodo [doValidationFormulaire]
Questo metodo elabora la richiesta n. 2 [POST /personne5/do/validationFormulaire] con [txtNom, txtAge] negli elementi inviati. Il suo codice è il seguente:
Novità:
- il metodo [doValidationFormulaire] invia in risposta una delle viste [réponse, erreurs]. Indipendentemente dalla risposta, il controller inserisce due cookie, righe 8-9. Un cookie è rappresentato da un oggetto [Cookie] il cui costruttore accetta due parametri: la chiave del cookie e il valore ad essa associato.
- riga 8: il valore inserito per il nome viene inserito in un cookie con chiave "nom"
- riga 9: il valore inserito per l’età viene inserito in un cookie con chiave "age"
- Un cookie viene aggiunto alla risposta HTTP inviata al client tramite il metodo [response.addCookie]. Questa risposta viene qui solo preparata. Verrà effettivamente inviata solo quando verrà eseguita la pagina JSP della vista inviata al client.
10.5.3. Il metodo [doRetourFormulaire]
Questo metodo elabora la richiesta n. 2 [POST /personne5/do/retourFormulaire] senza elementi inviati. Il suo codice è il seguente:
Novità:
Il metodo [doRetourFormulaire] deve visualizzare un modulo precompilato con gli ultimi dati inseriti. Nella versione precedente, questi dati erano memorizzati nella sessione. In questa versione, non si utilizza più la sessione, ma i cookie per memorizzare gli elementi tra uno scambio e l’altro tra client e server. Quando il cliente ha richiesto la convalida del modulo, ha ricevuto in risposta la vista [réponse] o [erreurs] a seconda dei casi, accompagnata da due cookie denominati "nome" e "età". Quando si clicca sul link [Retour au formulaire] presente in queste due viste, che genera un POST sull’URL [/do/retourFormulaire], il browser rinvierà al server i due cookie che ha ricevuto.
- righe 4-18: si recuperano i valori dei cookie denominati "nome" e "età". Stranamente, non esiste un metodo che consenta di ottenere il valore di un cookie a partire dalla sua chiave. Pertanto, si è costretti a esaminare uno per uno tutti i cookie ricevuti.
- Fatto ciò, i due valori ottenuti vengono inseriti nel modello della vista [formulaire] (righe 20-21) affinché questa li visualizzi.
10.6. Tests
Avviare o riavviare Tomcat dopo avervi integrato il progetto Eclipse [personne-mvc-05], quindi richiedere l’URL [http://localhost:8080/personne5].


