JavaRush /Blog Java /Random-FR /Création d'une application Web simple à l'aide de servlet...
Стас Пасинков
Niveau 26
Киев

Création d'une application Web simple à l'aide de servlets et de jsp (partie 1)

Publié dans le groupe Random-FR
Niveau de connaissances requis pour comprendre l'article : vous avez déjà plus ou moins compris Java Core et souhaitez vous intéresser aux technologies JavaEE et à la programmation web. Cela a plus de sens si vous étudiez actuellement la quête Java Collections, qui couvre des sujets proches de l'article. Création d'une application Web simple à l'aide de servlets et de jsp (partie 1) - 1Ce matériel est une suite logique de mon article Création d'un projet Web simple dans IntelliJ Idea Enterprise . J'y ai montré comment créer un modèle de projet Web fonctionnel. Cette fois, je vais vous montrer comment créer une application Web simple mais jolie à l'aide des technologies Java Servlet API et JavaServer Pages API. Notre application aura une page d'accueil avec deux liens :
  • à l'utilisateur ajoutant une page ;
  • à la page d'affichage de la liste des utilisateurs.
J'utiliserai toujours IntelliJ Idea Enterprise Edition, Apache Maven (incluez simplement quelques dépendances) et Apache Tomcat. A la fin, nous « décorerons » notre application à l'aide du framework W3.CSS . Nous supposerons qu'à l'heure actuelle vous disposez déjà d'un projet vide, que nous développerons ici. Sinon, parcourez le premier article et créez-le. Cela ne prendra que quelques minutes :)

Un peu sur la structure de la future application

Notre page principale ( / ) sera la page HTML statique la plus ordinaire avec un en-tête et deux liens/boutons :
  • ajouter un nouvel utilisateur (sera envoyé à /add );
  • afficher la liste des utilisateurs (envoie à /list ).
Tomcat interceptera les requêtes vers ces adresses et les enverra à l'une des deux servlets que nous réaliserons (nous décrirons le mappage dans le fichier web.xml ). Et les servlets, à leur tour, traiteront les requêtes, prépareront les données (ou les enregistreront si un utilisateur est ajouté) et transféreront le contrôle aux fichiers jsp correspondants, qui « rendront » déjà le résultat. Nous stockerons les données dans la liste la plus courante (List).

Créons une page d'accueil statique

Si vous avez index.jsp dans votre dossier Web , supprimez-le. Au lieu de cela, dans ce dossier, nous allons créer un simple fichier html appelé index.html :
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My super project!</title>
</head>
<body>
    <!-- header -->
    <div>
        <h1>Super app!<//h1>
    </div>

    <div>       <!-- content -->
        <div>    <!-- buttons holder -->
            <button onclick="location.href='/list'">List users<//button>
            <button onclick="location.href='/add'">Add user<//button>
        </div>
    </div>
</body>
</html>
Il n'y a rien de compliqué ici. En titre nous indiquons le titre de notre page. Dans le corps de la page, nous avons deux div principaux : header (header) et content (content). Dans le contenu, nous avons un support pour nos boutons, et en fait deux boutons qui, une fois cliqués, sont envoyés aux adresses appropriées. Vous pouvez exécuter le projet et voir à quoi il ressemble maintenant. Si vous cliquez sur les boutons, des pages avec une erreur 404 s'ouvrent car nous ne les avons pas encore. Mais cela suggère que les boutons fonctionnent. Permettez-moi de noter que ce n'est pas l'option la plus universelle, car si JavaScript est soudainement désactivé, ces boutons ne seront d'aucune utilité dans le navigateur. Mais nous supposerons que personne n'a désactivé JavaScript :). Il est clair que des liens simples pourraient être utilisés, mais je préfère les boutons. Vous faites ce que vous préférez. Et ne regardez pas le fait qu'il y aura beaucoup de divs dans mes exemples . Ensuite, nous les remplirons de styles et tout sera plus beau :).

