Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Jakarta EE
  3. La présentation avec les JSP
Extrait - Jakarta EE Développez des applications web en Java
Extraits du livre
Jakarta EE Développez des applications web en Java Revenir à la page d'achat du livre

La présentation avec les JSP

Introduction

Les servlets ne sont pas adaptées pour gérer efficacement l’affichage comme vous avez pu le constater dans le chapitre précédent. La plateforme Jakarta EE propose une solution nommée JSP (Jakarta Server Pages). Cette technologie permet de créer facilement un contenu dynamique au format HTML ou XML. Elle correspond au V (vue) de l’architecture MVC. La servlet s’occupe de faire le traitement métier et lorsque celui-ci est terminé, elle délègue l’affichage à une JSP. La suite du chapitre prendra comme exemple un contenu HTML.

Les JSP sont, tout simplement, des pages HTML d’extension .jsp dans lesquelles il est possible d’ajouter différents types de contenus (non HTML) qui seront traités par le conteneur de servlets pour générer un rendu spécifique lié au contexte d’exécution de la requête. Ces types de contenus peuvent être :

  • des scripts sous la forme de code Java,

  • des scripts sous la forme d’EL (Jakarta Expression Language),

  • des actions standards,

  • des tags standards (JSTL - Jakarta Standard Tag Library),

  • ou des tags personnalisés.

Le chapitre explique le principe de fonctionnement des JSP puis présente les différents types de contenus listés précédemment.

Différentes technologies sont abordées dans ce chapitre.

Tout d’abord...

Le projet

1. La création du projet

La suite du chapitre se base sur un projet exemple nommé Projet_JSP.

 Commencez par créer un projet de type Gradle Project avec les mêmes caractéristiques que dans le premier chapitre.

 Complétez l’arborescence de répertoires pour qu’elle ressemble à cela :

images/03EP01N.png

 Ajoutez un fichier nommé web.xml dans le répertoire src/main/webapp/WEB-INF avec un contenu équivalent au projet initial (PremierProjetWeb). Veillez simplement à renommer le nom du projet au sein de la balise <display-name>.

 Modifiez le fichier build.gradle avec le contenu suivant (observez la section dependencies permettant de référencer l’API des servlets et l’API des JSP) :

plugins { 
    id 'java' 
    id 'war' 
} 
 
repositories { 
    jcenter() 
} 
 
dependencies { 
    compileOnly "jakarta.servlet:jakarta.servlet-api:5.0.0" 
compileOnly group: 'jakarta.servlet.jsp', name: 
'jakarta.servlet.jsp-api', version: '3.0.0' 
} 

 Sélectionnez le menu contextuel Gradle - Refresh Gradle Project de votre projet pour télécharger les dépendances.

Le projet est prêt pour manipuler...

Le principe d’exécution

Les JSP existent pour simplifier la création d’un contenu dynamique car les servlets ne sont pas adaptées pour cette tâche. Lorsqu’une requête HTTP implique l’exécution d’une JSP, voici les actions qui sont déclenchées :

  • Si la JSP n’a encore jamais servi, celle-ci est transformée en classe Java (Translation phase) avant d’être compilée. La transformation est réalisée par le moteur Jasper 2 et la compilation est réalisée par défaut par le compilateur Java Eclipse JDT (et non pas javac). Pour plus d’informations, veuillez vous référer à la documentation officielle à l’adresse suivante : https://tomcat.apache.org/tomcat-10.0-doc/jasper-howto.html

images/03EP05N.png

Cette classe doit implémenter l’interface jakarta.servlet.Servlet. Dans l’environnement Tomcat, elle dérive indirectement de la classe jakarta.servlet. http.HttpServlet. Une JSP n’est donc ni plus ni moins qu’une servlet. La classe doit aussi implémenter l’interface jakarta.servlet.jsp.HttpJspPage.

Cette interface force l’écriture de la méthode _jspService(...). Cette méthode est l’équivalent des méthodes doXXX(...) des servlets. Elle prend en paramètre un objet de type HttpServletRequest et un objet de type HttpServletResponse. Elle a pour rôle la création d’une réponse à l’utilisateur.

Ensuite, la méthode service(...) de cette nouvelle classe est appelée. Elle appellera la méthode _jspService(...).

Le cycle de vie d’une JSP est le même que celui d’une servlet. La seule différence est le nom des méthodes...

Le paramétrage d’une JSP

