Connaissances requises pour comprendre l'article : Vous avez déjà plus ou moins compris Java Core et aimeriez vous pencher sur les technologies JavaEE et la programmation web . Il serait plus logique que vous étudiiez actuellement la quête Java Collections , qui traite de sujets proches de l'article.
Ce matériel est la suite logique de mon article Création du projet web le plus simple dans IntelliJ Idea Enterprise . Dans cet article, j'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 totalement attrayante à l'aide de l' API Java Servlet et de l' API JavaServer Pages . Notre application aura une page d'accueil avec deux liens :
Commençons. Tout d'abord, préparez le fichier POM . Quelque part après l' entrée /version , mais avant /project , insérez ce qui suit :
Passons le contrôle des servlets aux fichiers JSP. Nous allons modifier le code de nos méthodes comme suit :
- un lien vers une page pour ajouter des utilisateurs ;
- un lien vers la liste des utilisateurs.
Un peu sur la structure de notre future application
Notre page d'accueil (/) sera une page HTML statique la plus ordinaire avec un en-tête et deux liens/boutons :- ajouter un nouvel utilisateur (navigue vers / add );
- afficher la liste des utilisateurs (navigue vers / list ).
Créer une page d'accueil statique
Si vous index.jsp dans votre dossier Web, supprimez-le. Créez plutôt un fichier HTML simple appelé index.html dans ce dossier :
<!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> <!-- button 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. Dans la balise title , nous indiquons le titre de notre page. Dans le corps de la page, nous avons deux divs principaux : header et content . La div de contenu inclut un support pour nos boutons. Et là, nous avons deux boutons qui vous amènent à l'adresse correspondante en un clic. Vous pouvez exécuter le projet et voir à quoi il ressemble maintenant. Si vous cliquez sur les boutons, vous obtenez des pages d'erreur 404, car nous les pages correspondantes n'existent pas encore. Mais on peut dire que les boutons fonctionnent. Notez que ce n'est pas l'approche la plus universelle : si JavaScript est désactivé dans le navigateur, ces boutons ne fonctionneront pas. Mais nous supposerons que personne ne désactive JavaScript. :) Évidemment, vous pourriez vous débrouiller avec des liens simples, mais je préfère les boutons. Vous pouvez le faire comme vous préférez. Et ne vous inquiétez pas du fait que mes exemples auront beaucoup de divs . Nous les remplirons de styles plus tard, et tout sera plus beau. :)
Créer des fichiers JSP pour rendre le résultat
Dans le même répertoire web , créez un dossier où nous ajouterons nos fichiers JSP . Je l'ai appelé ' vues ', mais encore une fois tu peux improviser. Dans ce dossier, nous allons créer deux fichiers JSP :- add.jsp — une page pour ajouter des utilisateurs ;
- list.jsp — page pour afficher la liste des utilisateurs.
Créer deux servlets
Les servlets recevront et traiteront les requêtes que Tomcat leur envoie. Dans le dossier src/main/java , créez le package de l'application , où nous placerons notre code source. D'autres forfaits iront également là-bas. Donc, pour empêcher que ces packages soient créés les uns dans les autres, nous allons créer une classe dans le package de l'application (nous la supprimerons plus tard). Créez maintenant trois packages différents dans le package de l'application :- entités — nos entités (la classe qui décrit les objets utilisateur) vont ici ;
- modèle - c'est là que va notre modèle (nous en reparlerons un peu plus tard);
- servlets - et c'est là que vont nos servlets.
- AddServlet — traite les requêtes envoyées à / add ;
- ListServlet — traite les requêtes envoyées à / list .
Connexion des dépendances dans Maven
Tomcat 9. * implémente les spécifications pour Servlet 4.0 et JavaServer Pages 2.3 . C'est ce qui est indiqué dans la deuxième ligne du premier paragraphe de la documentation officielle de Tomcat 9. Cela signifie que si vous, comme moi, utilisez cette version de Tomcat , alors le code que vous écrirez et exécuterez utilisera ces versions. Mais nous aimerions avoir ces spécifications dans notre projet, afin que notre code, qui les utilise, se compile au moins avec succès. Et pour ce faire, 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 avez besoin de connecter quelque chose à votre projet à l'aide de Maven :
|
<dependencies>
</dependencies>
Nous faisons cela pour indiquer que nous allons lister les dépendances requises dans ces balises. Allez maintenant sur mvnrepository.com . Il y a un champ de recherche en haut. Pour commencer, recherchez ' servlet '. Le premier résultat, utilisé plus de sept mille fois, nous convient. Rappelez-vous, nous avons besoin de la version 4.0 (pour Tomcat 9). D'autres versions peuvent être appropriées pour les implémentations plus anciennes. C'est une version assez récente, donc il n'y a pas beaucoup d'utilisations. Mais nous en avons besoin. Une page s'ouvre où vous pouvez obtenir le code de cette dépendance pour une variété de gestionnaires de packages, ou vous pouvez simplement le télécharger. Mais comme nous voulons le connecter à l'aide de Maven, nous sélectionnerons le code dans l'onglet Maven. Nous copions et collons dans la section dépendance de notre fichier POM. Si vous recevez une notification vous demandant si vous souhaitez activer l'importation automatique dans le coin inférieur droit de l' IDEA , continuez et acceptez-la. Si vous avez accidentellement refusé, allez dans « Paramètres » et activez l'importation automatique manuellement : Paramètres (Ctrl + Alt + S) -> Build, Execution, Deployment -> Maven -> Importing .et les fichiers de configuration IDEA pour ce projet en synchronisation. Suivant le même principe, nous allons rechercher et connecter JavaServer Pages 2.3 (recherchez "JSP"). Et puisque nous avons déjà démarré Maven, disons simplement que nos fichiers sources suivent la syntaxe Java 8, et que nous devons les compiler en bytecode pour cette version. Après toutes ces étapes, 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>cc.codegym.info.fatfaggy</groupId>
<artifactId>my-super-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compile.source>1.8</maven.compile.source>
<maven.compile.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
Pour le moment, la paire de servlets que nous avons créée sont en fait des classes ordinaires. Ils n'ont aucune fonctionnalité. Mais maintenant, nous avons connecté l' API Servlet à notre projet et, par conséquent, nous pouvons utiliser ses classes. Pour rendre nos servlets "réelles", il suffit de leur faire hériter de la classe HttpServlet .Mappage ou balisage
Maintenant, ce serait bien de dire d'une manière ou d'une autre à Tomcat que les requêtes pour l'adresse / add sont traitées par notre AddServlet et que les requêtes pour l'adresse / list sont gérées par le ListServlet . Ce processus est appelé mappage (balisage). Cela se fait dans web.xml selon le même principe :- pour commencer, décrivez le servlet (fournissez un nom et spécifiez le chemin vers la classe elle-même);
- puis liez cette servlet à une adresse spécifique (précisez le nom de la servlet, que nous venons de lui donner, et précisez l'adresse dont les requêtes doivent être envoyées à cette servlet).
<servlet>
<servlet-name>add</servlet-name>
<servlet-class>app.servlets.AddServlet</servlet-class>
</servlet>
Liez-le maintenant à l'adresse :
<servlet-mapping>
<servlet-name>add</servlet-name>
<url-pattern>/add</url-pattern>
</servlet-mapping>
Comme vous pouvez le voir, servlet-name est le même dans les deux cas. Par conséquent, Tomcat sait que si une requête pour /add est reçue, elle doit être envoyée à app.servlets.AddServlet. Nous faisons la même chose avec la deuxième servlet. Au final, 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>
Au fait, nous n'avons pas créé de balisage pour la page d'accueil (/). Le fait est que nous n'en avons pas besoin dans ce cas. Notre page d'accueil est un simple fichier HTML qui n'affiche que deux boutons. Il n'a pas de contenu dynamique, nous n'avons donc pas besoin de créer un servlet séparé pour les requêtes de / qui ne fera que transmettre l'exécution à une JSP (qui devrait également être créée) pour dessiner deux boutons pour nous. Nous n'avons pas besoin de ça. Une page statique nous convient. Lorsque Tomcat reçoit une demande, il vérifie s'il existe un seul servlet qui pourrait traiter la demande pour cette adresse, puis verra que cette adresse contient déjà le fichier HTML prêt., qu'il servira. Nous pouvons exécuter à nouveau notre application (redémarrer le serveur ou le redéployer, selon votre préférence) et nous assurer que la page d'accueil est rendue, que rien ne s'est cassé et que les transitions se produisent lorsque nous cliquons sur les boutons (bien que nous obtenions à nouveau une erreur). Soit dit en passant, alors qu'avant nous avions une erreur 404, nous obtenons maintenant une erreur 405. Cela signifie que le mappage a fonctionné et que les servlets ont été trouvés, mais qu'ils n'avaient aucune méthode appropriée pour gérer la requête.
Petite parenthèse : que se passe-t-il « sous le capot » ?
Vous avez probablement déjà réfléchi au fonctionnement de notre application dans Tomcat. Que se passe-t-il là-dedans ? Et où est la méthode main() ? Dès que vous accédez à localhost:8080 dans votre navigateur, le navigateur envoie une requête à cette adresse en utilisant le protocole HTTP. J'espère que vous savez déjà qu'il existe de nombreux types de requêtes, et les plus populaires sont GET et POST. Chaque demande doit recevoir une réponse. Une requête GET est censée recevoir une réponse sous forme de code HTML prêt à l'emploi, renvoyé au navigateur. Le navigateur remplace alors le code par toutes les jolies lettres, boutons et formulaires. Une requête POST est un peu plus intéressante, car elle transporte également certaines informations. Par exemple, supposons que vous saisissiez des informations d'identification dans un formulaire d'inscription ou de connexion sur un site Web et que vous cliquiez sur "Envoyer". Cela provoque l'envoi d'une requête POST avec vos informations personnelles au serveur. Le serveur reçoit ces informations, les traite et renvoie une réponse (par exemple, une page HTML avec votre profil). La principale différence entre eux est que les requêtes GET ne sont utilisées que pour récupérer des données du serveur, tandis que les requêtes POST transportent certaines informations (et les données sur le serveur peuvent changer). Par exemple, lorsque vous téléchargez votre image sur le serveur, elle y est transportée dans une requête POST et le serveur l'ajoute à la base de données, c'est-à-dire qu'un changement se produit. Revenons maintenant à Tomcat. Lorsqu'il reçoit une demande d'un client, il regarde l'adresse. Il vérifie s'il existe un servlet approprié pour traiter les requêtes pour cette adresse (ou une ressource disponible qui peut être renvoyée immédiatement). S'il ne trouve pas quelque chose à retourner, puis il répond avec une erreur 404 plutôt qu'une page HTML. Mais s'il trouve un servlet approprié "assis" à cette adresse, il examine le type de requête (GET, POST ou autre) et demande au servlet s'il a une méthode capable de gérer ce type de requête. Si la servlet dit qu'elle ne sait pas comment gérer ce type, alorsTomcat renvoie un code 405. Et c'est exactement ce qui s'est passé dans notre projet. Mais si un servlet approprié est trouvé et qu'il a une méthode appropriée, alors Tomcat crée un objet servlet, le démarre sur un nouveau thread(ce qui lui permet de fonctionner seul), et Tomcat continue son propre travail, acceptant et envoyant des demandes. De plus, Tomcat crée deux objets supplémentaires : un HttpServletRequest (que j'appellerai la "demande" en abrégé) et un HttpServletResponse (que j'appellerai la "réponse"). Il place toutes les données reçues de la demande du client dans le premier objet, afin que toutes ces données puissent en être extraites. Et puis après tout cela, il passe ces deux objets à la méthode appropriée de la servlet qui a été démarrée sur un thread séparé. Dès que la servlet a terminé son travail et qu'elle a une réponse prête à être envoyée au client, elle agite un drapeau à Tomcat, disant "J'ai terminé. Tout est prêt". Tomcat reçoit la réponse et l'envoie au client. Cela permet à Tomcat de recevoir des requêtes et d'envoyer des réponses, sans être distrait, et tout le travail est effectué par des servlets s'exécutant sur des threads séparés. Cela signifie que lorsque nous écrivons le code du servlet, nous déterminons quel travail sera effectué. Et vous pouvez penser que la méthode main() est située à l'intérieur de Tomcat lui-même (oui, elle est écrite en Java), et lorsque nous "lançons" Tomcat, la méthode main() est lancée.Utilisez des servlets pour attraper les méthodes GET et envoyer des réponses super simples
Pour le moment, nos servlets n'ont pas de méthodes appropriées (GET), donc Tomcat renvoie une erreur 405. Créons-les ! La classe HttpServlet, dont nous héritons nos servlets, déclare diverses méthodes. Pour attribuer un code spécifique aux méthodes, nous les redéfinissons simplement. Dans ce cas, nous devons remplacer ladoGet()
méthode dans les deux servlets.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
Comme vous pouvez le voir, cette méthode prend deux arguments : req (demande) et resp (réponse). Ce sont les mêmes objets que Tomcat crée et remplit pour nous lorsqu'il appelle la méthode appropriée dans le servlet. Pour commencer, nous allons créer les réponses les plus simples. Pour ce faire, nous allons prendre l'objet resp et en tirer un objet PrintWriter. Ce type d'objet est utilisé pour composer une réponse. Nous l'utiliserons pour produire une chaîne simple.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("GET method from AddServlet");
}
Nous ferons quelque chose de similaire dans le ListServlet, puis nous redémarrerons notre serveur. Comme vous pouvez le voir, tout fonctionne ! Lorsque vous cliquez sur les boutons, vous obtenez des pages avec le texte que nous avons "écrit" avec le PrintWriter. Mais les fichiers JSP que nous avons préparés pour générer des pages avec des réponses ne sont pas utilisés. C'est simplement parce qu'ils ne sont jamais exécutés. Notre servlet crée la réponse elle-même et termine son exécution, signalant à Tomcat qu'elle est prête à répondre au client. Tomcat prend simplement la réponse et la renvoie au client.
- nous obtenons un objet répartiteur de requêtes à partir de l'objet requête et lui transmettons l'adresse de la page JSP à laquelle nous voulons transférer le contrôle ;
- nous utilisons cet objet pour transférer le contrôle à la page JSP spécifiée, sans oublier de transmettre 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 la balise body des pages JSP, vous pouvez ajouter quelque chose afin que nous puissions voir clairement quelle page est affichée. Une fois que vous avez fait cela, redémarrez le serveur et vérifiez. Nous cliquons sur les boutons de la page principale et les pages s'ouvrent, ce qui signifie que les requêtes sont envoyées aux servlets. Ensuite, le contrôle est passé aux pages JSP, qui sont maintenant rendues. C'est tout pour le moment. Dans la prochaine partie de cet article, nous allons travailler sur les fonctionnalités de notre application.
GO TO FULL VERSION