• Aucun résultat trouvé

S2. En pratique

Dans le document Applications orientées données (Page 44-50)

Tout cela est un peu abstrait sans doute pour l’instant, mais l’essentiel est dit et nous vous invitons à revenir aux quelques paragraphes qui précèdent chaque fois que c’est nécessaire pour bien vous imprégner des principes fonda-mentaux du MVC.

Applications orientées données, Version 1.1

<body>

Vous pouvez convertir une température exprimée en

<b>Celsius</b> en une valeur exprimée en

<b>Fahrenheit</b>.

<hr />

<form method="post"

action="${pageContext.request.contextPath}/convertisseur">

Valeur en Celsius: <input type="text" size="20" name="celsius" /> <br />

<input type="submit" value="Convertir" />

</form>

<hr />

</body>

</html>

Pour ce qui concerne le HTML proprement dit, notez que la méthode HTTP choisie quand on soumet le formulaire est post. Et notez également qu’un paramètre HTTP nommécelsiusest alors transmis à l’URL :

${pageContext.request.contextPath}/convertisseur

Cette expression${pageContext.request.contextPath} représente l’URL contextuelle de notre servlet convertisseur(que nous allons bientôt créer), autrement dit le domaine et chemin menant à notre application, dans le contexte particulier où elle est déployée. Dans notre environnement de développement, cette expression prend la valeurhttp://localhost:8080/nsy135, mais lors d’un déploiement éventuel, l’URL contextuelle sera probablement quelque chose de la formehttp://mondomaine.com/convertisseur. Il serait bien dommage (en fait, inaceptable) de coder “en dur” ce genre d’information, avec la sanction d’avoir à changer le code à chaque changement d’environnement. Les JSP nous permettent d’éviter ce genre de désagrément en utilisant des expressions dynamiques évaluées au moment de l’exécution.

Pour créer cette JSP, dans Eclipse, utilisez l’optionNewet le choixJSP page. Par défaut Eclipse place les JSP dans la racine du site, à savoirWebContent. Vous pouvez garder ce choix pour l’instant. Copiez/collez le code ci-dessus dans une page que vous pouvez appeler (par exemple)convinput.jsp.

Ce n’est pas plus compliqué que cela, et de fait cette page est directement accessible à l’adresse : http://localhost:8080/nsy135/convinput.jsp

Vous devriez obtenir un affichage semblable à celui de la figureAffichage du formulaire du convertisseur..

FIGURE4.2 – Affichage du formulaire du convertisseur.

4.2. S2. En pratique 41

Rien de particulier à ce stade, l’affichage est celui d’un formulaire HTML.

Note : Ceux parmi vous qui ont déjà intégré fortement les principes du modèle MVC peuvent froncer les sourcils en se disant : “est-il normal d’accéder à une vue sans passer par un contrôleur ?” Et ils ont raison, mais patience, tout sera dévoilé en temps et en heure.

4.2.2 Le contrôleur : une servlet

Notre contrôleur est une servlet, que nous créons selon la procédure habituelle avec notre Eclipse (faut-il vous la ré-expliquer ?). Appelons-làConvertisseur.javaet associons-là à l’URL/convertisseur. Si vous ne com-prenez pas la phrase qui précède, relisez les explications pour la création deservletue nous avons détaillés à la fin du chapitreEnvironnement Java.

Nous allons définir les deux méthodesdoGetetdoPostde manière à ce que d’une part la première affiche notre formulaire précédemment créé, et que d’autre part la seconde reçoive le paramètre de ce formulaire et effectue la conversion de la température saisie. Il s’agit d’une implantationextrêmement basique(et insatisfaisante) de la notion d’actionprésentée au début de ce chapitre, mais elle nous suffira pour l’instant.

Voici donc la méthodedoGet, déclenchée quand on envoie un messageGETà l’URL/convertisseur.

/**

* Méthode Get: on affiche le formulaire

*/

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String maVue = "/convinput.jsp";

RequestDispatcher dispatcher =

getServletContext().getRequestDispatcher(maVue);

dispatcher.forward(request,response);

}

Cet exemple est très simple et nous permet d’apprendre une nouvelle technique : ladélégationpar le contrôleur (la servlet) de tout ce qui concerne l’affichage à lavue(la JSP). Le code consiste donc à indiquer quelle JSP on veut déclencher (ici c’estconvinput.jsp, que l’on prend dans la racine du site, soitWebContent) et à transmettre, en fin de méthode, le flot de l’exécution avec la méthodeforwardà cette JSP.

