12. Webapplicatie MVC [personne] – versie 7
12.1. Introduction
In deze versie gaan we ervan uit dat er clientbrowsers kunnen zijn die het volgende hebben uitgeschakeld:
- het terugsturen van cookies die door de server worden verzonden
- de uitvoering van JavaScript-code die is ingebed in de weergegeven HTML-pagina’s
We willen echter dat dit soort browsers onze applicatie kan gebruiken. Punt 2 brengt ons terug naar versie 2 van onze applicatie, aangezien JavaScript pas vanaf versie 3 werd gebruikt. In versie 2 werkte de applicatie zonder JavaScript, dus punt 2 is opgelost.
Punt 1 kan al dan niet lastig zijn om op te lossen. Versie 6 van onze applicatie werkte zonder cookies. Door versie 2 en 6 samen te voegen, bereiken we het gewenste resultaat. We voegen nog een extra vereiste toe: de applicatie moet een sessie beheren. Dit is geen zinloze vereiste. In een applicatie waar gebruikers zich moeten authenticeren, moet de server de combinatie (gebruikersnaam/wachtwoord) van de gebruiker onthouden, zodat deze zich niet bij elke opgevraagde pagina opnieuw hoeft te authenticeren.
Tot nu toe hebben we drie oplossingen gebruikt om informatie op te slaan tijdens de communicatie tussen client en server:
- de sessie
- cookies
- verborgen velden.
Oplossing 2 kan worden uitgesloten, aangezien de browser van de gebruiker het gebruik van cookies mogelijk heeft geblokkeerd.
Oplossing 3 is die van versie 6 die we eerder hebben besproken. Deze kan om veiligheidsredenen niet worden gebruikt. Als de combinatie (gebruikersnaam/wachtwoord) in elke pagina die naar de browser wordt verzonden is ingekapseld, betekent dit dat deze bij elke uitwisseling tussen client en server over het netwerk wordt verzonden. Dit is niet goed voor de veiligheid van de applicatie. Men kan dan overwegen om het protocol HTTPS te gebruiken, dat de communicatie tussen client en server versleutelt. Maar het gebruik ervan voor elke pagina van de applicatie zal de belasting van de server verhogen.
Men zou oplossing 1 wellicht willen uitsluiten omdat deze ook op cookies is gebaseerd. Bij de eerste uitwisseling tussen client en server stuurt de server een sessietoken naar de client, dat de client bij elk nieuw verzoek naar de server terugstuurt. Dankzij dit token kan de server zijn client herkennen en hem informatie toewijzen die tijdens een eerdere uitwisseling was opgeslagen. Het sessietoken wordt door de server in een cookie verzonden. De browser die cookies niet heeft uitgeschakeld, kan dit cookie bij volgende verzoeken terugsturen. Als cookies zijn uitgeschakeld, is er een andere oplossing: de browser kan het sessietoken opnemen in de URL die hij opvraagt. Dit zien we nu als we het bestand [index.jsp] van versie 4 opnieuw bekijken:
<%@ 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="/main"/>
Ter herinnering: regel 5 hierboven leidt de client om naar de URL [/personne4/main?jsessionid=XX], waarbij XX het sessietoken is, zoals te zien is in de onderstaande schermafbeelding die is gemaakt na het opvragen van de URL [http://localhost:8080/personne4]:

Laten we eens nader bekijken hoe de tag <c:redirect> werkt met betrekking tot het sessietoken. Laten we een browser nemen waarin cookies worden geaccepteerd. Hieronder configureren we de Firefox-browser:

In [1] schakelen we cookies in en in [2] verwijderen we de bestaande cookies om vanuit een bekende situatie te beginnen. Vervolgens roepen we de URL [http://localhost:8080/personne4] op. We krijgen het volgende antwoord:

Het oorspronkelijke verzoek van de klant, HTTP, luidde als volgt:
We merken alleen op dat de klant geen sessiecookie verstuurt. Het door de server verzonden antwoord HTTP is als volgt:
- regel 1: de server vraagt de klant om door te sturen
- regel 3: de server verstuurt een sessietoken dat gekoppeld is aan het attribuut [JSESSIONID]
- regel 4: de omleidings-URL bevat het sessietoken. De tag <c:redirect> heeft dit erin geplaatst omdat de client geen sessiecookie had verzonden.
De browser, die werd gevraagd om door te sturen, heeft vervolgens het volgende verzoek verzonden:
- regel 1: hij vraagt de omleidings-URL op, inclusief het sessietoken. Daarom geeft de browser op de schermafbeelding deze URL weer.
- regel 10: de browser stuurt het sessietoken terug dat de server hem in de vorige uitwisseling heeft gestuurd. Dit is de normale werking van cookies wanneer deze zijn toegestaan in de browser van de klant. Als dat niet het geval is, worden de ontvangen cookies niet teruggestuurd.
De server heeft het volgende geantwoord op dit tweede verzoek:
Hij heeft de gevraagde pagina gevonden en stuurt deze door. Merk op dat hij het sessietoken niet meer meestuurt. Dit is de normale werking van het sessietoken: het wordt eenmalig door de server in de vorm van een cookie naar de browser gestuurd en de browser stuurt het vervolgens bij elk verzoek terug om zich te laten herkennen.
Laten we nu met dezelfde browser de URL [http://localhost:8080/personne4] opnieuw opvragen door deze handmatig in te voeren. We krijgen dan de volgende pagina te zien:

We zien dat de door de browser weergegeven URL het sessietoken niet meer bevat. Laten we eens kijken naar de eerste uitwisseling tussen client en server:
De browser heeft het volgende verzoek verzonden:
Dit is precies hetzelfde verzoek als de vorige keer, met echter één verschil: op regel 10 stuurt de browser het sessietoken terug dat hij tijdens de allereerste uitwisseling had ontvangen. Nogmaals, dit is de normale werking als de cookies van de browser zijn ingeschakeld.
De server heeft het volgende antwoord verzonden:
Hij vraagt de client om door te sturen. Aangezien hij een sessietoken van de client heeft ontvangen, zet hij deze sessie voort en verstuurt hij geen nieuw sessietoken. Om dezelfde reden neemt de <c:redirect>-tag dit sessietoken niet op in de omleidings-URL. Daarom bevat de URL die in de bovenstaande schermafbeelding wordt weergegeven geen sessietoken.
Hieruit kunnen we de volgende regel onthouden: de tag <c:redirect> neemt het sessietoken alleen op in de omleidings-URL als de client de header HTTP niet heeft verzonden:
Deze regel geldt ook voor de tag <c:url>, die we later nog zullen tegenkomen.
Wat gebeurt er als cookies in de browser zijn uitgeschakeld? Laten we het eens proberen. Eerst zetten we de browser terug naar de standaardinstellingen:

In [1] schakelen we cookies uit en in [2] verwijderen we de bestaande cookies om vanuit een bekende situatie te beginnen. Vervolgens vragen we de URL [http://localhost:8080/personne4] op. We krijgen het volgende antwoord:

We krijgen hetzelfde resultaat als eerder. De uitwisselingen HTTP zijn echter niet precies hetzelfde:
- regels 1-9: verzoek nr. 1 van de browser. Deze verstuurt geen sessiecookie.
- regels 11-17: het antwoord van de server waarin de browser wordt gevraagd om door te sturen naar een andere URL. De server verstuurt een sessiecookie regel 13: de tag <c:redirect> heeft het token opgenomen in de omleidings-URL regel 14.
- regels 19-27: verzoek nr. 2 van de browser. Deze stuurt het sessiecookie dat de server zojuist heeft verzonden niet terug, omdat cookies zijn uitgeschakeld.
- regels 29-33: het antwoord van de server. We zien dat, hoewel de browser geen sessiecookie heeft meegestuurd, de server toch geen nieuwe sessie start, zoals men zou verwachten. Dit blijkt uit het feit dat hij de header HTTP [Set-Cookie] niet verstuurt, zoals hij in regel 13 had gedaan. Dit betekent dat hij de vorige sessie voortzet. Hij heeft deze kunnen terugvinden dankzij het sessietoken in de URL die de browser in regel 19 heeft opgevraagd.
We onthouden dat de server een sessie volgt door het door de client verzonden sessietoken op twee mogelijke manieren op te halen:
- in de header HTTP [Set-Cookie] die door de client is verzonden
- in de door de klant opgevraagde URL
Laten we nu, met dezelfde browser, de URL [http://localhost:8080/personne4] opnieuw opvragen door deze handmatig in te voeren, zoals we deden toen cookies waren toegestaan. We krijgen dan de volgende pagina te zien:

Het resultaat verschilt van dat wat we kregen toen cookies waren toegestaan: het sessietoken staat in de URL die door de browser wordt weergegeven. Laten we dit resultaat toelichten zonder de uitwisselingen HTTP die hebben plaatsgevonden te bestuderen:
[cookies autorisés]
- bij het tweede verzoek voor de URL [http://localhost:8080/personne4] had de clientbrowser het sessiecookie teruggestuurd dat hij bij het eerste verzoek voor dezelfde URL van de server had ontvangen. De tag <c:redirect> had het sessietoken dus niet in het omleidingsadres opgenomen.
[cookies inhibés]
- bij het tweede verzoek voor de URL [http://localhost:8080/personne4] stuurt de clientbrowser het sessiecookie dat hij bij het eerste verzoek voor dezelfde URL van de server had ontvangen niet mee, aangezien zijn cookies zijn uitgeschakeld. De tag <c:redirect> neemt het sessietoken dus op in het omleidingsadres. Daarom is het te zien op de bovenstaande schermafbeelding.
Met de tags <c:redirect> en <c:url> kan het sessietoken in de URL's worden opgenomen. Dit is de oplossing die hier wordt voorgesteld.
12.2. Het Eclipse-project
Om het Eclipse-project [mvc-personne-07] van de webapplicatie [/personne7] aan te maken, dupliceren we het project [mvc-personne-06] volgens de procedure beschreven in paragraaf 6.2.
![]() | ![]() |
12.3. Configuratie van de webapplicatie [personne7]
Het bestand web.xml van de applicatie /personne7 ziet er als volgt uit:
<?xml version="1.0" encoding="UTF-8"?>
...
<display-name>mvc-personne-07</display-name>
...
Dit bestand is identiek aan dat van de vorige versie, behalve regel 3, waar de weergavenaam van de webapplicatie is gewijzigd in [mvc-personne-07]. De startpagina [index.jsp] blijft ongewijzigd.
...
<c:redirect url="/do/formulaire"/>
12.4. De code van de weergaven
De weergaven [formulaire, réponse, erreurs] zijn weer zoals ze waren in versie 2, c.a.d, zonder JavaScript. Ze behouden echter de tags JSTL van de laatste versies.
12.4.1. De weergave [formulaire]

De knoppen die gekoppeld waren aan JavaScript-code zijn verwijderd.
[formulaire.jsp]:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" action="<c:url value="validationFormulaire"/>" 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" name="bouton" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="submit" name="bouton" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
- regel 14: de doel-URL van POST wordt met de tag <c:url> geschreven, zodat het sessietoken daarin aanwezig is voor het geval de client een browser is die de header HTTP [Cookie] niet verstuurt.
- Het formulier bevat twee knoppen van het type [submit]: [Envoyer] (regel 28) en [Effacer] (regel 30). Beide knoppen hebben dezelfde naam: bouton. Bij het klikken op POST zal de browser de parameter verzenden:
- knop=Verzenden als de POST-aanroep is geactiveerd door de knop [Verzenden]
- knop=Wissen als de POST-verzoek is geactiveerd door de knop [Wissen]
Deze parameter helpt ons om de exacte actie te bepalen die moet worden uitgevoerd, aangezien de URL [/do/validationFormulaire] nu overeenkomt met twee verschillende acties.
12.4.2. De weergave [réponse]

[réponse.jsp]:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Personne - réponse</h2>
<hr>
<table>
<tr>
<td>Nom</td>
<td>${nom}</td>
</tr>
<tr>
<td>Age</td>
<td>${age}</td>
</tr>
</table>
<br>
<a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
</body>
</html>
- regel 24: de doel-URL van HREF wordt geschreven met de tag <c:url>, zodat het sessietoken daarin aanwezig is voor het geval de client een browser is die de header HTTP [Cookie] niet verstuurt.
12.4.3. De weergave [erreurs]

[erreurs.jsp]:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<c:forEach var="erreur" items="${erreurs}">
<li>${erreur}</li>
</c:forEach>
</ul>
<br>
<a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
</body>
</html>
- regel 18: de doel-URL van HREF wordt geschreven met de tag <c:url>, zodat het sessietoken daarin aanwezig is voor het geval de client een browser is die de header HTTP [Cookie] niet verstuurt.
De lezer wordt verzocht deze nieuwe weergaven te testen volgens het principe dat in eerdere versies is besproken.
12.5. De controller [ServletPersonne]
De controller [ServletPersonne] van de webapplicatie [/personne7] ziet er als volgt uit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
- regel 35: de actie [/retourFormulaire] wordt uitgevoerd door een GET en niet langer door een POST zoals in de vorige versie.
- regels 70-87: de actie [/validationFormulaire] wordt uitgevoerd door een POST, die wordt geactiveerd door een klik opeen van de knoppen [Envoyer] of [Effacer] in het scherm [formulaire]. De methode [doValidationFormulaire] zorgt ervoor dat deze twee gevallen door twee verschillende methoden worden afgehandeld.
- regels 90-103: de methode [doEnvoyer] komt overeen met de methode [doValidationFormulaire] uit de vorige versie. De ingevoerde gegevens worden in de sessie opgeslagen (regels 96-98), terwijl ze in de vorige versie in de query werden geplaatst.
- regels 58-67: de nieuwe methode [doEffacer] moet een leeg formulier weergeven. Men zou gebruik kunnen maken van de methode [doInit], die deze taak al uitvoert. Hier maken we van de gelegenheid gebruik om ook de elementen [nom, age] uit de sessie te verwijderen, zodat deze de laatste status van het formulier blijft weergeven.
- regels 50-55: vragen om de weergave van de weergave [formulaire] zonder dat het sjabloon van deze weergave zichtbaar wordt geïnitialiseerd. Dit sjabloon bestaat in feite uit de elementen [nom, age] die al in de sessie aanwezig zijn. Meer hoeft er niet te gebeuren.
12.6. Tests
Start Tomcat op of herstart het nadat je het Eclipse-project [personne-mvc-07] erin hebt geïntegreerd, en vraag vervolgens de URL [http://localhost:8080/personne7] op met een browser waarin cookies zijn uitgeschakeld en bestaande cookies zijn verwijderd. Je krijgt het volgende antwoord:

De broncode die de browser ontvangt, is als volgt:
Regel 1: het sessietoken staat in de doel-URL van POST.
Laten we het formulier invullen en verzenden:

De broncode die de browser ontvangt, is als volgt:
Regel 3: het sessietoken staat in de doel-URL van de link.