Une JSP se trouve naturellement dans le répertoire webapp du projet. Elle est ainsi accessible au travers d’une URL depuis le navigateur d’un client. Cependant, si on souhaite être strict dans l’architecture MVC, il ne faut pas qu’une JSP soit accessible directement au travers d’une URL. Il faut passer par une servlet qui délègue, le moment venu, la génération de la réponse à une JSP. Pour cela, il est possible de déplacer la JSP dans le répertoire WEB-INF, répertoire inaccessible au travers d’une URL.

Le problème est maintenant de pouvoir déléguer la génération de la réponse à la JSP depuis une servlet. Le travail se fait comme pour les servlets en utilisant le RequestDispatcher

Voici un exemple illustrant ce mécanisme :

 Créez une JSP nommée PageProtegee.jsp dans le sous-répertoire WEB-INF/jsp :

images/03EP07N.png

 Créez ensuite une servlet nommée AccesPageProtegee. Le rôle de cette servlet est de déléguer la génération de la réponse à la JSP.

Le code de cette servlet peut être écrit de deux manières différentes :

  • La première manière consiste en l’utilisation de la méthode getRequestDispatcher(...) de l’objet de type...

Les directives

1. Présentation

Les directives sont des messages dirigés vers le conteneur afin de lui donner des indications sur l’étape de transformation. Les directives ne produisent pas de contenu. La syntaxe d’une directive est la suivante :

<%@ nom_de_la_directive {attr="value"}* %> 

Une directive peut posséder plusieurs attributs.

Il existe trois directives :

  • la directive page,

  • la directive taglib,

  • la directive include.

2. La directive page

a. Présentation

Cette directive permet de définir des caractéristiques spécifiques à la page. Ces caractéristiques sont à destination du conteneur pour la phase de transformation. Il peut y avoir plusieurs directives page dans une JSP. Ces directives peuvent être positionnées n’importe où dans la page. Il existe une exception pour les attributs pageEncoding et contentType qui doivent se trouver dans une directive page en haut de la JSP. Chaque attribut ne doit être présent, au maximum, qu’une seule fois. Il existe une exception pour l’attribut import pour permettre l’import de plusieurs packages ou classes dans la JSP.

Si ces règles ne sont pas respectées, une erreur a lieu lors de la phase de transformation.

b. Les attributs de la directive

Voici les attributs disponibles sur la directive page :

  • language : cet attribut permet de définir le langage utilisé pour les scripts écrits dans la JSP devant s’exécuter côté serveur. Jusqu’à maintenant, la seule valeur possible est java. C’est d’ailleurs la valeur par défaut.

  • extends : cet attribut permet de définir le nom de la classe (complètement qualifié) dont dérive la JSP. Cet attribut est à utiliser avec précaution. En l’absence de cet attribut, le conteneur utilise la classe par défaut. Dans l’environnement Tomcat, c’est la classe org.apache.jasper.runtime.HttpJspBase.

  • import : cet attribut permet de définir les imports des packages et des classes nécessaires au fonctionnement des scripts écrits en Java dans la JSP. Cet attribut peut être présent plusieurs fois pour améliorer la lecture. S’il n’est présent qu’une seule fois, les différents imports sont...

Les éléments de script

1. Présentation

Les éléments de script sont très utilisés dans une page JSP. Ils permettent de rendre le contenu dynamique. Il y a deux types de scripts principaux :

  • Les scripts écrits en Java présentés dans les sections suivantes.

  • Les scripts écrits en EL présentés un peu plus loin dans le chapitre.

Les éléments de scripts permettent de faire un mélange de code, classiquement un mélange Java/HTML.

Les exemples de cette section se situent dans le fichier LesElementsDeScript.jsp ;

images/03EP10N.png

2. Les déclarations

a. Présentation

Les déclarations sont des éléments de script permettant de déclarer des variables membres et des méthodes dans la classe Java générée à partir de la page JSP. Le code doit être écrit dans la page JSP entre les balises suivantes :

<%!  Vos variables membres et vos méthodes %> 

Il peut y avoir plusieurs zones de déclarations dans la page JSP. Habituellement, il n’y en a qu’une seule en début de page pour améliorer la lisibilité. Les variables membres et les méthodes déclarées sont utilisables dans les différents éléments de scripts de la page et au travers de l’EL.

b. Un exemple de mise en œuvre

L’exemple suivant montre la déclaration d’une variable membre compteur et une méthode incrementer() :