C’est donc la mise en application du principe MVC qui veut que le contrôleur recoive les requêtes (ici, pour l’instant, on n’en fait rien), applique les fonctionnalités métiers implantés par les modèles (ici, pour l’instant, il n’y en a pas) et finalement transmette à la vue les éléments nécessaires à l’affichage.

On pourrait aller un peu plus loin en adoptant la convention suivante : la vue (JSP) porte le même nom que la serv-let, et on lui transfère systématiquement l’exécution. Il n’y aurait plus le moindre code à produire ! C’est en fait le comportement par défaut appliqué par certainsframeworks, d’où leur aspect parfoismagiquequand on les découvre.

Important : nous avons maintenant deux manières d’appeler notre page JSP : directement, ou en passant par la servlet.Dans une approche MVC, seule la seconde est bonne. Pour interdire la première, il faudrait placer la JSP dans un répertoire inaccessible par une URL. Un bon candidat pour cela est le répertoireWEB-INF.

Cette approche (interdiction d’exécuter une vue) est en fait forcée par lesframeworksdonc nous n’aurons plus à nous poser ce genre de question quand nous y aurons recours.

4.2.3 Le modèle : une classe Temperature

Notre modèle est on ne peut plus simple : il consiste en une classe représentant une température, et capable de fournir la valeur de cette température en degrés Celsius ou Farenheit.

Applications orientées données, Version 1.1

La classeTemperaturedonnée ci-dessous va suffire à nos besoins.

package modeles;

/**

* Une classe permettant d’obtenir une température en Celsius ou Farenheit.

*

*/

public class Temperature { /**

* La valeur, exprimée en degrés Celsius

*/

private double celsius;

/**

* Le constructeur, prend des Celsius en paramètres

*/

public Temperature(double valeurCelsius) {

celsius = valeurCelsius;

} /**

* Pour obtenir la valeur en Celsius

*

* @return Valeur de la température en Celsius

*/

public double getCelsius() { return celsius;

} /**

* Pour obtenir la valeur en Fahrenheit

*

* @return Valeur de la température en Farenheit

*/

public double getFahrenheit() { return (celsius * 9/5) + 32;

} }

Remarquez que nous suivons les bonnes pratiques de base de la programmation objet, entre autres : – aucune propriété n’est publique ;

– des méthodessetetget, au nommage normalisé, servent à lire/écrire les propriétés ;

– les commentaires sont abondants et permettront de produire unejavadocpour documenter le projet.

De plus, conformément aux principes du MVC, cette classe est totalement indépendante du contexte Web. Elle peut en fait être utilisée dans n’importe quelle application Java. Il serait évidemment souhaitable de l’enrichir avec quelques méthodes, par exemple pour l’initialiser à partir d’une valeur en Fahrenheit et pas en Celsius, pour ajouter des tempé-ratures, etc. Je vous laisse ce plaisir.

Pour créer cette classe, vous devriez pouvoir trouver la démarche tout seul maintenant. Utilisez à nouveau l’option Newdu menu contextuel du projet, et prenez le choixClassdans le menu déroulant. Nous avons placé notre classe dans lepackagemodeles, le fichier sera donc sauvegardé danssrc/modeles.

4.2. S2. En pratique 43

4.2.4 La seconde action : conversion

Equipés de ce modèle, nous sommes prêts à recevoir une température (en Celsius) entrée par l’utilisateur, à la convertir et à l’afficher. La conversion correspond à une seconde action que nous implantons dans la méthodedoPostde notre servlet. La voici :

1 /**

2 * Méthode Post: on affiche la conversion

3 */

4 protected void doPost(HttpServletRequest request, HttpServletResponse response)

5 throws ServletException, IOException {

6 // On devrait récuperer la valeur saisie par l’utilisateur

7 String valCelsius = request.getParameter("celsius");

8

9 if (valCelsius.isEmpty()) {

10 // Pas de valeur: il faudrait afficher un message, etc.

11 valCelsius = "20";

12 }

13

14 // Action: appliquons le convertisseur. Espérons que valCelsius représente

15 // bien un nombre, sinon...

16 Temperature temp = new Temperature(Double.valueOf(valCelsius));

17 // Enregistrons l’objet dans la requête

18 request.setAttribute("temperature", temp);

19

20 // Transfert à la vue

21 String maVue = "/convoutput.jsp";

22 RequestDispatcher dispatcher =

23 getServletContext().getRequestDispatcher(maVue);

24 dispatcher.forward(request,response);

25 }