Créez des fichiers jsp pour rendre le résultat

Dans le même répertoire web , nous créerons un dossier dans lequel nous placerons nos fichiers jsp . Je l'ai appelé vues, et encore une fois, vous pouvez improviser. Dans ce dossier nous allons créer deux fichiers jsp :
  • add.jsp — page pour ajouter des utilisateurs ;
  • list.jsp - page pour afficher une liste d'utilisateurs.
Donnons-leur les titres de page appropriés. Quelque chose comme « Ajouter un nouvel utilisateur » et « Liste des utilisateurs », et nous allons le laisser ainsi pour l'instant.

Créons deux servlets

Les servlets accepteront et traiteront les demandes que Tomcat leur transmettra. Dans le dossier src/main/java , nous allons créer un package d'application qui contiendra nos sources. Là, nous aurons des packages plus différents. Par conséquent, pour que ces packages ne soient pas créés les uns dans les autres, créons une classe dans le package d'application (puis supprimons-la). Créons maintenant trois packages différents dans le package d'application :
  • entités - c'est là que se trouveront nos entités (la classe elle-même, qui décrira les objets utilisateur) ;
  • modèle - notre modèle sera ici (nous en parlerons un peu plus tard) ;
  • servlets - eh bien, voici nos servlets.
Après cela, vous pouvez supprimer cette classe en toute sécurité du package d'application (si vous l'avez créée, bien sûr). Dans le package servlets , nous allons créer deux classes :
  • AddServlet - traitera les demandes reçues à /add ;
  • ListServlet - traitera les demandes reçues à /list .

Connexion des dépendances dans Maven

Tomcat version 9.* implémente les spécifications Servlet version 4.0 et JavaServer Pages version 2.3. Ceci est écrit dans la documentation officielle de Tomcat 9 dans le premier paragraphe de la deuxième ligne. Cela signifie que si, comme moi, vous utilisez cette version de Tomcat, le code que nous écrivons et envoyons pour exécuter utilisera exactement les versions spécifiées. Mais nous aimerions avoir ces spécifications dans notre projet, afin que notre code qui les utilise soit au moins compilé avec succès. Et pour cela, nous devons les charger dans notre projet. C'est là que Maven vient à la rescousse.

La règle générale est la suivante : si vous devez connecter quelque chose à votre projet à l'aide de Maven :

  • allez sur le site Web du référentiel Maven ;
  • recherchez-y la bibliothèque dont vous avez besoin et la version dont vous avez besoin ;
  • vous obtenez le code de dépendance qui doit être inséré dans votre pom.xml ;
  • insérer! :)
Alors commençons. Commençons par préparer un fichier pom . Quelque part après /version mais avant /project , insérez ce qui suit :
<dependencies>