<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
 
<%! 
      //Déclarations des variables membres et des méthodes 
      private int compteur = 0; 
 
      private void incrementer() 
      { 
        this.compteur++; 
      } 
%> 
<!DOCTYPE html> ...

Les objets disponibles dans une JSP

1. Présentation

Les éléments de script de type scriptlets et expressions sont écrits dans la méthode _jspService(...) lors de la transformation de la page JSP en classe Java. À ce titre, ces éléments de script peuvent accéder aux variables locales de cette méthode. Il existe un certain nombre de variables potentiellement disponibles. Voici cette liste :

  • L’objet request de type HttpServletRequest : cet objet a le même rôle que dans une servlet.

  • L’objet response de type HttpServletResponse : cet objet a le même rôle que dans une servlet.

  • L’objet pageContext de type jakarta.servlet.jsp.PageContext : cet objet permet d’accéder au contexte de la page. Il permet d’accéder aux différents objets présentés dans cette liste. Cet objet met aussi à disposition des méthodes permettant de manipuler les attributs des différents contextes représentés sous la forme de constante :

    • PageContext.APPLICATION_SCOPE,

    • PageContext.REQUEST_SCOPE,

    • PageContext.SESSION_SCOPE,

    • PageContext.PAGE_SCOPE.

    Ces méthodes sont :

    • getAttribute(String name, int scope) : cette méthode permet d’obtenir la valeur d’un attribut dans un contexte donné.

    • setAttribute(String name, int scope) : cette méthode permet d’écrire la valeur d’un attribut dans un contexte donné.

    • removeAttribute(String name, int scope) : cette méthode permet de supprimer la valeur d’un attribut dans un contexte donné.

    • findAttribute(String name) : cette méthode permet d’obtenir la valeur d’un attribut en le cherchant dans les différents contextes dans l’ordre suivant : PAGE_SCOPE, REQUEST_SCOPE, SESSION_SCOPE, APPLICATION_SCOPE. La méthode retourne la première valeur trouvée ou null. Cette méthode est largement utilisée au travers de l’EL.

  • L’objet session de type HttpSession : cet objet a le même rôle que dans une servlet. Cet objet n’est pas disponible si la directive page possède...

La gestion des erreurs

1. Présentation

Par la technologie employée, les erreurs peuvent survenir à deux moments bien distincts. Le premier moment correspond à la phase de transformation. Cette étape peut se traduire par un échec. Le deuxième moment correspond à la phase d’exécution. Un code peu robuste peut provoquer une exception inattendue. Un cas fonctionnel peut provoquer une exception attendue. Les sections suivantes détaillent la gestion de ces différents types d’exception.

2. Les erreurs à la transformation

L’origine des erreurs à la transformation est liée à un problème syntaxique au niveau de la page JSP, par exemple :

  • un mauvais usage des directives,

  • un mauvais usage des éléments de script.

Le résultat est le même soit il y a un problème à la transformation, soit il y a un problème à la compilation de la classe transformée.

L’exemple suivant met en évidence une erreur liée à l’application d’une mauvaise valeur dans l’attribut buffer de la directive page. Le développeur a écrit 10 au lieu de 10kb.

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

L’exemple est disponible au niveau du fichier PageErreurALaTransformation.jsp.

Le résultat est le suivant au moment de l’exécution de la requête :

images/03EP12N.png

Une exception de type JasperException (dans l’environnement Tomcat) indique un problème à la transformation. Le message est suffisamment explicite pour que le développeur...

L’utilisation de fragments

1. Présentation

Une application web classique est composée de plusieurs pages. Chacune de ces pages propose une structure souvent identique avec notamment un en-tête, un pied de page et un menu identiques. Au lieu de réécrire ce code autant de fois qu’il y a de pages, il est préférable de le centraliser dans des fichiers que l’on inclut dans les différentes pages. Ces fichiers ne sont pas des pages web fonctionnelles. Elles n’en contiennent qu’une partie. On parle généralement de fragments. Les sections suivantes montrent deux méthodes d’inclusion d’un fragment.

Une alternative aux fragments est l’utilisation de balises personnalisées. Pour plus d’informations, veuillez vous référer à la section Les balises personnalisées à la fin de ce chapitre.

2. L’inclusion statique

La directive include permet d’inclure une ressource externe dans la JSP au moment de la transformation. L’utilisation de cette directive est décrite dans la section Les directives - La directive include.