Décomposons ce code. La première étape consiste à récupérer le paramètre saisi par l’utilisateur. Souvenez-vous de notre formulaire et de son champcelsius. Ce champ, quand l’utilisateur valide le formulaire, devient un paramètre celsiusde larequêteHTTP. C’est donc logiquement par l’objetrequestque nous pouvons récupérer la valeur de ce paramètre :

String valCelsius = request.getParameter("celsius");

Deux remarques s’imposent : (i) on récupère des chaînes de caractères, car les paramètres HTTP ne sont pas typés, (ii) rien ne garantit que l’utilisateur a vraiment saisi une valeur avant d’appuyer sur le bouton, et encore moins que cette valeur est convertible en numérique. Il y aurait toute une phase de contrôle à intégrer dans le code, que nous nous épargnons ici.

Passons donc directeent à la suite : on instancie un objet de notre classeTemperatureavec la valeur du paramètre : Temperature temp = new Temperature(Double.valueOf(valCelsius));

C’est ici que le logique “métier” de l’application intervient sous la forme d’un objet du modèle. Pas question de mettre directementdans le code du contrôleur la conversion de Celsius en Fahrenheit, car elle ne serait pasréutilisabledans un autre contexte. Le contrôleur se charge des interactions, de la coordination des composants, et c’est tout.

Nous en arrivons à une partie importante et pas forcément évidente à comprendre dans un premier temps : comment passer à lavue, qui va se charger de l’affichage, l’information à afficher, à savoir la température ? Le principe est que la servlet et la vuepartagentun certain nombre d’objets formant lecontextede l’exécution d’une requête côté serveur.

Parmi ces objets, on trouverequestet quelques autres (sessionpar exemple) que nous découvrirons ensuite.

Applications orientées données, Version 1.1

En conséquence : toute information disponible dansrequestsera accessible par la vue JSP. Par ailleurs, l’objet requesta la capacité d’enregistrer desattributsdont la valeur peut être n’importe quel objet java. Ici, nous créons donc un nouvel attribut derequest, nommétemperature, et nous lui affectons notre objet-modèle :

request.setAttribute("temperature", temp);

C’est le mécanisme général : la servlet place dansrequestles informations dont la vue a besoin, et déclenche ensuite la vue (ici,convoutput.jsp) avec la méthodeforwardque nous avons déjà rencontrée. Il reste à voir comment la vue gère cet affichage.

4.2.5 L’autre vue JSP

La voici.

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Résultat de la conversion</title>

</head>

<body>

<p>Vous avez demandé la conversion en Fahrenheit de la valeur en Celsius ${requestScope.temperature.celsius}</p>

<p>

<b>Et le résultat est: ${requestScope.temperature.fahrenheit}

degrés Fahrenheit </b>!

</p>

</body>

</html>

Toute la nouveauté (et la “magie” de la chose ) tient à ces expressions intégrées au HTML :

${requestScope.temperature.celsius}

Elles offrent une syntaxe extrêmement simple pour accéder aux objets placés dans le contexte de la vue par la servlet.

Le seul de ces objets que nous avons utilisés pour l’instant est la requête, désignée ici parrequestScope. L’expres-sionrequestScope.temperaturefait donc référence àl’attributtemperatureque nous avons ajouté à la requête avant l’appel au JSP.

Et finalement que signifie temperature.celsius? C’est ici qu’un peu de magie basée sur la convention de codage intervient : le contexte d’exécution “devine” quetemperature.celsius est une valeur obtenue par la méthodegetCelsius()appliquée à l’objettemperature. La convention de nommage (celle dite desjava beans, à base degettersetsetters) permet cette substitution.

Nous avons fini ce premier tour, minimaliste mais complet, d’une application MVC écrite avec JEE. Créez cette page JSP avec Eclipse, ajoutez à la servlet les deux méthodesdoGetetdoPostvues ci-dessus, et exécutez votre application qui devrait afficher un résultat de conversion semblable à celui de la figureAffichage de la seconde JSP.

Il est maintenant probablement profitable pour vous de faire quelques modifications au code, de bien réfléchir aux mécanismes d’échange, au rôle des différents composants, etc. Vous êtes donc invités à effectuer l’exercice suivant.

Exercice : compléter notre convertisseur

4.2. S2. En pratique 45

FIGURE4.3 – Affichage de la seconde JSP

Il s’agit de compléter naturellement les classes, controleurs et JSP donnés en exemple précédemment pour permettre la saisie d’une valeur en Celsius OU ou Fahrenheit. L’application doit effectuer la conversion dans l’autre unité et produire l’affichage approprié.

Passez ensuite à la dernière session qui va récapituler ce que nous avons appris et en tirer un bilan.

Dans le document Applications orientées données (Page 44-50)