</dependencies>
Ainsi, nous avons indiqué qu'à l'intérieur de ces balises nous listerons les dépendances dont nous avons besoin. Allez maintenant sur mvnrepository.com , il y aura un champ de recherche en haut. Tout d’abord, entrez servlet dans la recherche. Le premier résultat, où il y a plus de sept mille usages, nous convient. Rappelons que nous avons besoin de la version 4.0 (pour Tomcat 9 ; pour d'autres versions, des implémentations plus anciennes peuvent convenir). Il s'agit d'une version assez récente, donc il n'y a pas beaucoup d'utilisations, mais c'est celle dont nous avons besoin. Une page s'ouvrira où vous pourrez obtenir le code de cette dépendance pour différents gestionnaires de packages et vous pourrez même simplement le télécharger. Mais comme nous voulons le connecter via Maven, nous sélectionnons le code dans l'onglet Maven. Nous copions et collons dans notre fichier pom dans la section dépendances. Si une notification apparaît dans le coin inférieur droit d'IDEA nous demandant si nous souhaitons activer l'importation automatique, nous sommes d'accord. Si vous avez accidentellement refusé, allez dans « Paramètres » et activez l'importation automatique manuellement : Paramètres (Ctrl + Alt + S) -> Construction, exécution, déploiement -> Maven -> Importation. Cela conservera le fichier pom et les fichiers de configuration IDEA pour cela. projet synchronisé. Maintenant, en utilisant le même principe, nous allons trouver et connecter JavaServer Pages version 2.3 (entrez jsp dans la recherche). Et puisque nous avons déjà repris Maven, disons-lui tout de suite que nos sources sont conformes à la syntaxe Java 8, et qu'elles doivent être compilées en bytecode de la même version. Après toutes ces manipulations, notre pom.xml ressemblera à ceci :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ru.javarush.info.fatfaggy</groupId>
    <artifactId>my-super-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compile.source>
        <maven.compiler.target>1.8</maven.compile.target>
    </properties>

    <dependencies>
        <!-- Servlet API 4.0 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- JavaServer Pages API 2.3 for tomcat 9 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

Faire de nos servlets de véritables servlets

À ce stade, les quelques servlets que nous avons créées ne sont en réalité que des classes normales. Ils n'ont aucune fonctionnalité. Mais maintenant, nous avons connecté l'API Servlet à notre projet et, si c'est le cas, nous pouvons utiliser les classes à partir de là. Pour rendre nos servlets de « vraies » servlets, il nous suffit simplement de les hériter de la classe HttpServlet .

Mappage ou partitionnement

Maintenant, ce serait bien de dire d'une manière ou d'une autre à Tomcat que les requêtes de /add soient gérées par notre servlet AddServlet , et donc que les requêtes de /list soient gérées par la servlet ListServlet . Ce processus est appelé cartographie . Cela se fait dans le fichier web.xml selon ce principe :
  • nous décrivons d'abord le servlet (nous donnons un nom et indiquons le chemin d'accès à la classe elle-même) ;
  • puis on lie cette servlet à une adresse précise (on indique le nom de la servlet que l'on vient de lui donner et on indique l'adresse à partir de laquelle les requêtes doivent être envoyées à cette servlet).
Décrivons la servlet :
<servlet>
    <servlet-name>add</servlet-name>
    <servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Maintenant, nous le lions à l'adresse :
<servlet-mapping>
    <servlet-name>add</servlet-name>
    <url-pattern>/add</url-pattern>
</servlet-mapping>
Comme vous pouvez le constater, le nom du servlet est le même dans les deux cas. Grâce à cela, Tomcat sait que si une requête arrive à l' adresse /add , elle doit être transmise au servlet app.servlets.AddServlet . Nous faisons de même avec la deuxième servlet. En conséquence, notre web.xml a approximativement le contenu suivant :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- add servlet -->
    <servlet>
        <servlet-name>add</servlet-name>
        <servlet-class>app.servlets.AddServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>add</servlet-name>
        <url-pattern>/add</url-pattern>
    </servlet-mapping>

    <!-- list servlet -->
    <servlet>
        <servlet-name>list</servlet-name>
        <servlet-class>app.servlets.ListServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>list</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>