Le code du fragment est copié dans chacune des classes Java issues des pages JSP ayant utilisé cette directive. En cas de mise à jour du fragment, l’ensemble des pages JSP doit être transformé de nouveau pour inclure les nouvelles modifications. Mais vous n’avez rien à faire, c’est le serveur Tomcat qui s’en...

Les actions standards

1. Présentation

Les actions standards sont des balises supplémentaires disponibles dans une page JSP pour faciliter sa création. Ces balises sont un substitut aux scriptlets afin de simplifier l’écriture des pages JSP et de rendre ce travail possible par des informaticiens ne maîtrisant pas le langage Java. Les sections suivantes ont pour objectif de présenter les principales.

2. Qu’est-ce qu’un JavaBean ?

Plusieurs balises présentées par la suite utilisent la notion de JavaBean. Un JavaBean est tout simplement une classe Java respectant certaines règles d’écriture :

  • La classe doit proposer un constructeur sans paramètre. Ce constructeur peut être le constructeur implicite disponible par défaut. Si au moins un autre constructeur est défini, à ce moment, il est obligatoire d’ajouter explicitement le constructeur sans paramètre dans la liste des constructeurs disponibles.

  • Les variables membres privées doivent être accessibles au travers d’accesseurs et de mutateurs (getters et setters en anglais). Le nom de ces méthodes est de la forme suivante. Pour une variable membre nommée variable, le getter est getVariable() et le setter est setVariable(...). Ces deux méthodes constituent une propriété (Property).

  • La classe ne doit pas être final. C’est-à-dire qu’elle doit pouvoir être dérivée.

  • La classe doit implémenter l’interface Serializable afin notamment de pouvoir faire transiter l’objet sur le réseau.

Les classes du package fr.editions_eni.jakartaee.models comme la classe Sport sont des JavaBeans :

public class Sport implements Serializable { 
 
    private static final long serialVersionUID = 1L; 
    //VARIABLES MEMBRES 
    private int identifiant; 
    //... 
 
    //ACCESSEURS/MUTATEURS 
    public int getIdentifiant() { 
        return identifiant; 
    } 
    public void setIdentifiant(int identifiant) { 
        this.identifiant = identifiant; 
    } 
    //... 
 
    //CONSTRUCTEURS 
   ...

L’EL (Expression Language)

1. Présentation

L’EL est un langage d’expression efficace pour remplacer le Java dans les pages JSP. Il permet de manipuler les objets Java et d’évaluer des expressions. Il ne permet pas de mettre en place des structures de code comme des conditionnelles ou des répétitives. Pour cela, il est nécessaire de l’utiliser en lien avec des balises JSTL. L’EL est aussi utilisé avec la technologie JSF. Pour plus d’informations à ce sujet, veuillez vous référer au chapitre Le framework de présentation JSF. L’EL est actuellement dans sa version 4.0. La spécification est consultable à l’adresse suivante : https://jakarta.ee/specifications/expression-language/4.0/jakarta-expression-language-spec-4.0.pdf

2. La syntaxe

Une expression EL s’écrit de cette manière :

${ expression } 

L’expression débute par ${ et se termine par }. Entre ces deux bornes se trouve l’expression EL. Les opérateurs . et [] permettent d’accéder aux variables membres et aux méthodes des objets manipulés.

L’exemple suivant permet de lire le nom d’un client :

${client.nom} 

L’exemple suivant permet de lire le premier message d’un client :

${client.messages[0].message} 

L’exemple suivant permet d’appeler la méthode toString() d’un client :

${client.toString()} 

Chaque expression utilisée en dehors des balises JSTL provoque l’affichage du résultat obtenu car la transformation de la page JSP donne le code Java suivant :

out.write((java.lang.String)  
org.apache.jasper.runtime.PageContextImpl. 
    proprietaryEvaluate("${client.nom}", 
                    java.lang.String.class,  
              (javax.servlet.jsp.PageContext) 
                        _jspx_page_context,  
                    null)); 

La méthode write(...) est responsable de l’affichage.

Les sections suivantes permettent de préciser ce fonctionnement et les possibilités offertes. ...

Les balises JSTL

1. Présentation

Les balises JSTL (Jakarta Server Pages Standard Tag Library) ont pour objectif de simplifier la réalisation des pages JSP. Il n’est alors plus nécessaire d’être un développeur Java confirmé pour réaliser des pages JSP. Les balises JSTL sont en version 2.0 et la documentation est accessible à l’adresse suivante : https://jakarta.ee/specifications/tags/2.0/jakarta-tags-spec-2.0.pdf

Les balises JSTL permettent de réaliser des traitements récurrents parmi lesquels on retrouve :

  • la gestion des accès aux ressources,

  • l’internationalisation (i18n) et le formatage,

  • la gestion des accès aux bases de données,

  • la création de contenu XML,

  • la manipulation de chaînes de caractères.

Les balises JSTL sont étroitement liées à l’EL et permettent l’ajout de fonctionnalités comme la mise en place de conditionnelles, d’itérations...

Les balises JSTL sont regroupées en bibliothèques de tags (Tag Libraries). Elles sont au nombre de cinq comme le présente le tableau suivant :

Librairie

URI

Préfixe

La bibliothèque de base (core)

http://java.sun.com/jsp/jstl/core

c

La bibliothèque permettant la manipulation XML

http://java.sun.com/jsp/jstl/x

x

La bibliothèque permettant l’internationalisation

http://java.sun.com/jsp/jstl/fmt

fmt

La bibliothèque permettant l’accès aux bases de données

http://java.sun.com/jsp/jstl/sql

sql

La bibliothèque de fonctions

http://java.sun.com/jsp/jstl/functions

fn

Les sections suivantes présentent les éléments principaux des bibliothèques de base, d’internationalisation et de fonctions.

2. Les modifications du projet

Le JDK et Tomcat n’apportent pas l’archive nativement. Il est nécessaire de la référencer par la suite. Pour cela, il suffit de modifier la section dependencies du fichier build.gradle du projet Projet_JSP :

images/03EP20N.png

N’oubliez pas de mettre à jour le projet en réalisant un clic droit sur le projet et en sélectionnant le menu Gradle - Refresh Gradle Project.

3. L’utilisation d’une librairie dans une JSP

Pour permettre l’utilisation d’une librairie dans une JSP, il faut la référencer à l’aide...

Les balises personnalisées

1. Présentation

Il peut être intéressant de créer des balises personnalisées à l’image des balises JSTL. Ces balises personnalisées pourront ensuite être utilisées dans différents projets améliorant ainsi la productivité. En effet, la bibliothèque JSTL est riche mais des besoins complémentaires et récurrents se font vite sentir. Le terme utilisé pour désigner ces balises personnalisées est tag. Une balise personnalisée est donc un tag correspondant physiquement à un fichier ressemblant fortement à une page JSP.

C’est un peu équivalent au mécanisme des fragments (cf. L’utilisation de fragments). La technologie mise en œuvre est cependant différente. Le tag donne naissance à une classe Java pendant la phase de transformation héritant de la classe jakarta.servlet.jsp.tagext.SimpleTagSupport. Les sections suivantes proposent une brève introduction sur le sujet.

2. La création d’une balise personnalisée

Une balise personnalisée correspond à un fichier d’extension .tag dans le répertoire WEB-INF\tags de l’application. Eclipse propose une aide à la création d’un tag :

 Effectuez un clic droit sur votre projet puis cliquez sur le menu New - Other. L’écran suivant apparaît. Filtrez la liste en écrivant tag dans la zone Wizards :

images/03EP25N.png

 Sélectionnez le type de fichiers JSP Tag et cliquez sur Next pour passer à l’écran suivant.

 Sélectionnez le répertoire tags préalablement créé et donnez un nom à votre fichier :

images/03EP26N.png

 Cliquez sur le bouton Finish. Le fichier Sports.tag est créé et le contenu est le suivant :

<%@ tag language="java" pageEncoding="UTF-8"%> 

Cette directive permet d’indiquer que le fichier est un tag.

Il est possible d’utiliser dans ce fichier toutes les technologies présentées dans les sections précédentes. Pour le moment, le tag va rester très simple avec un contenu statique :

<h1>Liste des sports</h1> 
<ul> 
    <li>Badminton</li> 
    <li>Tennis</li> ...

Conclusion

Ce chapitre a présenté la richesse de la technologie JSP. Il est certes possible d’écrire du code Java dans un fichier JSP, mais les actions standards (<jsp:XXX>), l’Expression Language, les balises JSTL et personnalisées invitent le développeur à utiliser les outils à disposition pour augmenter la productivité et la qualité du travail. Le chapitre suivant expose le framework JSF permettant d’aller encore plus loin dans la mise en place d’une solution professionnelle.