</web-app>
À propos, nous n'avons pas créé de balisage pour la page principale ici (à l'adresse / ). Le fait est que dans ce cas, nous n’en avons pas besoin. Notre page d'accueil est un simple fichier HTML qui affiche simplement deux boutons. Il n'y a pas de contenu dynamique, cela n'a donc aucun sens pour nous de créer un servlet séparé, auquel les requêtes de l'adresse / seront envoyées et qui ne fera rien d'autre que transférer l'exécution vers un jsp (qui devrait également être créé), qui dessinerait Si seulement nous avions deux boutons. Nous n’en avons pas besoin ; nous nous contentons d’une ressource statique. Lorsque Tomcat recevra une demande, il vérifiera qu'il n'y a pas un seul servlet qui pourrait traiter la demande à une telle adresse, puis il verra qu'à cette adresse il y a en fait un fichier html prêt à l'emploi, qu'il enverra avec succès . Nous pouvons réexécuter notre application (redémarrer le serveur ou redéployer, comme vous le souhaitez) et vous assurer que la page principale est rendue, rien n'est cassé, lorsque nous cliquons sur les boutons, des transitions se produisent, mais pour l'instant une erreur est également écrit. À propos, si avant nous avions une erreur 404, nous avons maintenant une erreur 405. Cela signifie que le mappage a fonctionné, que les servlets ont été trouvés, mais qu'ils n'avaient tout simplement pas de méthodes appropriées pour traiter la demande. Si à ce stade vous obtenez toujours une erreur 404, même si tout a été fait correctement, vous devriez peut-être corriger la configuration de déploiement dans l'idée. Pour cela, vous devez vous rendre dans Modifier les configurations (en haut près du bouton démarrer), aller dans l'onglet Déploiement à droite de la fenêtre et vous assurer que dans le contexte Application c'est simplement indiqué /

Petite digression lyrique : que se passe-t-il « sous le capot » ?

Vous vous êtes probablement déjà demandé comment fonctionne notre application dans Tomcat ? Que se passe-t-il ici? Et où est la méthode main() ? Dès que vous tapez localhost:8080 dans votre navigateur et que vous vous rendez à cette adresse, le navigateur envoie une requête à cette adresse via le protocole http . J'espère que vous savez déjà que les requêtes peuvent être de différents « types », les plus populaires étant GET et POST . Chaque demande doit avoir une réponse. Une requête GET s'attend à ce qu'en réponse, elle reçoive un code HTML prêt à l'emploi, qui sera renvoyé au navigateur, et le navigateur remplacera magnifiquement ce code par toutes sortes de lettres, de boutons et de formulaires. La requête POST est un peu plus intéressante, car elle transporte également des informations. Par exemple, dans le formulaire d’inscription ou d’autorisation d’utilisateur, vous avez saisi vos données et cliqué sur « envoyer ». À ce moment, une requête POST a été envoyée au serveur contenant vos informations personnelles. Le serveur a accepté ces informations, les a traitées et a renvoyé une sorte de réponse (par exemple, une page HTML avec votre profil). La différence fondamentale entre elles est que les requêtes GET sont destinées uniquement à recevoir des données du serveur, tandis que les requêtes POST contiennent certaines informations et que les données sur le serveur peuvent changer (par exemple, lorsque vous téléchargez votre photo sur le serveur, elle " va voler dans la requête POST et le serveur l'ajoutera à la base de données, c'est-à-dire qu'un changement se produira. Revenons maintenant à Tomcat. Lorsqu'il reçoit une requête du client, il regarde l'adresse. Recherche ses données pour voir s'il existe un servlet approprié, qui traiterait les requêtes vers une telle adresse (ou une ressource prête à l'emploi qui peut être renvoyée immédiatement). S'il ne trouve rien à renvoyer, il ne répond pas avec une page HTML, mais avec une réponse 404. S'il trouve un servlet approprié, qui "se trouve" sur cette adresse, il regarde quel type de requête il a reçu (GET, POST ou autre), puis demande au servlet s'il a une méthode qui pourrait gérer ce type de requête. Si la servlet dit qu'elle ne peut pas traiter ce type, Tomcat répond au client avec le code 405. C'est ce qui vient de nous arriver. Mais si un servlet approprié est trouvé et qu'il dispose d'une méthode appropriée, Tomcat crée un objet de ce servlet, l'exécute dans un nouveau thread ( thread ), ce qui permet au servlet de fonctionner dans un thread séparé, et Tomcat continue de travailler en soi, recevoir et envoyer des demandes. De plus, Tomcat crée deux autres objets : un de type HttpServletRequest (je l'appellerai brièvement une requête à l'avenir) et le second de type HttpServletResponse .(Je l'appellerai la réponse). Dans le premier objet, il place toutes les données qu'il a reçues dans une requête du client, afin que toutes ces données puissent être extraites de cet objet. Eh bien, après tout cela, il transmet ces deux objets à la méthode appropriée du servlet qui s'exécute dans un thread séparé. Dès que la servlet termine son travail et qu'elle a une réponse prête à envoyer au client, elle lève un drapeau à Tomcat en disant : « J'ai terminé, tout est prêt ». Tomcat accepte la réponse et l'envoie au client. Cela permet à Tomcat d'accepter les demandes et d'envoyer des réponses sans interruption, tandis que tout le travail est effectué par des servlets exécutés dans des threads séparés. En conséquence, lorsque nous écrivons du code de servlet, nous définissons le travail qui sera effectué. Et oui, vous pouvez considérer la méthode main() comme étant dans Tomcat lui-même (oui, elle est écrite en Java), et lorsque nous "démarrons" Tomcat, le fichier main().

Nous captons les méthodes GET avec des servlets et envoyons des réponses simples

Pour le moment, nos servlets n'ont pas de méthodes adaptées (GET), donc Tomcat nous renvoie une erreur 405. Faisons-les ! La classe HttpServlet , dont nous héritons de nos servlets, définit différentes méthodes. Afin de définir du code pour les méthodes, nous les remplaçons simplement. Dans ce cas, nous devons remplacer la méthode doGet() dans les deux servlets.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

}
Comme vous pouvez le voir, cette méthode accepte deux objets : req (requête) et resp (réponse). Ce sont ces mêmes objets que Tomcat créera et remplira pour nous lorsqu'il appellera la méthode appropriée dans cette servlet. Commençons par les réponses les plus simples. Pour ce faire, prenez l' objet resp et obtenez-en un objet PrintWriter , qui peut être utilisé pour composer des réponses. Eh bien, en l'utilisant, nous imprimerons une chaîne simple.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    PrintWriter writer = resp.getWriter();
    writer.println("Method GET from AddServlet");
}
Nous ferons quelque chose de similaire dans la servlet ListServlet , après quoi nous redémarrerons notre serveur. Comme vous pouvez le constater, tout fonctionne ! Lorsque vous cliquez sur les boutons, des pages s'ouvrent avec le texte que nous avons « enregistré » avec PrintWriter . C'est juste que nos jsp que nous avons préparés pour générer des pages avec des réponses ne sont en aucun cas utilisées. C’est parce que l’exécution ne les atteint tout simplement pas. Le serveur lui-même génère désormais une réponse et termine son travail, signalant à Tomcat qu'il a une réponse prête pour le client. Tomcat prend simplement cette réponse et la renvoie au client. Nous transférons le contrôle des servlets vers jsp. Modifions le code de nos méthodes de cette façon :
  • nous obtenons de l'objet de requête un objet gestionnaire de requêtes, où nous transmettons l' adresse jsp de la page à laquelle nous voulons transférer le contrôle ;
  • en utilisant l'objet reçu, nous transférons le contrôle vers la page jsp spécifiée , et n'oublions pas d'y joindre les objets de requête et de réponse que nous avons reçus de Tomcat.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
    requestDispatcher.forward(req, resp);
}
Dans le corps des pages jsp (à l'intérieur de la balise body), nous pouvons écrire quelque chose pour que nous puissions voir clairement quelle page est affichée. Après cela, nous redémarrons le serveur et vérifions. Les boutons de la page principale sont enfoncés, les pages sont ouvertes, ce qui signifie que les requêtes sont envoyées aux servlets, après quoi le contrôle est transféré aux pages jsp, qui sont déjà rendues. C'est tout. Dans la prochaine partie de l'article, nous aborderons les fonctionnalités de notre application.

Que lire d'autre :

Création d'un projet Web simple dans IntelliJ Idea Enterprise. Pas à pas, avec photos


Mon chat
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION